TenantAtlas/apps/platform/tests/Unit/Providers/ProviderBoundaryClassificationTest.php
Ahmed Darrazi 079a7dcaf3
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 57s
feat: harden provider boundaries
2026-04-24 22:55:44 +02:00

58 lines
2.8 KiB
PHP

<?php
use App\Support\Providers\Boundary\ProviderBoundaryCatalog;
use App\Support\Providers\Boundary\ProviderBoundaryOwner;
use App\Support\Providers\Boundary\ProviderBoundarySeam;
it('classifies the authoritative first-slice provider seams', function (): void {
$catalog = app(ProviderBoundaryCatalog::class);
expect(array_keys($catalog->all()))->toBe([
'provider.connection_resolution',
'provider.gateway_runtime',
'provider.identity_resolution',
'provider.operation_registry',
'provider.operation_start_gate',
]);
expect($catalog->get('provider.gateway_runtime')->owner)->toBe(ProviderBoundaryOwner::ProviderOwned);
expect($catalog->get('provider.identity_resolution')->owner)->toBe(ProviderBoundaryOwner::PlatformCore);
expect($catalog->get('provider.connection_resolution')->owner)->toBe(ProviderBoundaryOwner::PlatformCore);
expect($catalog->get('provider.operation_registry')->owner)->toBe(ProviderBoundaryOwner::PlatformCore);
expect($catalog->get('provider.operation_start_gate')->owner)->toBe(ProviderBoundaryOwner::PlatformCore);
});
it('records implementation paths and bounded exception metadata for platform-core seams', function (): void {
$catalog = app(ProviderBoundaryCatalog::class);
$identity = $catalog->get('provider.identity_resolution');
expect($identity->coversPath('app/Services/Providers/ProviderIdentityResolution.php'))->toBeTrue()
->and($identity->neutralTerms)->toContain('target scope')
->and($identity->retainedProviderSemantics)->toContain('entra_tenant_id')
->and($identity->retainedProviderSemantics)->not->toContain('Microsoft Graph option keys')
->and($identity->followUpAction)->toBe(ProviderBoundarySeam::FOLLOW_UP_SPEC);
$registry = $catalog->get('provider.operation_registry');
expect($registry->neutralTerms)->toContain('provider binding')
->and($registry->retainedProviderSemantics)->toContain('active provider binding')
->and($registry->followUpAction)->toBe(ProviderBoundarySeam::FOLLOW_UP_DOCUMENT_IN_FEATURE);
});
it('aligns the catalog shape with the logical boundary contract', function (): void {
$seam = app(ProviderBoundaryCatalog::class)->get('provider.operation_start_gate');
expect($seam->key)->toBe('provider.operation_start_gate')
->and($seam->owner->value)->toBeIn(ProviderBoundaryOwner::values())
->and($seam->description)->not->toBeEmpty()
->and($seam->implementationPaths)->not->toBeEmpty()
->and($seam->neutralTerms)->not->toBeEmpty()
->and($seam->retainedProviderSemantics)->toContain('target_scope.entra_tenant_id')
->and($seam->followUpAction)->toBeIn([
ProviderBoundarySeam::FOLLOW_UP_NONE,
ProviderBoundarySeam::FOLLOW_UP_DOCUMENT_IN_FEATURE,
ProviderBoundarySeam::FOLLOW_UP_SPEC,
]);
});