TenantAtlas/tests/Feature/Graph/GraphContractRegistryCoverageSpec095Test.php
ahmido eec93b510a Spec 095: Graph contracts registry completeness + registry-backed call sites (#114)
Implements Spec 095.

What changed
- Registers 4 Graph resources in the contract registry (plus required subresource template)
- Refactors in-scope call sites to resolve Graph paths via the registry (no ad-hoc endpoints for these resources)
- Adds/updates regression tests to prevent future drift (missing registry entries and endpoint string reintroduction)
- Includes full SpecKit artifacts under specs/095-graph-contracts-registry-completeness/

Validation
- Focused tests:
  - `vendor/bin/sail artisan test --compact tests/Feature/Graph/GraphContractRegistryCoverageSpec095Test.php tests/Feature/SettingsCatalogDefinitionResolverTest.php`

Notes
- Livewire v4.0+ / Filament v5 compliant (no UI changes).
- No new routes/pages; no RBAC model changes.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #114
2026-02-15 15:02:27 +00:00

75 lines
3.5 KiB
PHP

<?php
declare(strict_types=1);
use App\Services\Graph\GraphContractRegistry;
it('Spec095 keeps graph contract entries for governed deviceManagement resources', function (): void {
$requiredResources = [
'configurationPolicyTemplate' => 'deviceManagement/configurationPolicyTemplates',
'settingsCatalogDefinition' => 'deviceManagement/configurationSettings',
'settingsCatalogCategory' => 'deviceManagement/configurationCategories',
'rbacRoleAssignment' => 'deviceManagement/roleAssignments',
];
foreach ($requiredResources as $contractType => $resourcePath) {
$resource = config("graph_contracts.types.{$contractType}.resource");
expect($resource)
->toBeString("Spec095 missing graph contract resource for {$contractType}")
->toBe($resourcePath, "Spec095 graph contract resource mismatch for {$contractType}");
}
$settingTemplatesPath = config('graph_contracts.types.configurationPolicyTemplate.subresources.settingTemplates.path');
expect($settingTemplatesPath)
->toBeString('Spec095 missing settingTemplates subresource for configurationPolicyTemplate');
expect(str_contains((string) $settingTemplatesPath, '{id}'))
->toBeTrue('Spec095 settingTemplates subresource path must include the parent {id} placeholder');
});
it('Spec095 keeps registry path helpers for governed resources', function (): void {
$contracts = app(GraphContractRegistry::class);
expect($contracts->configurationPolicyTemplateListPath())
->toBe('/deviceManagement/configurationPolicyTemplates');
expect($contracts->configurationPolicyTemplateItemPath('template/abc'))
->toBe('/deviceManagement/configurationPolicyTemplates/template%2Fabc');
expect($contracts->configurationPolicyTemplateSettingTemplatesPath('template/abc'))
->toBe('/deviceManagement/configurationPolicyTemplates/template%2Fabc/settingTemplates');
expect($contracts->settingsCatalogDefinitionItemPath('definition/abc'))
->toBe('/deviceManagement/configurationSettings/definition%2Fabc');
expect($contracts->settingsCatalogCategoryItemPath('category/abc'))
->toBe('/deviceManagement/configurationCategories/category%2Fabc');
expect($contracts->rbacRoleAssignmentItemPath('assignment/abc'))
->toBe('/deviceManagement/roleAssignments/assignment%2Fabc');
});
it('Spec095 guards against hardcoded governed endpoint strings in scoped call sites', function (): void {
$scopedGuards = [
'app/Services/Intune/ConfigurationPolicyTemplateResolver.php' => ['deviceManagement/configurationPolicyTemplates'],
'app/Services/Intune/SettingsCatalogDefinitionResolver.php' => ['deviceManagement/configurationSettings'],
'app/Services/Intune/SettingsCatalogCategoryResolver.php' => ['deviceManagement/configurationCategories'],
'app/Services/Intune/RbacOnboardingService.php' => ['deviceManagement/roleAssignments'],
'app/Services/Intune/RbacHealthService.php' => ['deviceManagement/roleAssignments'],
];
foreach ($scopedGuards as $file => $forbiddenSubstrings) {
$contents = file_get_contents(base_path($file));
expect($contents)
->not->toBeFalse("Spec095 regression guard could not read {$file}");
foreach ($forbiddenSubstrings as $forbiddenSubstring) {
expect(str_contains((string) $contents, $forbiddenSubstring))
->toBeFalse("Spec095 regression guard found hardcoded '{$forbiddenSubstring}' in {$file}; use GraphContractRegistry helper paths instead.");
}
}
});