$id, 'user_id' => User::factory()->create()->id, 'type' => 'image', 'status' => 'draft', 'title' => null, 'slug' => null, 'category_id' => null, 'description' => null, 'tags' => null, 'license' => null, 'nsfw' => false, 'is_scanned' => false, 'has_tags' => false, 'preview_path' => null, 'published_at' => null, 'final_path' => null, 'expires_at' => null, 'created_at' => now(), 'updated_at' => now(), ]; DB::table('uploads')->insert(array_merge($defaults, $overrides)); return $id; } public function test_deletes_expired_draft_uploads_and_returns_count(): void { Storage::fake('local'); $uploadId = $this->insertUploadRow([ 'status' => 'draft', 'expires_at' => now()->subMinute(), ]); Storage::disk('local')->put("tmp/drafts/{$uploadId}/meta.json", '{}'); $deleted = app(CleanupService::class)->cleanupStaleDrafts(); $this->assertSame(1, $deleted); $this->assertFalse(DB::table('uploads')->where('id', $uploadId)->exists()); } public function test_keeps_active_drafts_untouched(): void { Storage::fake('local'); $uploadId = $this->insertUploadRow([ 'status' => 'draft', 'expires_at' => now()->addDay(), 'updated_at' => now()->subHours(2), ]); Storage::disk('local')->put("tmp/drafts/{$uploadId}/meta.json", '{}'); $deleted = app(CleanupService::class)->cleanupStaleDrafts(); $this->assertSame(0, $deleted); $this->assertTrue(DB::table('uploads')->where('id', $uploadId)->exists()); $this->assertTrue(Storage::disk('local')->exists("tmp/drafts/{$uploadId}/meta.json")); } public function test_removes_temp_folder_when_deleting_stale_drafts(): void { Storage::fake('local'); $uploadId = $this->insertUploadRow([ 'status' => 'draft', 'updated_at' => now()->subHours(25), ]); Storage::disk('local')->put("tmp/drafts/{$uploadId}/main/file.bin", 'x'); $this->assertTrue(Storage::disk('local')->exists("tmp/drafts/{$uploadId}/main/file.bin")); $deleted = app(CleanupService::class)->cleanupStaleDrafts(); $this->assertSame(1, $deleted); $this->assertFalse(Storage::disk('local')->exists("tmp/drafts/{$uploadId}/main/file.bin")); } public function test_enforces_hard_cleanup_limit_of_100_per_run(): void { Storage::fake('local'); for ($index = 0; $index < 120; $index++) { $uploadId = $this->insertUploadRow([ 'status' => 'draft', 'updated_at' => now()->subHours(30), ]); Storage::disk('local')->put("tmp/drafts/{$uploadId}/meta.json", '{}'); } $deleted = app(CleanupService::class)->cleanupStaleDrafts(999); $this->assertSame(100, $deleted); $this->assertSame(20, DB::table('uploads')->count()); } public function test_never_deletes_published_uploads(): void { Storage::fake('local'); $uploadId = $this->insertUploadRow([ 'status' => 'published', 'updated_at' => now()->subDays(5), 'published_at' => now()->subDays(4), ]); Storage::disk('local')->put("tmp/drafts/{$uploadId}/meta.json", '{}'); $deleted = app(CleanupService::class)->cleanupStaleDrafts(); $this->assertSame(0, $deleted); $this->assertTrue(DB::table('uploads')->where('id', $uploadId)->where('status', 'published')->exists()); $this->assertTrue(Storage::disk('local')->exists("tmp/drafts/{$uploadId}/meta.json")); } }