Implemented the first version of the operator resolution guidance framework. Added new foundation classes (ResolutionCase, ResolutionAction) and a ReviewPackOutputResolutionAdapter. Updated the Customer Review Workspace and Environment Review Resource to use the new adapter. Added extensive test coverage for the framework and UI integrations. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #421
95 lines
3.9 KiB
PHP
95 lines
3.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Support\ResolutionGuidance\ResolutionAction;
|
|
use App\Support\ResolutionGuidance\ResolutionCase;
|
|
|
|
it('normalizes navigation and download actions into the shared contract shape', function (): void {
|
|
$navigation = ResolutionAction::fromArray([
|
|
'key' => 'review_output.open_review',
|
|
'label' => 'Open review',
|
|
'url' => '/admin/reviews/1',
|
|
'kind' => 'environment_link',
|
|
'icon' => 'heroicon-o-arrow-top-right-on-square',
|
|
], 'review_output.open_review');
|
|
$download = ResolutionAction::fromArray([
|
|
'key' => 'review_output.download_review_pack_with_limitations',
|
|
'label' => 'Download review pack with limitations',
|
|
'url' => '/admin/review-packs/1/download',
|
|
'kind' => 'download',
|
|
'icon' => 'heroicon-o-arrow-down-tray',
|
|
], 'review_output.download_review_pack_with_limitations');
|
|
|
|
expect($navigation['type'])->toBe(ResolutionAction::TYPE_NAVIGATION)
|
|
->and($navigation['kind'])->toBe('environment_link')
|
|
->and($download['type'])->toBe(ResolutionAction::TYPE_DOWNLOAD)
|
|
->and($download['kind'])->toBe('download');
|
|
});
|
|
|
|
it('degrades unsafe executable actions to a safe non-executable fallback', function (): void {
|
|
$action = ResolutionAction::fromArray([
|
|
'key' => 'review_output.retry_generation',
|
|
'label' => 'Retry generation',
|
|
'type' => ResolutionAction::TYPE_OPERATION_ACTION,
|
|
'url' => '/admin/operations/1',
|
|
'icon' => 'heroicon-o-arrow-path',
|
|
], 'review_output.retry_generation');
|
|
|
|
expect($action['type'])->toBe(ResolutionAction::TYPE_NAVIGATION)
|
|
->and($action['url'])->toBe('/admin/operations/1')
|
|
->and($action['capability'])->toBeNull()
|
|
->and($action['audit_event'])->toBeNull()
|
|
->and($action['requires_confirmation'])->toBeFalse()
|
|
->and($action['operation_run_type'])->toBeNull();
|
|
});
|
|
|
|
it('builds a resolution case with explicit scope and proof references', function (): void {
|
|
$case = ResolutionCase::make(
|
|
key: 'review_output.publication_blocked',
|
|
scope: [
|
|
'type' => 'review_pack',
|
|
'workspace_id' => 1,
|
|
'managed_environment_id' => 41,
|
|
'environment_review_id' => 6,
|
|
'source_surface' => 'customer_review_workspace',
|
|
],
|
|
severity: 'critical',
|
|
status: 'blocked',
|
|
title: 'Output not customer-ready',
|
|
reason: 'The published review is based on incomplete evidence.',
|
|
impact: 'Do not share the current review pack externally.',
|
|
primaryAction: ResolutionAction::fromArray([
|
|
'key' => 'review_output.resolve_review_blockers',
|
|
'label' => 'Inspect review blockers',
|
|
'url' => '/admin/reviews/6',
|
|
'kind' => 'environment_link',
|
|
], 'review_output.resolve_review_blockers'),
|
|
secondaryActions: [
|
|
ResolutionAction::fromArray([
|
|
'key' => 'review_output.open_evidence_basis',
|
|
'label' => 'Open evidence basis',
|
|
'url' => '/admin/evidence/8',
|
|
'kind' => 'environment_link',
|
|
], 'review_output.open_evidence_basis'),
|
|
],
|
|
sourceRefs: [
|
|
['type' => 'environment_review', 'id' => 6],
|
|
['type' => 'review_pack', 'id' => 8],
|
|
],
|
|
evidenceRefs: [
|
|
['type' => 'evidence_snapshot', 'id' => 8],
|
|
],
|
|
technicalDetails: [
|
|
'Review status' => 'Published',
|
|
],
|
|
);
|
|
|
|
expect($case['scope']['source_surface'])->toBe('customer_review_workspace')
|
|
->and($case['primary_action']['key'])->toBe('review_output.resolve_review_blockers')
|
|
->and($case['secondary_actions'])->toHaveCount(1)
|
|
->and($case['source_refs'])->toHaveCount(2)
|
|
->and($case['evidence_refs'])->toHaveCount(1)
|
|
->and($case['technical_details']['Review status'])->toBe('Published');
|
|
});
|