operationalUser(); $user->delete(); User::withTrashed()->whereKey($user->id)->update(['deleted_at' => now()->subDays($days)]); return $user->fresh(); } public function test_it_anonymizes_users_past_the_retention_window(): void { $this->systemUser(); $old = $this->trashedDaysAgo(40); $this->artisan('users:purge', ['--days' => 30])->assertSuccessful(); $old->refresh(); $this->assertNotNull($old->anonymized_at); $this->assertSame('Deleted user', $old->name); } public function test_it_skips_users_still_within_retention(): void { $this->systemUser(); $recent = $this->trashedDaysAgo(5); $this->artisan('users:purge', ['--days' => 30])->assertSuccessful(); $recent->refresh(); $this->assertNull($recent->anonymized_at); } public function test_dry_run_does_not_modify_anyone(): void { $this->systemUser(); $old = $this->trashedDaysAgo(40); $this->artisan('users:purge', ['--days' => 30, '--dry-run' => true])->assertSuccessful(); $old->refresh(); $this->assertNull($old->anonymized_at); } public function test_it_never_touches_the_system_user(): void { $system = $this->systemUser(); // Anche se (per assurdo) cestinato e vecchio, l'utente di sistema รจ escluso. $system->delete(); User::withTrashed()->whereKey($system->id)->update(['deleted_at' => now()->subDays(99)]); $this->artisan('users:purge', ['--days' => 30])->assertSuccessful(); $this->assertNull($system->fresh()->anonymized_at); } public function test_it_reports_when_there_is_nothing_to_do(): void { $this->systemUser(); $this->artisan('users:purge', ['--days' => 30]) ->expectsOutputToContain('No users to anonymize.') ->assertSuccessful(); } }