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); }