$root, 'uploads.local_originals_root' => $root, 'app.download_accel_enabled' => false, 'app.url' => 'https://skinbase.test', 'skinbase-sessions.enabled' => true, 'skinbase-sessions.debug_header' => true, 'skinbase-sessions.skip_anonymous_public_get' => true, ]); if (File::exists($root)) { File::deleteDirectory($root); } File::makeDirectory($root, 0755, true); }); afterEach(function () { $root = storage_path('framework/testing/artwork-downloads-m15c'); if (File::exists($root)) { File::deleteDirectory($root); } }); function m15cOriginal(string $hash, string $ext, string $content = '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; } it('returns a cheap 404 for a nonexistent artwork without analytics', function () { $this->mock(ArtworkStatsService::class, function ($mock): void { $mock->shouldReceive('incrementDownloads')->never(); }); $this->get('/download/artwork/999999')->assertNotFound(); expect(DB::table('artwork_downloads')->count())->toBe(0); }); it('returns a cheap 404 for a missing original without analytics', function () { $artwork = Artwork::factory()->create([ 'hash' => 'c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0', 'file_ext' => 'webp', 'file_name' => 'gone.webp', ]); $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('keeps valid anonymous downloads and X-Accel-Redirect when enabled', function () { config(['app.download_accel_enabled' => true, 'app.download_accel_path' => '/internal/originals']); $hash = '2721722cb2f407cc53539ee8718cc89c4cdfc579'; m15cOriginal($hash, 'zip'); $artwork = Artwork::factory()->create([ 'hash' => $hash, 'file_ext' => 'zip', 'file_name' => 'Anon File', ]); $this->get('/download/artwork/'.$artwork->id) ->assertOk() ->assertHeader('X-Accel-Redirect', '/internal/originals/27/21/2721722cb2f407cc53539ee8718cc89c4cdfc579.zip'); }); it('still records ArtworkDownload.user_id for authenticated downloads', function () { $hash = 'aa11bb22cc33dd44ee55ff6677889900aabbccdd'; m15cOriginal($hash, 'png'); $user = User::factory()->create(); $artwork = Artwork::factory()->create([ 'hash' => $hash, 'file_ext' => 'png', 'file_name' => 'Auth File', ]); $this->actingAs($user)->get('/download/artwork/'.$artwork->id)->assertOk(); $this->assertDatabaseHas('artwork_downloads', [ 'artwork_id' => $artwork->id, 'user_id' => $user->id, ]); }); it('skips session for anonymous download GET without a session cookie', function () { $this->get('/download/artwork/999999') ->assertNotFound() ->assertHeader('X-Skinbase-Session', 'skipped'); }); it('starts session for download GET when a session cookie is already present', function () { $cookie = (string) config('session.cookie'); $this->withCookie($cookie, 'existing-session-cookie') ->get('/download/artwork/999999') ->assertNotFound() ->assertHeader('X-Skinbase-Session', 'started'); }); it('does not record presence for artwork download requests', function () { $this->mock(OnlineVisitorRepository::class, function ($mock): void { $mock->shouldReceive('track')->never(); }); $this->get('/download/artwork/999999')->assertNotFound(); });