'A', 'type' => 'application', 'description' => null, 'features' => ['backup'], 'status' => 'missing', 'details' => null, ], [ 'key' => 'B', 'type' => 'delegated', 'description' => null, 'features' => ['backup'], 'status' => 'missing', 'details' => null, ], ]; expect(TenantRequiredPermissionsViewModelBuilder::deriveOverallStatus($rows)) ->toBe(VerificationReportOverall::Blocked->value); }); it('maps overall to needs_attention when only delegated permissions are missing', function (): void { $rows = [ [ 'key' => 'A', 'type' => 'application', 'description' => null, 'features' => ['backup'], 'status' => 'granted', 'details' => null, ], [ 'key' => 'B', 'type' => 'delegated', 'description' => null, 'features' => ['backup'], 'status' => 'missing', 'details' => null, ], ]; expect(TenantRequiredPermissionsViewModelBuilder::deriveOverallStatus($rows)) ->toBe(VerificationReportOverall::NeedsAttention->value); }); it('maps overall to needs_attention when any permission is in error', function (): void { $rows = [ [ 'key' => 'A', 'type' => 'application', 'description' => null, 'features' => ['backup'], 'status' => 'granted', 'details' => null, ], [ 'key' => 'B', 'type' => 'application', 'description' => null, 'features' => ['backup'], 'status' => 'error', 'details' => ['source' => 'graph_api'], ], ]; expect(TenantRequiredPermissionsViewModelBuilder::deriveOverallStatus($rows)) ->toBe(VerificationReportOverall::NeedsAttention->value); }); it('maps overall to ready when nothing is missing', function (): void { $rows = [ [ 'key' => 'A', 'type' => 'application', 'description' => null, 'features' => ['backup'], 'status' => 'granted', 'details' => null, ], [ 'key' => 'B', 'type' => 'delegated', 'description' => null, 'features' => ['backup'], 'status' => 'granted', 'details' => null, ], ]; expect(TenantRequiredPermissionsViewModelBuilder::deriveOverallStatus($rows)) ->toBe(VerificationReportOverall::Ready->value); });