181 lines
5.9 KiB
PHP
181 lines
5.9 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\ExportLog;
|
|
use Database\Seeders\DatabaseSeeder;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Tests\TestCase;
|
|
|
|
class ExportPurgeCommandTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
public function test_command_purges_files_older_than_retention_period(): void
|
|
{
|
|
Storage::fake('local');
|
|
$this->seed(DatabaseSeeder::class);
|
|
|
|
$path = 'exports/finance/old-export.xlsx';
|
|
Storage::disk('local')->put($path, 'export content');
|
|
|
|
$log = ExportLog::query()->create([
|
|
'generated_at' => now()->subDays(31),
|
|
'report_type' => 'finance_verification_list',
|
|
'file_name' => 'old-export.xlsx',
|
|
'disk' => 'local',
|
|
'path' => $path,
|
|
'created_at' => now()->subDays(31),
|
|
'updated_at' => now()->subDays(31),
|
|
]);
|
|
|
|
$this->artisan('exports:purge', ['--days' => 30])
|
|
->assertSuccessful()
|
|
->expectsOutputToContain('Purged 1 export file(s).');
|
|
|
|
Storage::disk('local')->assertMissing($path);
|
|
$this->assertNotNull($log->fresh()->purged_at);
|
|
}
|
|
|
|
public function test_command_does_not_purge_files_within_retention_period(): void
|
|
{
|
|
Storage::fake('local');
|
|
$this->seed(DatabaseSeeder::class);
|
|
|
|
$path = 'exports/finance/recent-export.xlsx';
|
|
Storage::disk('local')->put($path, 'export content');
|
|
|
|
$log = ExportLog::query()->create([
|
|
'generated_at' => now()->subDays(10),
|
|
'report_type' => 'finance_verification_list',
|
|
'file_name' => 'recent-export.xlsx',
|
|
'disk' => 'local',
|
|
'path' => $path,
|
|
]);
|
|
|
|
$this->artisan('exports:purge', ['--days' => 30])
|
|
->assertSuccessful()
|
|
->expectsOutputToContain('No export files eligible');
|
|
|
|
Storage::disk('local')->assertExists($path);
|
|
$this->assertNull($log->fresh()->purged_at);
|
|
}
|
|
|
|
public function test_command_marks_log_as_purged_even_when_file_missing(): void
|
|
{
|
|
$this->seed(DatabaseSeeder::class);
|
|
|
|
$log = ExportLog::query()->create([
|
|
'generated_at' => now()->subDays(40),
|
|
'report_type' => 'attendance_detail_by_pusat',
|
|
'file_name' => 'missing-file.xlsx',
|
|
'disk' => 'local',
|
|
'path' => 'exports/attendance/missing-file.xlsx',
|
|
'created_at' => now()->subDays(40),
|
|
'updated_at' => now()->subDays(40),
|
|
]);
|
|
|
|
$this->artisan('exports:purge', ['--days' => 30])
|
|
->assertSuccessful()
|
|
->expectsOutputToContain('1 record(s) had no file on disk');
|
|
|
|
$this->assertNotNull($log->fresh()->purged_at);
|
|
}
|
|
|
|
public function test_command_does_not_re_purge_already_purged_records(): void
|
|
{
|
|
Storage::fake('local');
|
|
$this->seed(DatabaseSeeder::class);
|
|
|
|
$path = 'exports/finance/already-purged.xlsx';
|
|
|
|
$log = ExportLog::query()->create([
|
|
'generated_at' => now()->subDays(60),
|
|
'report_type' => 'finance_verification_list',
|
|
'file_name' => 'already-purged.xlsx',
|
|
'disk' => 'local',
|
|
'path' => $path,
|
|
'purged_at' => now()->subDays(5),
|
|
'created_at' => now()->subDays(60),
|
|
'updated_at' => now()->subDays(60),
|
|
]);
|
|
|
|
$this->artisan('exports:purge', ['--days' => 30])
|
|
->assertSuccessful()
|
|
->expectsOutputToContain('No export files eligible');
|
|
|
|
// purged_at should not change
|
|
$this->assertEquals(
|
|
$log->fresh()->purged_at->toDateString(),
|
|
now()->subDays(5)->toDateString()
|
|
);
|
|
}
|
|
|
|
public function test_command_accepts_custom_retention_days(): void
|
|
{
|
|
Storage::fake('local');
|
|
$this->seed(DatabaseSeeder::class);
|
|
|
|
$path = 'exports/finance/week-old.xlsx';
|
|
Storage::disk('local')->put($path, 'export content');
|
|
|
|
$log = ExportLog::query()->create([
|
|
'generated_at' => now()->subDays(8),
|
|
'report_type' => 'finance_verification_list',
|
|
'file_name' => 'week-old.xlsx',
|
|
'disk' => 'local',
|
|
'path' => $path,
|
|
'created_at' => now()->subDays(8),
|
|
'updated_at' => now()->subDays(8),
|
|
]);
|
|
|
|
// With default 30 days — should NOT purge
|
|
$this->artisan('exports:purge', ['--days' => 30])
|
|
->assertSuccessful()
|
|
->expectsOutputToContain('No export files eligible');
|
|
|
|
$this->assertNull($log->fresh()->purged_at);
|
|
|
|
// With 7 days — should purge
|
|
$this->artisan('exports:purge', ['--days' => 7])
|
|
->assertSuccessful()
|
|
->expectsOutputToContain('Purged 1 export file(s).');
|
|
|
|
$this->assertNotNull($log->fresh()->purged_at);
|
|
Storage::disk('local')->assertMissing($path);
|
|
}
|
|
|
|
public function test_command_records_activity_log_on_purge(): void
|
|
{
|
|
Storage::fake('local');
|
|
$this->seed(DatabaseSeeder::class);
|
|
|
|
$path = 'exports/finance/log-test.xlsx';
|
|
Storage::disk('local')->put($path, 'export content');
|
|
|
|
ExportLog::query()->create([
|
|
'generated_at' => now()->subDays(31),
|
|
'report_type' => 'finance_verification_list',
|
|
'file_name' => 'log-test.xlsx',
|
|
'disk' => 'local',
|
|
'path' => $path,
|
|
'created_at' => now()->subDays(31),
|
|
'updated_at' => now()->subDays(31),
|
|
]);
|
|
|
|
$this->artisan('exports:purge', ['--days' => 30])->assertSuccessful();
|
|
|
|
$this->assertDatabaseHas('activity_log', [
|
|
'log_name' => 'exports',
|
|
'description' => 'export_file_purged',
|
|
]);
|
|
}
|
|
|
|
public function test_command_rejects_invalid_days_option(): void
|
|
{
|
|
$this->artisan('exports:purge', ['--days' => 0])
|
|
->assertFailed();
|
|
}
|
|
}
|