TenantAtlas/apps/platform/tests/Browser/Spec422ExchangeTeamsComparableRenderableOperatorSurfaceSmokeTest.php
ahmido 13d363c8b8 feat: complete spec 422 exchange teams comparable renderable pack (#489)
## Summary

This PR completes spec 422 exchange teams comparable renderable pack with comparable diffing, renderable summary builders, and comprehensive test updates.

## Commit
- 4c1e14c6 feat: complete spec 422 exchange teams comparable renderable pack

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #489
2026-06-30 04:20:13 +00:00

381 lines
16 KiB
PHP

<?php
declare(strict_types=1);
use App\Filament\Pages\TenantConfiguration\CoverageV2Readiness;
use App\Models\ManagedEnvironment;
use App\Models\OperationRun;
use App\Models\ProviderConnection;
use App\Models\TenantConfigurationResource;
use App\Models\TenantConfigurationResourceEvidence;
use App\Models\TenantConfigurationResourceType;
use App\Models\TenantConfigurationSupportedScope;
use App\Models\User;
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;
use App\Support\Workspaces\WorkspaceContext;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
pest()->browser()->timeout(60_000);
it('Spec422 smokes the Coverage v2 inspect surface for Exchange and Teams comparable renderable evidence', function (): void {
[$user, $environment] = spec422CoverageV2BrowserFixture();
spec422AuthenticateCoverageV2Browser($this, $user, $environment);
$page = visit(CoverageV2Readiness::getUrl(tenant: $environment, panel: 'admin'))
->resize(768, 1100)
->waitForText('Coverage v2 Readiness')
->waitForText('Spec422 Browser Meeting Policy')
->assertSee('Resource type registry')
->assertSee('Resource instances')
->assertSee('Transport rule')
->assertSee('Meeting policy')
->assertSee('Coverage level')
->assertSee('Renderable')
->assertSee('Internal only')
->assertDontSee('meetingPolicy:provider_external_id:spec422-browser')
->assertDontSee('transportRule:provider_external_id:spec422-browser')
->assertDontSee('Exchange covered')
->assertDontSee('Teams covered')
->assertDontSee('certified')
->assertDontSee('restore-ready')
->assertDontSee('customer-ready')
->assertDontSee('full Exchange coverage')
->assertDontSee('100% Teams')
->assertDontSee('spec422-browser-raw-secret')
->assertDontSee('spec422-browser-chat-secret')
->assertScript('typeof window.Livewire !== "undefined"', true)
->assertScript('(() => document.querySelectorAll("table tbody tr").length > 0)()', true)
->assertScript(<<<'JS'
(() => {
const row = Array.from(document.querySelectorAll('table tbody tr'))
.find((candidate) => candidate.textContent.includes('Spec422 Browser Meeting Policy'));
const resourceTypeCellText = row?.querySelectorAll('td')?.[1]?.innerText ?? '';
return resourceTypeCellText.includes('Meeting policy')
&& ! resourceTypeCellText.includes('meetingPolicy');
})()
JS, true)
->assertScript("(() => performance.getEntriesByType('resource').filter((entry) => /graph\\.microsoft\\.com|\\/tcm\\b|provider-remote/i.test(entry.name)).length)()", 0)
->assertScript("(() => Array.from(document.querySelectorAll('main button, main a')).map((element) => element.textContent.trim()).filter(Boolean).some((label) => /^(Capture|Restore|Certify|Export|Download)$/i.test(label)))()", false)
->assertNoJavaScriptErrors()
->assertNoConsoleLogs();
$page->script(<<<'JS'
(() => {
const rows = Array.from(document.querySelectorAll('table tbody tr'));
const row = rows.find((candidate) => candidate.textContent.includes('Spec422 Browser Meeting Policy'));
const inspect = Array.from(row?.querySelectorAll('button, a') ?? [])
.find((element) => element.textContent.includes('Spec422 Browser Meeting Policy'));
inspect?.click();
})()
JS);
$page
->waitForText('Coverage: Renderable')
->assertSee('Teams meeting policy')
->assertSee('Display name')
->assertSee('Spec422 Browser Meeting Policy')
->assertSee('Recording / transcription')
->assertSee('Allow Transcription: yes')
->assertSee('Content sharing')
->assertSee('Screen Sharing Mode: EntireScreen')
->assertSee('Compare summary')
->assertSee('Material changes detected')
->assertSee('Previous comparable evidence')
->assertSee('Recording Transcription Allow Transcription')
->assertSee('Redacted fields')
->assertSee('chatContent')
->assertSee('Evidence: Content backed')
->assertSee('Identity: Stable')
->assertSee('Claim: Internal only')
->assertSee('View technical details')
->assertDontSee('Source: TCM')
->assertDontSee('Evidence hash')
->assertDontSee('Source contract')
->assertDontSee('Source schema hash')
->assertDontSee('Operation #')
->assertDontSee('meetingPolicy:provider_external_id:spec422-browser')
->assertScript('(() => document.querySelector("details")?.open === false)()', true)
->assertScript(<<<'JS'
(() => {
const technicalDetails = document.querySelector('details')?.textContent ?? '';
return technicalDetails.includes('Source: TCM')
&& technicalDetails.includes('Evidence hash')
&& technicalDetails.includes('Source contract')
&& technicalDetails.includes('Source schema hash')
&& technicalDetails.includes('Operation #');
})()
JS, true)
->assertDontSee('Exchange covered')
->assertDontSee('Teams covered')
->assertDontSee('certified')
->assertDontSee('restore-ready')
->assertDontSee('customer-ready')
->assertDontSee('full Exchange coverage')
->assertDontSee('100% Teams')
->assertDontSee('spec422-browser-raw-secret')
->assertDontSee('spec422-browser-chat-secret')
->assertNoJavaScriptErrors()
->assertNoConsoleLogs()
->screenshot(true, 'spec422-exchange-teams-comparable-renderable-operator-surface');
});
/**
* @return array{0: User, 1: ManagedEnvironment}
*/
function spec422CoverageV2BrowserFixture(): array
{
app(ResourceTypeRegistry::class)->syncDefaults();
$environment = ManagedEnvironment::factory()->active()->create([
'name' => 'Spec422 Browser Environment',
'external_id' => 'spec422-browser-environment',
]);
[$user, $environment] = createUserWithTenant(
tenant: $environment,
role: 'owner',
workspaceRole: 'owner',
clearCapabilityCaches: true,
);
$connection = ProviderConnection::factory()->create([
'workspace_id' => (int) $environment->workspace_id,
'managed_environment_id' => (int) $environment->getKey(),
'display_name' => 'Spec422 Browser Microsoft provider',
]);
TenantConfigurationSupportedScope::factory()->create([
'scope_key' => 'spec422_browser_internal_exchange_teams_scope',
'display_name' => 'Spec422 Browser internal Exchange Teams scope',
'minimum_coverage_level' => CoverageLevel::ContentBacked->value,
'included_resource_types' => ['transportRule', 'meetingPolicy'],
'allow_graph_fallback' => false,
'allow_beta' => false,
'customer_claims_allowed' => false,
]);
spec422BrowserEvidenceResource(
environment: $environment,
user: $user,
connection: $connection,
canonicalType: 'transportRule',
displayName: 'Spec422 Browser Transport Rule',
previousPayload: [
'DisplayName' => 'Spec422 Browser Transport Rule',
'Enabled' => true,
'Actions' => ['RedirectMessageTo' => ['old-security@example.com']],
],
latestPayload: [
'DisplayName' => 'Spec422 Browser Transport Rule',
'Enabled' => true,
'Actions' => ['RedirectMessageTo' => ['security@example.com']],
],
hashSeed: 'a',
);
spec422BrowserEvidenceResource(
environment: $environment,
user: $user,
connection: $connection,
canonicalType: 'meetingPolicy',
displayName: 'Spec422 Browser Meeting Policy',
previousPayload: [
'DisplayName' => 'Spec422 Browser Meeting Policy',
'AllowTranscription' => false,
'ScreenSharingMode' => 'SingleApplication',
],
latestPayload: [
'DisplayName' => 'Spec422 Browser Meeting Policy',
'AllowTranscription' => true,
'ScreenSharingMode' => 'EntireScreen',
'chatContent' => 'spec422-browser-chat-secret',
],
hashSeed: 'b',
);
return [$user, $environment->refresh()];
}
function spec422BrowserEvidenceResource(
ManagedEnvironment $environment,
User $user,
ProviderConnection $connection,
string $canonicalType,
string $displayName,
array $previousPayload,
array $latestPayload,
string $hashSeed,
): TenantConfigurationResource {
$resourceType = TenantConfigurationResourceType::query()
->where('canonical_type', $canonicalType)
->where('source_class', SourceClass::Tcm->value)
->firstOrFail();
$previousRun = spec422BrowserRun($environment, $user, $connection, $canonicalType, minutesAgo: 5);
$run = spec422BrowserRun($environment, $user, $connection, $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-browser',
'canonical_key_kind' => CanonicalKeyKind::ProviderExternalId->value,
'source_resource_id' => 'spec422-browser',
'source_display_name' => $displayName,
'source_class' => SourceClass::Tcm->value,
'source_metadata' => [
'source_contract_key' => 'spec422.synthetic.'.$canonicalType,
'source_endpoint' => '/spec422/synthetic/'.$canonicalType,
'source_version' => 'v1.0',
'registry_source_class' => SourceClass::Tcm->value,
'registry_support_state' => 'out_of_scope',
],
'identity_strategy' => 'provider.external.id.v1',
'source_identity' => [
'primary_field' => 'id',
'primary_value' => 'spec422-browser',
],
'identity_diagnostics' => [
'reason_code' => 'provider_external_id',
],
'identity_evaluated_at' => now(),
'latest_evidence_state' => EvidenceState::ContentBacked->value,
'latest_identity_state' => IdentityState::Stable->value,
'latest_claim_state' => ClaimState::InternalOnly->value,
'latest_captured_at' => now(),
]);
TenantConfigurationResourceEvidence::factory()->create([
'resource_id' => (int) $resource->getKey(),
'workspace_id' => (int) $environment->workspace_id,
'managed_environment_id' => (int) $environment->getKey(),
'provider_connection_id' => (int) $connection->getKey(),
'resource_type_id' => (int) $resourceType->getKey(),
'operation_run_id' => (int) $previousRun->getKey(),
'source_contract_key' => 'spec422.synthetic.'.$canonicalType,
'source_endpoint' => '/spec422/synthetic/'.$canonicalType,
'source_version' => 'v1.0',
'source_schema_hash' => 'spec422-browser-previous-schema-hash',
'source_metadata' => [
'registry_source_class' => SourceClass::Tcm->value,
'registry_support_state' => 'out_of_scope',
],
'raw_payload' => ['id' => 'spec422-browser'],
'normalized_payload' => $previousPayload,
'payload_hash' => str_repeat($hashSeed, 64),
'permission_context' => ['scopes_granted' => []],
'evidence_state' => EvidenceState::ContentBacked->value,
'coverage_level' => CoverageLevel::Comparable->value,
'capture_outcome' => CaptureOutcome::Captured->value,
'captured_at' => now()->subMinutes(5),
]);
$evidence = TenantConfigurationResourceEvidence::factory()->create([
'resource_id' => (int) $resource->getKey(),
'workspace_id' => (int) $environment->workspace_id,
'managed_environment_id' => (int) $environment->getKey(),
'provider_connection_id' => (int) $connection->getKey(),
'resource_type_id' => (int) $resourceType->getKey(),
'operation_run_id' => (int) $run->getKey(),
'source_contract_key' => 'spec422.synthetic.'.$canonicalType,
'source_endpoint' => '/spec422/synthetic/'.$canonicalType,
'source_version' => 'v1.0',
'source_schema_hash' => 'spec422-browser-schema-hash',
'source_metadata' => [
'registry_source_class' => SourceClass::Tcm->value,
'registry_support_state' => 'out_of_scope',
],
'raw_payload' => ['id' => 'spec422-browser', 'secret' => 'spec422-browser-raw-secret'],
'normalized_payload' => $latestPayload,
'payload_hash' => str_repeat(strtoupper($hashSeed), 64),
'permission_context' => ['scopes_granted' => []],
'evidence_state' => EvidenceState::ContentBacked->value,
'coverage_level' => CoverageLevel::Renderable->value,
'capture_outcome' => CaptureOutcome::Captured->value,
'captured_at' => now(),
]);
$resource->forceFill([
'latest_evidence_id' => (int) $evidence->getKey(),
'latest_payload_hash' => (string) $evidence->payload_hash,
])->save();
return $resource->refresh();
}
function spec422BrowserRun(
ManagedEnvironment $environment,
User $user,
ProviderConnection $connection,
string $canonicalType,
int $minutesAgo = 0,
): OperationRun {
$timestamp = $minutesAgo > 0 ? now()->subMinutes($minutesAgo) : now();
return OperationRun::factory()->create([
'workspace_id' => (int) $environment->workspace_id,
'managed_environment_id' => (int) $environment->getKey(),
'user_id' => (int) $user->getKey(),
'initiator_name' => (string) $user->name,
'type' => OperationRunType::TenantConfigurationCapture->value,
'status' => OperationRunStatus::Completed->value,
'outcome' => OperationRunOutcome::Succeeded->value,
'summary_counts' => [
'total' => 1,
'processed' => 1,
'succeeded' => 1,
'skipped' => 0,
'failed' => 0,
'errors_recorded' => 0,
],
'context' => [
'requested_resource_types' => [$canonicalType],
'outcomes' => [
['canonical_type' => $canonicalType, 'outcome' => CaptureOutcome::Captured->value],
],
'target_scope' => [
'workspace_id' => (int) $environment->workspace_id,
'managed_environment_id' => (int) $environment->getKey(),
'provider_connection_id' => (int) $connection->getKey(),
],
],
'started_at' => $timestamp,
'completed_at' => $timestamp,
]);
}
function spec422AuthenticateCoverageV2Browser(
mixed $test,
User $user,
ManagedEnvironment $environment,
): void {
$workspaceId = (int) $environment->workspace_id;
$test->actingAs($user)->withSession([
WorkspaceContext::SESSION_KEY => $workspaceId,
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
(string) $workspaceId => (int) $environment->getKey(),
],
]);
session()->put(WorkspaceContext::SESSION_KEY, $workspaceId);
session()->put(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY, [
(string) $workspaceId => (int) $environment->getKey(),
]);
}