TenantAtlas/apps/platform/tests/Unit/Support/TenantConfiguration/Spec427SourceContractRedactionTest.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

63 lines
2.9 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\ExchangeTeamsComparablePayloadNormalizer;
use App\Services\TenantConfiguration\ResourceTypeRegistry;
it('Spec427 source contract metadata keeps raw payloads permission context and secrets out of default output', function (string $canonicalType): void {
$decision = (new CoverageSourceContractResolver(new GraphContractRegistry))
->resolve(spec427RedactionResourceType($canonicalType));
$rules = $decision->sourceMetadata['redaction_rules'];
$metadataJson = json_encode($decision->sourceMetadata, JSON_THROW_ON_ERROR);
expect($decision->sourceContractState)->toBe(CoverageSourceContractDecision::CONTRACT_BLOCKED_REPO_ADAPTER_MISSING)
->and($rules['raw_payload_default_visible'])->toBeFalse()
->and($rules['permission_context_default_visible'])->toBeFalse()
->and($rules['redacted_permission_context'])->toBeTrue()
->and($rules['forbidden_default_output'])->toContain('raw_provider_payload')
->and($rules['forbidden_default_output'])->toContain('tokens')
->and($rules['forbidden_default_output'])->toContain('credentials')
->and($rules['forbidden_default_output'])->toContain('mail_content')
->and($metadataJson)->not->toContain('client-secret-value')
->and($metadataJson)->not->toContain('authorization-token-value');
})->with([
'transportRule',
'acceptedDomain',
'appPermissionPolicy',
'meetingPolicy',
]);
it('Spec427 preserves Exchange and Teams helper redaction for future verified payloads', function (): void {
$normalized = app(ExchangeTeamsComparablePayloadNormalizer::class)->normalize('transportRule', [
'Guid' => 'rule-guid',
'DisplayName' => 'Sensitive transport rule',
'ProviderResponse' => 'raw-provider-response-secret',
'SubjectContainsWords' => ['private subject phrase'],
'clientSecret' => 'client-secret-value',
]);
$json = json_encode($normalized, JSON_THROW_ON_ERROR);
expect($json)
->not->toContain('raw-provider-response-secret')
->not->toContain('private subject phrase')
->not->toContain('client-secret-value')
->and(data_get($normalized, 'conditions.subject_contains_words'))->toBe('[redacted]');
});
function spec427RedactionResourceType(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);
}