[ fn (\App\Models\Tenant $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() ->for($tenant) ->for($backupSet) ->failedOutcome() ->create([ 'completed_at' => now()->subMinutes(10), ]), 'failed', 'The dashboard opened this restore run because the latest executed restore failed.', 'The restore did not complete successfully. Follow-up is still required.', ], 'partial' => [ fn (\App\Models\Tenant $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() ->for($tenant) ->for($backupSet) ->partialOutcome() ->create([ 'completed_at' => now()->subMinutes(10), ]), 'partial', 'The dashboard opened this restore run because the latest executed restore completed partially.', 'The restore reached a terminal state, but some items or assignments still need follow-up.', ], 'completed with follow-up' => [ fn (\App\Models\Tenant $tenant, BackupSet $backupSet): RestoreRun => RestoreRun::factory() ->for($tenant) ->for($backupSet) ->completedWithFollowUp() ->create([ 'completed_at' => now()->subMinutes(10), ]), 'completed_with_follow_up', 'The dashboard opened this restore run because skipped or non-applied work still needs follow-up.', 'The restore completed, but follow-up remains for skipped or non-applied work.', ], ]); it('elevates restore result attention above raw item diagnostics', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); $backupSet = BackupSet::factory()->create([ 'tenant_id' => $tenant->id, ]); $restoreRun = RestoreRun::factory()->create([ 'tenant_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', 'results' => [ 'foundations' => [], 'items' => [ 1 => [ 'status' => 'applied', 'policy_identifier' => 'policy-1', 'assignment_outcomes' => [ ['status' => 'skipped', 'assignment' => []], ], ], ], ], 'metadata' => [ 'non_applied' => 1, 'scope_basis' => [ 'fingerprint' => 'scope-1', 'scope_mode' => 'selected', 'selected_item_ids' => [1], ], 'preview_basis' => [ 'fingerprint' => 'scope-1', 'generated_at' => now('UTC')->toIso8601String(), ], 'check_basis' => [ 'fingerprint' => 'scope-1', 'ran_at' => now('UTC')->toIso8601String(), 'blocking_count' => 0, 'warning_count' => 0, ], 'execution_safety_snapshot' => [ 'safety_state' => 'ready_with_caution', 'follow_up_boundary' => 'run_completed_not_recovery_proven', ], ], ]); Filament::setTenant($tenant, true); Livewire::test(ViewRestoreRun::class, ['record' => $restoreRun->getKey()]) ->assertSee('Follow-up required') ->assertSee('Review skipped or non-applied items before closing the run.') ->assertSee('No dominant cause recorded') ->assertSee('Tenant-wide recovery is not proven.') ->assertDontSee('review_skipped_items') ->assertDontSee('run_completed_not_recovery_proven'); }); it('shows not run checks instead of legacy stale for preview-only runs without checks evidence', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); $backupSet = BackupSet::factory()->create([ 'tenant_id' => $tenant->id, ]); /** @var RestoreSafetyResolver $resolver */ $resolver = app(RestoreSafetyResolver::class); $previewData = [ 'backup_set_id' => (int) $backupSet->getKey(), 'scope_mode' => 'all', 'backup_item_ids' => [], 'group_mapping' => [], 'preview_summary' => [ 'generated_at' => now('UTC')->toIso8601String(), 'policies_total' => 1, 'policies_changed' => 1, 'assignments_changed' => 0, 'scope_tags_changed' => 0, ], 'preview_ran_at' => now('UTC')->toIso8601String(), ]; $previewBasis = $resolver->previewBasisFromData($previewData); $restoreRun = RestoreRun::factory()->create([ 'tenant_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'previewed', 'is_dry_run' => true, 'preview' => [ [ 'policy_identifier' => 'policy-1', 'policy_type' => 'settingsCatalogPolicy', 'platform' => 'windows', 'action' => 'update', ], ], 'metadata' => [ 'scope_basis' => [ 'fingerprint' => 'scope-1', 'scope_mode' => 'all', 'selected_item_ids' => [], ], 'preview_summary' => $previewData['preview_summary'], 'preview_ran_at' => $previewData['preview_ran_at'], 'preview_basis' => $previewBasis, 'check_basis' => [], 'check_summary' => [], ], ]); Filament::setTenant($tenant, true); Livewire::test(ViewRestoreRun::class, ['record' => $restoreRun->getKey()]) ->assertSee('Current basis') ->assertSee('Not run') ->assertSee('Preview evidence is current for the selected restore scope.') ->assertSee('No execution was performed from this record.') ->assertDontSee('preview_only_no_execution_proven') ->assertDontSee('Legacy stale'); }); it('renders preview-only foundations without falling back to unknown', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); $backupSet = BackupSet::factory()->create([ 'tenant_id' => $tenant->id, ]); $restoreRun = RestoreRun::factory()->create([ 'tenant_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'previewed', 'is_dry_run' => true, 'preview' => [ [ 'type' => 'intuneRoleDefinition', 'sourceId' => 'role-def-1', 'sourceName' => 'Application Manager', 'decision' => 'dry_run', 'reason' => 'preview_only', ], ], 'metadata' => [ 'scope_basis' => [ 'fingerprint' => 'scope-1', 'scope_mode' => 'all', 'selected_item_ids' => [], ], 'preview_basis' => [ 'fingerprint' => 'scope-1', 'generated_at' => now('UTC')->toIso8601String(), ], ], ]); Filament::setTenant($tenant, true); Livewire::test(ViewRestoreRun::class, ['record' => $restoreRun->getKey()]) ->assertSee('Application Manager') ->assertSee('Preview only') ->assertSee('Preview only. This foundation type is not applied during execution.') ->assertDontSee('Unknown'); }); it('renders preview-only result foundations without exposing raw reason codes', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); $backupSet = BackupSet::factory()->create([ 'tenant_id' => $tenant->id, ]); $restoreRun = RestoreRun::factory()->create([ 'tenant_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', 'is_dry_run' => false, 'results' => [ 'foundations' => [ [ 'type' => 'intuneRoleDefinition', 'sourceId' => 'role-def-1', 'sourceName' => 'Application Manager', 'decision' => 'dry_run', 'reason' => 'preview_only', ], ], 'items' => [], ], ]); Filament::setTenant($tenant, true); Livewire::test(ViewRestoreRun::class, ['record' => $restoreRun->getKey()]) ->assertSee('Application Manager') ->assertSee('Preview only') ->assertSee('Preview only. This foundation type is not applied during execution.') ->assertDontSee('Unknown'); }); it('keeps dashboard-linked restore-result confirmation aligned for problematic restore runs', function ( Closure $makeRestoreRun, string $reason, string $expectedSubheading, string $expectedSummary, ): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); $backupSet = BackupSet::factory()->for($tenant)->create(); $restoreRun = $makeRestoreRun($tenant, $backupSet); Filament::setTenant($tenant, true); $this->get(RestoreRunResource::getUrl('view', [ 'record' => (int) $restoreRun->getKey(), 'recovery_posture_reason' => $reason, ], panel: 'tenant', tenant: $tenant)) ->assertOk() ->assertSee($expectedSubheading) ->assertSee($expectedSummary); })->with('dashboard-linked-restore-result-reasons');