TenantAtlas/apps/platform/tests/Unit/ResolutionGuidance/Spec350ReviewPackResolutionAdapterTest.php
ahmido d4e4d2d109 feat: review output resolve actions v1 (spec 351) (#422)
Implemented the first version of review output resolve actions. Included a ReviewOutputResolveActionMapper, commands to seed browser fixtures, updated CustomerReviewWorkspace, EnvironmentReviewResource, UI enforcement, and related views. Also added extensive unit, feature, and browser tests, and updated the design coverage matrix.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #422
2026-06-04 00:55:02 +00:00

112 lines
4.5 KiB
PHP

<?php
declare(strict_types=1);
use App\Models\EnvironmentReview;
use App\Models\EvidenceSnapshot;
use App\Models\ReviewPack;
use App\Support\EnvironmentReviewCompletenessState;
use App\Support\ResolutionGuidance\Adapters\ReviewPackOutputResolutionAdapter;
use App\Support\ResolutionGuidance\ResolutionAction;
use App\Support\ReviewPacks\ReviewPackOutputReadiness;
use App\Support\ReviewPacks\ReviewPackOutputResolutionGuidance;
it('maps publication-blocked review output guidance into one shared resolution case', function (): void {
$readiness = ReviewPackOutputReadiness::derive(
reviewStatus: 'published',
reviewCompletenessState: EnvironmentReviewCompletenessState::Complete->value,
evidenceCompletenessState: EnvironmentReviewCompletenessState::Partial->value,
sectionStateCounts: [
EnvironmentReviewCompletenessState::Complete->value => 3,
EnvironmentReviewCompletenessState::Missing->value => 2,
],
requiredSectionCount: 5,
requiredSectionStateCounts: [
EnvironmentReviewCompletenessState::Complete->value => 3,
EnvironmentReviewCompletenessState::Missing->value => 2,
],
publishBlockers: ['Operator approval note is still missing.'],
hasReadyExport: false,
includePii: false,
protectedValuesHidden: true,
disclosurePresent: true,
);
$guidance = ReviewPackOutputResolutionGuidance::fromReadiness($readiness, [
'download' => '/admin/review-packs/8/download',
'review' => '/admin/reviews/6',
'evidence' => '/admin/evidence/8',
]);
$review = new EnvironmentReview;
$review->forceFill([
'id' => 6,
'workspace_id' => 1,
'managed_environment_id' => 41,
'status' => 'published',
]);
$review->setRelation('evidenceSnapshot', tap(new EvidenceSnapshot, function (EvidenceSnapshot $snapshot): void {
$snapshot->forceFill(['id' => 8]);
}));
$review->setRelation('currentExportReviewPack', tap(new ReviewPack, function (ReviewPack $pack): void {
$pack->forceFill(['id' => 8]);
}));
$case = ReviewPackOutputResolutionAdapter::fromGuidance($review, $guidance, 'customer_review_workspace');
expect($case['key'])->toBe('review_output.publication_blocked')
->and($case['severity'])->toBe('critical')
->and($case['status'])->toBe('blocked')
->and($case['title'])->toBe('Output not customer-ready')
->and($case['primary_action']['key'])->toBe('resolve_review_blockers')
->and($case['primary_action']['type'])->toBe(ResolutionAction::TYPE_NAVIGATION)
->and($case['source_refs'])->toEqual([
['type' => 'environment_review', 'id' => 6],
['type' => 'review_pack', 'id' => 8],
])
->and($case['evidence_refs'])->toEqual([
['type' => 'evidence_snapshot', 'id' => 8],
]);
});
it('maps ready customer-safe exports to a download-first shared resolution case', function (): void {
$readiness = ReviewPackOutputReadiness::derive(
reviewStatus: 'published',
reviewCompletenessState: EnvironmentReviewCompletenessState::Complete->value,
evidenceCompletenessState: EnvironmentReviewCompletenessState::Complete->value,
sectionStateCounts: [
EnvironmentReviewCompletenessState::Complete->value => 5,
],
requiredSectionCount: 5,
requiredSectionStateCounts: [
EnvironmentReviewCompletenessState::Complete->value => 5,
],
publishBlockers: [],
hasReadyExport: true,
includePii: false,
protectedValuesHidden: true,
disclosurePresent: true,
);
$guidance = ReviewPackOutputResolutionGuidance::fromReadiness($readiness, [
'download' => '/admin/review-packs/8/download',
'review' => '/admin/reviews/6',
]);
$review = new EnvironmentReview;
$review->forceFill([
'id' => 6,
'workspace_id' => 1,
'managed_environment_id' => 41,
'status' => 'published',
]);
$case = ReviewPackOutputResolutionAdapter::fromGuidance($review, $guidance, 'customer_review_workspace');
expect($case['key'])->toBe('review_output.customer_safe_ready')
->and($case['severity'])->toBe('success')
->and($case['status'])->toBe('ready')
->and($case['primary_action']['key'])->toBe('download_customer_safe_review_pack')
->and($case['primary_action']['type'])->toBe(ResolutionAction::TYPE_DOWNLOAD);
});