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

101 lines
4.3 KiB
PHP

<?php
declare(strict_types=1);
use App\Services\TenantConfiguration\ExchangeTeamsCoverageComparator;
it('Spec422 treats Exchange and Teams volatile-only differences as unchanged', function (string $canonicalType, array $payload): void {
$result = app(ExchangeTeamsCoverageComparator::class)->compare(
$canonicalType,
[...$payload, 'modifiedDateTime' => '2026-06-28T10:00:00Z'],
[...$payload, 'modifiedDateTime' => '2026-06-28T11:00:00Z'],
);
expect($result['changed'])->toBeFalse()
->and($result['classification'])->toBe('unchanged')
->and(collect($result['changes'])->pluck('classification'))->toContain('ignored_volatile');
})->with([
'transport rule' => ['transportRule', ['DisplayName' => 'Rule', 'Enabled' => true]],
'meeting policy' => ['meetingPolicy', ['DisplayName' => 'Meeting', 'AllowCloudRecording' => true]],
]);
it('Spec422 detects material Exchange and Teams changes with bounded importance', function (string $canonicalType, array $before, array $after, string $field, string $importance, string $classification = 'changed'): void {
$result = app(ExchangeTeamsCoverageComparator::class)->compare($canonicalType, $before, $after);
$change = collect($result['changes'])->firstWhere('field', $field);
expect($result['changed'])->toBeTrue()
->and($result['classification'])->toBe('changed')
->and($change)->not->toBeNull()
->and($change['classification'])->toBe($classification)
->and($change['importance'])->toBe($importance);
})->with([
'transport enabled' => [
'transportRule',
['DisplayName' => 'Rule', 'Enabled' => true],
['DisplayName' => 'Rule', 'Enabled' => false],
'enabled_state',
'critical',
],
'accepted domain default' => [
'acceptedDomain',
['DomainName' => 'contoso.com', 'IsDefault' => false],
['DomainName' => 'contoso.com', 'IsDefault' => true],
'is_default',
'critical',
],
'app blocked list' => [
'appPermissionPolicy',
['DisplayName' => 'Policy', 'BlockAppList' => []],
['DisplayName' => 'Policy', 'BlockAppList' => [['DisplayName' => 'Consumer App', 'AppId' => 'consumer-app']]],
'blocked_apps',
'critical',
'added',
],
'meeting transcription' => [
'meetingPolicy',
['DisplayName' => 'Meeting', 'AllowTranscription' => false],
['DisplayName' => 'Meeting', 'AllowTranscription' => true],
'recording_transcription.allow_transcription',
'critical',
],
]);
it('Spec422 keeps array ordering stable and handles null or empty values explicitly', function (): void {
$ordered = app(ExchangeTeamsCoverageComparator::class)->compare('appPermissionPolicy', [
'DisplayName' => 'Policy',
'AllowAppList' => [
['DisplayName' => 'Planner', 'AppId' => 'planner-app'],
['DisplayName' => 'Bookings', 'AppId' => 'bookings-app'],
],
], [
'DisplayName' => 'Policy',
'AllowAppList' => [
['DisplayName' => 'Bookings', 'AppId' => 'bookings-app'],
['DisplayName' => 'Planner', 'AppId' => 'planner-app'],
],
]);
$added = app(ExchangeTeamsCoverageComparator::class)->compare('meetingPolicy', [
'DisplayName' => 'Meeting',
'AllowCloudRecording' => null,
], [
'DisplayName' => 'Meeting',
'AllowCloudRecording' => true,
]);
expect($ordered['changed'])->toBeFalse()
->and($added['changed'])->toBeTrue()
->and(collect($added['changes'])->firstWhere('field', 'recording_transcription.allow_cloud_recording')['classification'])->toBe('added');
});
it('Spec422 records redacted and unsupported Exchange/Teams fields as non-material diagnostics', function (): void {
$result = app(ExchangeTeamsCoverageComparator::class)->compare(
'transportRule',
['DisplayName' => 'Rule', 'Enabled' => true],
['DisplayName' => 'Rule', 'Enabled' => true, 'clientSecret' => 'spec422-comparator-secret'],
);
expect($result['changed'])->toBeFalse()
->and(collect($result['changes'])->pluck('classification'))->toContain('redacted', 'unsupported_field')
->and(json_encode($result, JSON_THROW_ON_ERROR))->not->toContain('spec422-comparator-secret');
});