TenantAtlas/apps/platform/tests/Unit/Support/TenantConfiguration/Spec427SourceContractResponseShapeTest.php
ahmido bfb52b84d6 feat: implement spec 427 source contract enablement (#494)
Automated PR for spec 427 Exchange Teams verified source contract enablement.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #494
2026-07-03 23:12:45 +00:00

45 lines
2.3 KiB
PHP

<?php
declare(strict_types=1);
use App\Models\TenantConfigurationResourceType;
use App\Services\Graph\GraphContractRegistry;
use App\Services\TenantConfiguration\CoverageSourceContractDecision;
use App\Services\TenantConfiguration\CoverageSourceContractResolver;
use App\Services\TenantConfiguration\ResourceTypeRegistry;
it('Spec427 response metadata keeps empty denied unavailable unsupported and malformed outcomes distinct before verification', function (string $canonicalType): void {
$decision = (new CoverageSourceContractResolver(new GraphContractRegistry))
->resolve(spec427ResponseShapeResourceType($canonicalType));
$shape = $decision->sourceMetadata['response_shape'];
expect($decision->sourceContractState)->toBe(CoverageSourceContractDecision::CONTRACT_BLOCKED_REPO_ADAPTER_MISSING)
->and($shape['raw_payload_shape'])->toBe('provider_collection_candidate')
->and($shape['collection_semantics'])->toBe('collection_candidate')
->and($shape['pagination_model'])->toBe('blocked_until_adapter_exists')
->and($shape['empty_response_meaning'])->toBe('must_be_distinguished_by_future_adapter')
->and($shape['permission_denied_response_meaning'])->toBe('must_be_distinguished_by_future_adapter')
->and($shape['unsupported_response_meaning'])->toBe('must_be_distinguished_by_future_adapter')
->and($shape['source_unavailable_response_meaning'])->toBe('must_be_distinguished_by_future_adapter')
->and($shape['malformed_response_meaning'])->toBe('must_be_distinguished_by_future_adapter')
->and($shape['response_shape_safety'])->toBe('blocked_until_empty_denied_unsupported_unavailable_and_malformed_are_distinguishable')
->and($shape['collection_item_path'])->toBe('value')
->and($shape['pagination_cursor_path'])->toBe('@odata.nextLink');
})->with([
'transportRule',
'acceptedDomain',
'appPermissionPolicy',
'meetingPolicy',
]);
function spec427ResponseShapeResourceType(string $canonicalType): TenantConfigurationResourceType
{
$definition = collect(ResourceTypeRegistry::defaultDefinitions())
->firstWhere('canonical_type', $canonicalType);
expect($definition)->not->toBeNull("Missing default resource type definition for {$canonicalType}.");
return new TenantConfigurationResourceType($definition);
}