Added jobs, controllers, and PDF generation logic for management report runtime as defined in Spec 379. Includes artifact migrations, payload builders, and testing coverage. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #450
63 lines
2.7 KiB
PHP
63 lines
2.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Services\Evidence\Sources\BaselineDriftPostureSource;
|
|
use App\Support\Evidence\EvidenceCompletenessState;
|
|
use App\Support\OperationRunOutcome;
|
|
|
|
it('keeps baseline drift posture missing when no drift findings or compare proof exist', function (): void {
|
|
[, $tenant] = createUserWithTenant(role: 'owner');
|
|
|
|
$payload = app(BaselineDriftPostureSource::class)->collect($tenant);
|
|
|
|
expect($payload['state'])->toBe(EvidenceCompletenessState::Missing->value)
|
|
->and($payload['summary_payload']['drift_count'])->toBe(0)
|
|
->and($payload['summary_payload']['latest_compare_run_id'])->toBeNull();
|
|
});
|
|
|
|
it('marks no baseline drift as complete when the latest compare succeeded', function (): void {
|
|
[, $tenant] = createUserWithTenant(role: 'owner');
|
|
[$profile, $snapshot] = seedActiveBaselineForTenant($tenant);
|
|
|
|
$run = seedBaselineCompareRun(
|
|
tenant: $tenant,
|
|
profile: $profile,
|
|
snapshot: $snapshot,
|
|
compareContext: ['reason_code' => 'baseline.compare.no_drift_detected'],
|
|
outcome: OperationRunOutcome::Succeeded->value,
|
|
);
|
|
|
|
$payload = app(BaselineDriftPostureSource::class)->collect($tenant);
|
|
|
|
expect($payload['state'])->toBe(EvidenceCompletenessState::Complete->value)
|
|
->and($payload['measured_at']?->equalTo($run->completed_at))->toBeTrue()
|
|
->and($payload['summary_payload']['drift_count'])->toBe(0)
|
|
->and($payload['summary_payload']['latest_compare_run_id'])->toBe((int) $run->getKey())
|
|
->and($payload['summary_payload']['latest_compare_outcome'])->toBe(OperationRunOutcome::Succeeded->value);
|
|
});
|
|
|
|
it('marks no baseline drift as partial when the latest compare completed with warnings', function (): void {
|
|
[, $tenant] = createUserWithTenant(role: 'owner');
|
|
[$profile, $snapshot] = seedActiveBaselineForTenant($tenant);
|
|
|
|
$run = seedBaselineCompareRun(
|
|
tenant: $tenant,
|
|
profile: $profile,
|
|
snapshot: $snapshot,
|
|
compareContext: [
|
|
'reason_code' => 'baseline.compare.no_drift_detected',
|
|
'evidence_gaps' => ['count' => 3],
|
|
],
|
|
outcome: OperationRunOutcome::PartiallySucceeded->value,
|
|
);
|
|
|
|
$payload = app(BaselineDriftPostureSource::class)->collect($tenant);
|
|
|
|
expect($payload['state'])->toBe(EvidenceCompletenessState::Partial->value)
|
|
->and($payload['measured_at']?->equalTo($run->completed_at))->toBeTrue()
|
|
->and($payload['summary_payload']['drift_count'])->toBe(0)
|
|
->and($payload['summary_payload']['latest_compare_run_id'])->toBe((int) $run->getKey())
|
|
->and($payload['summary_payload']['latest_compare_outcome'])->toBe(OperationRunOutcome::PartiallySucceeded->value);
|
|
});
|