Automated PR for spec 427 Exchange Teams verified source contract enablement. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #494
66 lines
2.8 KiB
PHP
66 lines
2.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Models\TenantConfigurationResourceType;
|
|
use App\Services\Graph\GraphContractRegistry;
|
|
use App\Services\TenantConfiguration\CanonicalIdentityResolver;
|
|
use App\Services\TenantConfiguration\CoverageSourceContractDecision;
|
|
use App\Services\TenantConfiguration\CoverageSourceContractResolver;
|
|
use App\Services\TenantConfiguration\ResourceTypeRegistry;
|
|
use App\Support\TenantConfiguration\IdentityState;
|
|
|
|
it('Spec427 identity handoff metadata uses stable candidates and rejects display-name identity', function (string $canonicalType): void {
|
|
$decision = (new CoverageSourceContractResolver(new GraphContractRegistry))
|
|
->resolve(spec427IdentityResourceType($canonicalType));
|
|
|
|
$handoff = $decision->sourceMetadata['identity_handoff'];
|
|
|
|
expect($decision->sourceContractState)->toBe(CoverageSourceContractDecision::CONTRACT_BLOCKED_REPO_ADAPTER_MISSING)
|
|
->and($handoff['identity_stability_class'])->toBe('stable_candidate')
|
|
->and($handoff['singleton_or_collection_identity_rule'])->toBe('collection_item_identity_required')
|
|
->and($handoff['display_name_is_stable_identity'])->toBeFalse()
|
|
->and($handoff['known_identity_risks'])->toContain('display_name_not_stable')
|
|
->and($handoff['known_identity_risks'])->toContain('order_and_payload_hash_not_stable_identity');
|
|
|
|
$identityFields = [
|
|
...$handoff['preferred_identity_fields'],
|
|
...$handoff['fallback_identity_fields'],
|
|
];
|
|
|
|
expect(array_intersect($identityFields, ['displayName', 'DisplayName', 'name', 'Name', 'Identity']))
|
|
->toBe([]);
|
|
})->with([
|
|
'transportRule',
|
|
'acceptedDomain',
|
|
'appPermissionPolicy',
|
|
'meetingPolicy',
|
|
]);
|
|
|
|
it('Spec427 keeps display-only payloads blocked from stable identity readiness', function (string $canonicalType): void {
|
|
$result = app(CanonicalIdentityResolver::class)->resolve(
|
|
spec427IdentityResourceType($canonicalType),
|
|
['DisplayName' => 'Display-only object', 'Name' => 'Display-only object', 'Identity' => 'Global'],
|
|
['source_contract_key' => $canonicalType, 'source_version' => 'not_verified'],
|
|
);
|
|
|
|
expect($result->identityState)->toBe(IdentityState::MissingExternalId)
|
|
->and($result->sourceResourceId)->toStartWith('missing:')
|
|
->and($result->canonicalResourceKey)->not->toContain('Display-only object');
|
|
})->with([
|
|
'transportRule',
|
|
'acceptedDomain',
|
|
'appPermissionPolicy',
|
|
'meetingPolicy',
|
|
]);
|
|
|
|
function spec427IdentityResourceType(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);
|
|
}
|