create(); $olderBasis = createInventorySyncOperationRunWithCoverage($tenant, [ 'deviceConfiguration' => ['status' => 'succeeded', 'item_count' => 1], ], attributes: [ 'completed_at' => now()->subHours(2), 'outcome' => 'succeeded', ]); createInventorySyncOperationRun($tenant, [ 'status' => 'completed', 'outcome' => 'failed', 'completed_at' => now()->subMinute(), ]); $latestCoverageBearing = createInventorySyncOperationRunWithCoverage($tenant, [ 'deviceConfiguration' => ['status' => 'failed', 'item_count' => 2, 'error_code' => 'graph_forbidden'], ], attributes: [ 'completed_at' => now()->subMinutes(5), 'outcome' => 'failed', ]); expect(OperationRun::latestCompletedCoverageBearingInventorySyncForTenant((int) $tenant->getKey())?->is($latestCoverageBearing)) ->toBeTrue() ->and(OperationRun::latestCompletedCoverageBearingInventorySyncForTenant((int) $tenant->getKey())?->is($olderBasis)) ->toBeFalse(); $truth = app(TenantCoverageTruthResolver::class)->resolve($tenant); expect($truth->basisRunId())->toBe((int) $latestCoverageBearing->getKey()) ->and($truth->basisRunOutcome())->toBe('failed') ->and($truth->hasCurrentCoverageResult)->toBeTrue(); }); it('derives per-type coverage truth, observed counts, and deterministic follow-up order', function (): void { $tenant = Tenant::factory()->create(); InventoryItem::factory()->count(3)->create([ 'tenant_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceCompliancePolicy', ]); InventoryItem::factory()->count(2)->create([ 'tenant_id' => (int) $tenant->getKey(), 'policy_type' => 'conditionalAccessPolicy', ]); InventoryItem::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', ]); createInventorySyncOperationRunWithCoverage($tenant, [ 'deviceCompliancePolicy' => [ 'status' => 'failed', 'item_count' => 3, 'error_code' => 'graph_forbidden', ], 'deviceConfiguration' => [ 'status' => 'succeeded', 'item_count' => 1, ], 'roleScopeTag' => [ 'status' => 'skipped', 'item_count' => 0, ], ], foundationTypes: ['roleScopeTag'], attributes: [ 'completed_at' => now(), 'outcome' => 'partially_succeeded', ]); $truth = app(TenantCoverageTruthResolver::class)->resolve($tenant); $rowsByType = collect($truth->rows)->keyBy( static fn (TenantCoverageTypeTruth $row): string => $row->type, ); expect($truth->supportedTypeCount)->toBeGreaterThanOrEqual(4) ->and($truth->succeededTypeCount)->toBe(1) ->and($truth->failedTypeCount)->toBe(1) ->and($truth->skippedTypeCount)->toBe(1) ->and($truth->unknownTypeCount)->toBe($truth->supportedTypeCount - 3) ->and($truth->followUpTypeCount)->toBe($truth->supportedTypeCount - 1) ->and($truth->observedItemTotal)->toBe(6); expect($rowsByType['deviceCompliancePolicy']) ->coverageState->toBe('failed') ->basisErrorCode->toBe('graph_forbidden') ->basisItemCount->toBe(3) ->followUpGuidance->toBe('Review provider consent or permissions, then rerun inventory sync.'); expect($rowsByType['conditionalAccessPolicy']) ->coverageState->toBe('unknown') ->observedItemCount->toBe(2) ->followUpGuidance->toBe('No current basis result exists for this type. Run inventory sync to confirm coverage.'); expect($rowsByType['deviceConfiguration']) ->coverageState->toBe('succeeded') ->basisItemCount->toBe(1) ->followUpRequired->toBeFalse(); expect($rowsByType['roleScopeTag']) ->coverageState->toBe('skipped') ->segment->toBe('foundation') ->followUpGuidance->toBe('Run inventory sync again with the required types selected.'); $orderedTypes = array_map( static fn (TenantCoverageTypeTruth $row): string => $row->type, $truth->rows, ); expect(array_search('deviceCompliancePolicy', $orderedTypes, true))->toBeLessThan(array_search('conditionalAccessPolicy', $orderedTypes, true)) ->and(array_search('conditionalAccessPolicy', $orderedTypes, true))->toBeLessThan(array_search('roleScopeTag', $orderedTypes, true)) ->and($truth->topPriorityFollowUpRow()?->type)->toBe('deviceCompliancePolicy'); }); it('returns unknown coverage rows when no basis run exists', function (): void { $tenant = Tenant::factory()->create(); InventoryItem::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'policy_type' => 'deviceConfiguration', ]); $truth = app(TenantCoverageTruthResolver::class)->resolve($tenant); expect($truth->hasCurrentCoverageResult)->toBeFalse() ->and($truth->basisRunId())->toBeNull() ->and($truth->succeededTypeCount)->toBe(0) ->and($truth->failedTypeCount)->toBe(0) ->and($truth->skippedTypeCount)->toBe(0) ->and($truth->unknownTypeCount)->toBe($truth->supportedTypeCount) ->and($truth->followUpTypeCount)->toBe($truth->supportedTypeCount) ->and($truth->observedItemTotal)->toBe(1) ->and($truth->topPriorityFollowUpRow())->not->toBeNull(); });