- Added testing check to buffer stop/clear on streaming output due to
interference during tests.
- Made content-disposition header a little safer in download responses.
- Also aligned how we check for testing environment.
{
return response()->make($content, 200, [
'Content-Type' => 'application/octet-stream',
{
return response()->make($content, 200, [
'Content-Type' => 'application/octet-stream',
- 'Content-Disposition' => 'attachment; filename="' . $fileName . '"',
+ 'Content-Disposition' => 'attachment; filename="' . str_replace('"', '', $fileName) . '"',
'X-Content-Type-Options' => 'nosniff',
]);
}
'X-Content-Type-Options' => 'nosniff',
]);
}
protected function streamedDownloadResponse($stream, string $fileName): StreamedResponse
{
return response()->stream(function() use ($stream) {
protected function streamedDownloadResponse($stream, string $fileName): StreamedResponse
{
return response()->stream(function() use ($stream) {
+ // End & flush the output buffer otherwise we still seem to use memory.
+ // Ignore in testing since output buffers are used to gather a response.
+ if (!app()->runningUnitTests()) {
+ ob_end_clean();
+ }
+
fpassthru($stream);
fclose($stream);
}, 200, [
'Content-Type' => 'application/octet-stream',
fpassthru($stream);
fclose($stream);
}, 200, [
'Content-Type' => 'application/octet-stream',
- 'Content-Disposition' => 'attachment; filename="' . $fileName . '"',
+ 'Content-Disposition' => 'attachment; filename="' . str_replace('"', '', $fileName) . '"',
'X-Content-Type-Options' => 'nosniff',
]);
}
'X-Content-Type-Options' => 'nosniff',
]);
}
return response()->make($content, 200, [
'Content-Type' => $mime,
return response()->make($content, 200, [
'Content-Type' => $mime,
- 'Content-Disposition' => 'inline; filename="' . $fileName . '"',
+ 'Content-Disposition' => 'inline; filename="' . str_replace('"', '', $fileName) . '"',
'X-Content-Type-Options' => 'nosniff',
]);
}
'X-Content-Type-Options' => 'nosniff',
]);
}
fclose($stream);
}, 200, [
'Content-Type' => $mime,
fclose($stream);
}, 200, [
'Content-Type' => $mime,
- 'Content-Disposition' => 'inline; filename="' . $fileName . '"',
+ 'Content-Disposition' => 'inline; filename="' . str_replace('"', '', $fileName) . '"',
'X-Content-Type-Options' => 'nosniff',
]);
}
'X-Content-Type-Options' => 'nosniff',
]);
}
- @if (!app()->environment('testing'))
+ @if (!app()->runningUnitTests())
{!! file_get_contents(public_path('/dist/export-styles.css')) !!}
@endif
</style>
{!! file_get_contents(public_path('/dist/export-styles.css')) !!}
@endif
</style>
use BookStack\Entities\Models\Page;
use BookStack\Uploads\Attachment;
use Illuminate\Http\UploadedFile;
use BookStack\Entities\Models\Page;
use BookStack\Uploads\Attachment;
use Illuminate\Http\UploadedFile;
+use Illuminate\Testing\AssertableJsonString;
use Tests\TestCase;
class AttachmentsApiTest extends TestCase
use Tests\TestCase;
class AttachmentsApiTest extends TestCase
$attachment = Attachment::query()->orderByDesc('id')->where('name', '=', $details['name'])->firstOrFail();
$resp = $this->getJson("{$this->baseEndpoint}/{$attachment->id}");
$attachment = Attachment::query()->orderByDesc('id')->where('name', '=', $details['name'])->firstOrFail();
$resp = $this->getJson("{$this->baseEndpoint}/{$attachment->id}");
$resp->assertStatus(200);
$resp->assertStatus(200);
+ $resp->assertHeader('Content-Type', 'application/json');
+
+ $json = new AssertableJsonString($resp->streamedContent());
+ $json->assertSubset([
'id' => $attachment->id,
'content' => base64_encode(file_get_contents(storage_path($attachment->path))),
'external' => false,
'id' => $attachment->id,
'content' => base64_encode(file_get_contents(storage_path($attachment->path))),
'external' => false,
$pageGet->assertSee($attachment->getUrl());
$attachmentGet = $this->get($attachment->getUrl());
$pageGet->assertSee($attachment->getUrl());
$attachmentGet = $this->get($attachment->getUrl());
- $attachmentGet->assertSee('Hi, This is a test file for testing the upload process.');
+ $content = $attachmentGet->streamedContent();
+ $this->assertStringContainsString('Hi, This is a test file for testing the upload process.', $content);
$this->deleteUploads();
}
$this->deleteUploads();
}