$root, 'uploads.local_originals_root' => $root, 'app.download_accel_enabled' => false, 'app.download_accel_path' => '/internal/originals', 'app.url' => 'https://skinbase.test', ]); if (File::exists($root)) { File::deleteDirectory($root); } File::makeDirectory($root, 0755, true); }); afterEach(function () { $root = storage_path('framework/testing/artwork-downloads-accel'); if (File::exists($root)) { File::deleteDirectory($root); } }); function accelOriginal(string $hash, string $ext, string $content = 'original-bytes'): string { $root = rtrim((string) config('uploads.local_originals_root'), DIRECTORY_SEPARATOR); $dir = $root.DIRECTORY_SEPARATOR.substr($hash, 0, 2).DIRECTORY_SEPARATOR.substr($hash, 2, 2); File::makeDirectory($dir, 0755, true, true); $path = $dir.DIRECTORY_SEPARATOR.$hash.'.'.$ext; File::put($path, $content); return $path; } function resolveAccelUri(string $filePath): ?string { $controller = app(ArtworkDownloadController::class); $method = new ReflectionMethod(ArtworkDownloadController::class, 'resolveAccelUri'); return $method->invoke($controller, $filePath); } it('uses the PHP download fallback when acceleration is disabled', function () { $hash = '2721722cb2f407cc53539ee8718cc89c4cdfc579'; accelOriginal($hash, 'zip', 'zip-body'); $artwork = Artwork::factory()->create([ 'file_name' => 'Nested Original', 'hash' => $hash, 'file_ext' => 'zip', ]); $response = $this->get('/download/artwork/'.$artwork->id); $response->assertOk(); expect($response->headers->get('X-Accel-Redirect'))->toBeNull() ->and($response->baseResponse)->toBeInstanceOf(BinaryFileResponse::class); }); it('returns X-Accel-Redirect for a nested original when acceleration is enabled', function () { config(['app.download_accel_enabled' => true]); $hash = '2721722cb2f407cc53539ee8718cc89c4cdfc579'; accelOriginal($hash, 'zip', 'zip-body'); $artwork = Artwork::factory()->create([ 'file_name' => 'Nested Original', 'hash' => $hash, 'file_ext' => 'zip', ]); $this->mock(ArtworkStatsService::class, function ($mock) use ($artwork): void { $mock->shouldReceive('incrementDownloads')->once()->with($artwork->id, 1, false); }); $response = $this->get('/download/artwork/'.$artwork->id); $response->assertOk() ->assertHeader('X-Accel-Redirect', '/internal/originals/27/21/2721722cb2f407cc53539ee8718cc89c4cdfc579.zip') ->assertHeader('Content-Type', 'application/octet-stream') ->assertHeader('X-Content-Type-Options', 'nosniff'); $disposition = (string) $response->headers->get('Content-Disposition'); expect($disposition)->toContain('attachment') ->and($disposition)->toContain('Nested Original') ->and($disposition)->toContain('.zip') ->and($response->baseResponse)->not->toBeInstanceOf(BinaryFileResponse::class); expect(DB::table('artwork_downloads')->where('artwork_id', $artwork->id)->count())->toBe(1); }); it('maps nested originals under the accel prefix without duplicate slashes', function () { config(['app.download_accel_enabled' => true]); $root = rtrim((string) config('uploads.local_originals_root'), DIRECTORY_SEPARATOR); $relative = '27'.DIRECTORY_SEPARATOR.'21'.DIRECTORY_SEPARATOR.'2721722cb2f407cc53539ee8718cc89c4cdfc579.zip'; $path = $root.DIRECTORY_SEPARATOR.$relative; expect(resolveAccelUri($path))->toBe('/internal/originals/27/21/2721722cb2f407cc53539ee8718cc89c4cdfc579.zip'); }); it('does not emit an accel URI for a file outside the originals root', function () { config(['app.download_accel_enabled' => true]); $outside = sys_get_temp_dir().DIRECTORY_SEPARATOR.'not-original.zip'; File::put($outside, 'nope'); expect(resolveAccelUri($outside))->toBeNull(); File::delete($outside); }); it('returns 404 for an unsupported original extension', function () { $hash = 'aa11bb22cc33dd44ee55ff6677889900aabbccdd'; accelOriginal($hash, 'exe', 'not-allowed'); $artwork = Artwork::factory()->create([ 'hash' => $hash, 'file_ext' => 'exe', 'file_name' => 'bad.exe', ]); $this->mock(ArtworkStatsService::class, function ($mock): void { $mock->shouldReceive('incrementDownloads')->never(); }); $this->get('/download/artwork/'.$artwork->id)->assertNotFound(); expect(DB::table('artwork_downloads')->where('artwork_id', $artwork->id)->count())->toBe(0); }); it('still records download analytics when acceleration is enabled', function () { config(['app.download_accel_enabled' => true]); $hash = 'bb22cc33dd44ee55ff6677889900aabbccddeeff'; accelOriginal($hash, 'jpg', 'jpeg-bytes'); $artwork = Artwork::factory()->create([ 'hash' => $hash, 'file_ext' => 'jpg', 'file_name' => 'Photo', ]); DB::table('artwork_stats')->insertOrIgnore([ 'artwork_id' => $artwork->id, 'views' => 0, 'views_24h' => 0, 'views_7d' => 0, 'downloads' => 0, 'downloads_24h' => 0, 'downloads_7d' => 0, 'favorites' => 0, 'rating_avg' => 0, 'rating_count' => 0, ]); $this->get('/download/artwork/'.$artwork->id) ->assertOk() ->assertHeader('X-Accel-Redirect'); expect(DB::table('artwork_downloads')->where('artwork_id', $artwork->id)->count())->toBe(1) ->and((int) DB::table('artwork_stats')->where('artwork_id', $artwork->id)->value('downloads'))->toBe(1); });