$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; } it('runs uploads cleanup command and deletes stale drafts', function () { Storage::fake('local'); $expiredId = createCleanupUpload([ 'status' => 'draft', 'expires_at' => now()->subMinute(), ]); $activeId = createCleanupUpload([ 'status' => 'draft', 'expires_at' => now()->addHours(2), 'updated_at' => now()->subHours(2), ]); Storage::disk('local')->put("tmp/drafts/{$expiredId}/meta.json", '{}'); Storage::disk('local')->put("tmp/drafts/{$activeId}/meta.json", '{}'); $code = Artisan::call('uploads:cleanup'); expect($code)->toBe(0); expect(Artisan::output())->toContain('Uploads cleanup deleted 1 draft(s).'); expect(DB::table('uploads')->where('id', $expiredId)->exists())->toBeFalse(); expect(DB::table('uploads')->where('id', $activeId)->where('status', 'draft')->exists())->toBeTrue(); expect(Storage::disk('local')->exists("tmp/drafts/{$expiredId}/meta.json"))->toBeFalse(); expect(Storage::disk('local')->exists("tmp/drafts/{$activeId}/meta.json"))->toBeTrue(); }); it('respects command limit option', function () { Storage::fake('local'); for ($index = 0; $index < 5; $index++) { $uploadId = createCleanupUpload([ 'status' => 'draft', 'updated_at' => now()->subHours(26), ]); Storage::disk('local')->put("tmp/drafts/{$uploadId}/meta.json", '{}'); } $code = Artisan::call('uploads:cleanup', ['--limit' => 2]); expect($code)->toBe(0); expect(Artisan::output())->toContain('Uploads cleanup deleted 2 draft(s).'); expect(DB::table('uploads')->count())->toBe(3); });