80 lines
3.0 KiB
PHP
80 lines
3.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Models\OperationRun;
|
|
use App\Services\Audit\AuditRecorder;
|
|
use App\Support\Audit\AuditActorSnapshot;
|
|
use App\Support\Audit\AuditActorType;
|
|
use App\Support\Audit\AuditOutcome;
|
|
use App\Support\Audit\AuditTargetSnapshot;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
it('records workspace and tenant audit rows through the shared recorder', function (): void {
|
|
[$user, $tenant] = createUserWithTenant(role: 'owner');
|
|
|
|
$run = OperationRun::factory()->create([
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'user_id' => (int) $user->getKey(),
|
|
'type' => 'backup_create',
|
|
]);
|
|
|
|
$audit = app(AuditRecorder::class)->record(
|
|
action: 'backup.created',
|
|
context: [
|
|
'item_count' => 3,
|
|
'client_secret' => 'super-secret',
|
|
],
|
|
workspace: $tenant->workspace,
|
|
tenant: $tenant,
|
|
actor: AuditActorSnapshot::human($user),
|
|
target: new AuditTargetSnapshot(
|
|
type: 'backup_set',
|
|
id: '42',
|
|
label: 'Nightly backup',
|
|
),
|
|
outcome: 'completed',
|
|
summary: null,
|
|
operationRunId: (int) $run->getKey(),
|
|
)->refresh();
|
|
|
|
expect((int) $audit->workspace_id)->toBe((int) $tenant->workspace_id)
|
|
->and((int) $audit->tenant_id)->toBe((int) $tenant->getKey())
|
|
->and($audit->actorSnapshot()->type)->toBe(AuditActorType::Human)
|
|
->and($audit->actorDisplayLabel())->toBe($user->name)
|
|
->and($audit->resource_type)->toBe('backup_set')
|
|
->and((string) $audit->resource_id)->toBe('42')
|
|
->and($audit->targetDisplayLabel())->toBe('Nightly backup')
|
|
->and($audit->summaryText())->toBe('Backup set created for Nightly backup')
|
|
->and($audit->normalizedOutcome())->toBe(AuditOutcome::Success)
|
|
->and((int) $audit->operation_run_id)->toBe((int) $run->getKey())
|
|
->and(data_get($audit->metadata, 'client_secret'))->toBe('[REDACTED]')
|
|
->and(data_get($audit->metadata, 'item_count'))->toBe(3);
|
|
});
|
|
|
|
it('infers actor kind, target identity, and normalized outcome when snapshots are omitted', function (): void {
|
|
[$user, $tenant] = createUserWithTenant(role: 'owner');
|
|
|
|
$audit = app(AuditRecorder::class)->record(
|
|
action: 'backup_schedule.run_failed',
|
|
context: [
|
|
'_actor_type' => 'scheduled',
|
|
'backup_schedule_id' => 123,
|
|
'status' => 'failed',
|
|
'token' => 'top-secret',
|
|
],
|
|
workspace: $tenant->workspace,
|
|
tenant: $tenant,
|
|
)->refresh();
|
|
|
|
expect($audit->actorSnapshot()->type)->toBe(AuditActorType::Scheduled)
|
|
->and($audit->resource_type)->toBe('backup_schedule')
|
|
->and((string) $audit->resource_id)->toBe('123')
|
|
->and($audit->targetDisplayLabel())->toBe('Backup schedule #123')
|
|
->and($audit->normalizedOutcome())->toBe(AuditOutcome::Failed)
|
|
->and(data_get($audit->metadata, 'token'))->toBe('[REDACTED]');
|
|
});
|