TenantAtlas/apps/platform/tests/Feature/TenantConfiguration/Spec422ExchangeTeamsCoverageLevelPromotionTest.php
Ahmed Darrazi 4c1e14c6bc
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 6m9s
feat: complete spec 422 exchange teams comparable renderable pack
2026-06-30 06:18:15 +02:00

113 lines
5.2 KiB
PHP

<?php
declare(strict_types=1);
use App\Models\OperationRun;
use App\Models\ProviderConnection;
use App\Models\TenantConfigurationResource;
use App\Models\TenantConfigurationResourceEvidence;
use App\Models\TenantConfigurationResourceType;
use App\Services\TenantConfiguration\CoverageEvidenceWriter;
use App\Services\TenantConfiguration\CoverageSourceContractDecision;
use App\Services\TenantConfiguration\ResourceTypeRegistry;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\OperationRunType;
use App\Support\TenantConfiguration\CanonicalKeyKind;
use App\Support\TenantConfiguration\CaptureOutcome;
use App\Support\TenantConfiguration\ClaimState;
use App\Support\TenantConfiguration\CoverageLevel;
use App\Support\TenantConfiguration\EvidenceState;
use App\Support\TenantConfiguration\IdentityState;
use App\Support\TenantConfiguration\SourceClass;
it('Spec422 promotes selected Exchange and Teams content-backed evidence rows to renderable coverage', function (string $canonicalType, array $payload): void {
app(ResourceTypeRegistry::class)->syncDefaults();
[$user, $environment] = createMinimalUserWithTenant(role: 'owner');
$connection = ProviderConnection::factory()->withCredential()->create([
'workspace_id' => (int) $environment->workspace_id,
'managed_environment_id' => (int) $environment->getKey(),
]);
$resourceType = spec422PromotionResourceType($canonicalType);
$resource = TenantConfigurationResource::factory()->create([
'workspace_id' => (int) $environment->workspace_id,
'managed_environment_id' => (int) $environment->getKey(),
'provider_connection_id' => (int) $connection->getKey(),
'resource_type_id' => (int) $resourceType->getKey(),
'canonical_type' => $canonicalType,
'canonical_resource_key' => $canonicalType.':provider_external_id:spec422-promotion',
'canonical_key_kind' => CanonicalKeyKind::ProviderExternalId->value,
'source_resource_id' => 'spec422-promotion',
'source_display_name' => 'Spec422 promotion '.$canonicalType,
'source_class' => SourceClass::Tcm->value,
'latest_evidence_state' => EvidenceState::ContentBacked->value,
'latest_identity_state' => IdentityState::Stable->value,
'latest_claim_state' => ClaimState::InternalOnly->value,
]);
$run = OperationRun::factory()->withUser($user)->forTenant($environment)->create([
'type' => OperationRunType::TenantConfigurationCapture->value,
'status' => OperationRunStatus::Completed->value,
'outcome' => OperationRunOutcome::Succeeded->value,
]);
$evidence = app(CoverageEvidenceWriter::class)->append(
resource: $resource,
resourceType: $resourceType,
providerConnection: $connection,
operationRun: $run,
decision: new CoverageSourceContractDecision(
canonicalType: $canonicalType,
outcome: CaptureOutcome::Captured,
contractKey: 'spec422.synthetic.'.$canonicalType,
sourceEndpoint: '/spec422/synthetic/'.$canonicalType,
),
rawPayload: $payload,
normalizedPayload: $payload,
payloadHash: hash('sha256', json_encode($payload, JSON_THROW_ON_ERROR)),
);
expect($evidence)->toBeInstanceOf(TenantConfigurationResourceEvidence::class)
->and($evidence->coverage_level)->toBe(CoverageLevel::Renderable)
->and($resource->fresh()->latest_evidence_state)->toBe(EvidenceState::ContentBacked);
})->with([
'transportRule' => ['transportRule', ['DisplayName' => 'Rule', 'Enabled' => true, 'Actions' => ['RedirectMessageTo' => ['security@example.com']]]],
'acceptedDomain' => ['acceptedDomain', ['DomainName' => 'contoso.com', 'DomainType' => 'Authoritative', 'IsDefault' => true]],
'appPermissionPolicy' => ['appPermissionPolicy', ['DisplayName' => 'Policy', 'AllowAppList' => [['DisplayName' => 'Planner', 'AppId' => 'planner-app']]]],
'meetingPolicy' => ['meetingPolicy', ['DisplayName' => 'Meeting', 'AllowTranscription' => true]],
]);
it('Spec422 leaves deferred Exchange and Teams types unpromoted without content-backed evidence', function (): void {
app(ResourceTypeRegistry::class)->syncDefaults();
$resourceTypes = TenantConfigurationResourceType::query()
->whereIn('canonical_type', [
'remoteDomain',
'organizationConfig',
'sharedMailbox',
'mailboxPlan',
'appSetupPolicy',
'messagingPolicy',
'teamsUpdateManagementPolicy',
'voiceRoute',
])
->get()
->keyBy('canonical_type');
expect($resourceTypes)->toHaveCount(8);
foreach ($resourceTypes as $resourceType) {
expect($resourceType->default_coverage_level)->toBe(CoverageLevel::Detected)
->and($resourceType->default_evidence_state)->toBe(EvidenceState::NotCaptured)
->and($resourceType->allows_certified_claims)->toBeFalse();
}
});
function spec422PromotionResourceType(string $canonicalType): TenantConfigurationResourceType
{
return TenantConfigurationResourceType::query()
->where('canonical_type', $canonicalType)
->where('source_class', SourceClass::Tcm->value)
->firstOrFail();
}