browser()->timeout(15_000); it('smokes tenant detail with existing operation surfaces and canonical operations routes', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $report = VerificationReportWriter::build('provider.connection.check', [ [ 'key' => 'provider.connection.check', 'title' => 'Provider connection preflight', 'status' => 'fail', 'severity' => 'critical', 'blocking' => true, 'reason_code' => 'provider_connection_missing', 'message' => 'No provider connection configured.', 'evidence' => [], 'next_steps' => [], ], ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'tenant_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Blocked->value, 'context' => [ 'target_scope' => [ 'entra_tenant_id' => (string) $tenant->tenant_id, ], 'verification_report' => $report, ], ]); $this->actingAs($user)->withSession([ WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id, ]); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); $page = visit(TenantResource::getUrl('view', ['record' => $tenant->getRouteKey()], panel: 'admin')); $page ->assertNoJavaScriptErrors() ->assertSee((string) $tenant->name) ->assertSee('Recent operations') ->assertSee('Verification report') ->assertSee(OperationRunLinks::openCollectionLabel()) ->assertSee(OperationRunLinks::collectionScopeDescription()) ->assertSee(OperationRunLinks::openLabel()) ->assertSee(ViewTenant::verificationHeaderActionLabel()) ->assertDontSee('Start verification') ->click(OperationRunLinks::openCollectionLabel()) ->assertNoJavaScriptErrors() ->assertRoute('admin.operations.index'); visit(OperationRunLinks::tenantlessView($run)) ->assertNoJavaScriptErrors() ->assertRoute('admin.operations.view', ['run' => (int) $run->getKey()]) ->assertSee(OperationRunLinks::identifier((int) $run->getKey())); }); it('smokes tenant detail empty verification state without an inline inspect action', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user)->withSession([ WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id, ]); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); visit(TenantResource::getUrl('view', ['record' => $tenant->getRouteKey()], panel: 'admin')) ->assertNoJavaScriptErrors() ->assertSee('Verification report') ->assertSee('No verification operation has been started yet.') ->assertSee('Start verification') ->assertDontSee(OperationRunLinks::openLabel()); }); it('smokes onboarding verify step without a verification run', function (): void { $workspace = Workspace::factory()->create(); $tenant = Tenant::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'status' => Tenant::STATUS_ONBOARDING, ]); $user = User::factory()->create(['name' => 'Spec172 Browser Owner']); createUserWithTenant( tenant: $tenant, user: $user, role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false, ); $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'tenant_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => (string) $tenant->tenant_id, 'is_default' => true, 'status' => 'connected', ]); TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), 'tenant_id' => (int) $tenant->getKey(), 'entra_tenant_id' => (string) $tenant->tenant_id, 'current_step' => 'verify', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), ], 'started_by_user_id' => (int) $user->getKey(), 'updated_by_user_id' => (int) $user->getKey(), ]); $this->actingAs($user)->withSession([ WorkspaceContext::SESSION_KEY => (int) $workspace->getKey(), ]); session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); visit('/admin/onboarding') ->assertNoJavaScriptErrors() ->assertSee('Verify access') ->assertSee('Run a queued verification check (Operation).') ->assertSee('Start verification') ->assertDontSee('Refresh') ->assertDontSee(OperationRunLinks::openLabel()); }); it('smokes onboarding active verification state with refresh and current-run inspection', function (): void { $workspace = Workspace::factory()->create(); $tenant = Tenant::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'status' => Tenant::STATUS_ONBOARDING, ]); $user = User::factory()->create(['name' => 'Spec172 Active Browser Owner']); createUserWithTenant( tenant: $tenant, user: $user, role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false, ); $connection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'tenant_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => (string) $tenant->tenant_id, 'is_default' => true, 'status' => 'connected', ]); $run = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'tenant_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Running->value, 'outcome' => OperationRunOutcome::Pending->value, 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ 'entra_tenant_id' => (string) $tenant->tenant_id, 'entra_tenant_name' => (string) $tenant->name, ], ], ]); TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), 'tenant_id' => (int) $tenant->getKey(), 'entra_tenant_id' => (string) $tenant->tenant_id, 'current_step' => 'verify', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), ], 'started_by_user_id' => (int) $user->getKey(), 'updated_by_user_id' => (int) $user->getKey(), ]); $this->actingAs($user)->withSession([ WorkspaceContext::SESSION_KEY => (int) $workspace->getKey(), ]); session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); visit('/admin/onboarding') ->assertNoJavaScriptErrors() ->assertSee('Verify access') ->assertSee('Refresh') ->assertSee(OperationRunLinks::openLabel()) ->assertDontSee('Start verification'); }); it('smokes onboarding completed verification details with secondary links revealed only in technical details', function (): void { $workspace = Workspace::factory()->create(); $tenant = Tenant::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'tenant_id' => '17217217-2172-4172-9172-172172172172', 'external_id' => 'browser-spec172-complete', 'status' => Tenant::STATUS_ONBOARDING, ]); $user = User::factory()->create(['name' => 'Spec172 Completed Browser Owner']); createUserWithTenant( tenant: $tenant, user: $user, role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false, ); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), 'tenant_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => (string) $tenant->tenant_id, 'display_name' => 'Spec172 completed connection', 'is_default' => true, 'status' => 'connected', ]); $previousRun = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'tenant_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ 'entra_tenant_id' => (string) $tenant->tenant_id, ], 'verification_report' => VerificationReportWriter::build('provider.connection.check', []), ], ]); $report = VerificationReportWriter::build('provider.connection.check', [ [ 'key' => 'permissions.admin_consent', 'title' => 'Required application permissions', 'status' => 'fail', 'severity' => 'critical', 'blocking' => true, 'reason_code' => 'permission_denied', 'message' => 'Missing required Graph permissions.', 'evidence' => [], 'next_steps' => [], ], ]); $report['previous_report_id'] = (int) $previousRun->getKey(); $currentRun = OperationRun::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'tenant_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ 'entra_tenant_id' => (string) $tenant->tenant_id, 'entra_tenant_name' => (string) $tenant->name, ], 'verification_report' => $report, ], ]); TenantOnboardingSession::query()->create([ 'workspace_id' => (int) $workspace->getKey(), 'tenant_id' => (int) $tenant->getKey(), 'entra_tenant_id' => (string) $tenant->tenant_id, 'current_step' => 'verify', 'state' => [ 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $currentRun->getKey(), ], 'started_by_user_id' => (int) $user->getKey(), 'updated_by_user_id' => (int) $user->getKey(), ]); $this->actingAs($user)->withSession([ WorkspaceContext::SESSION_KEY => (int) $workspace->getKey(), ]); session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); $page = visit('/admin/onboarding'); $page ->assertNoJavaScriptErrors() ->assertSee('Verify access') ->assertSee('Technical details') ->assertSee(OperationRunLinks::openLabel()) ->assertDontSee('Open previous operation') ->assertDontSee(OperationRunLinks::advancedMonitoringLabel()) ->click('Technical details') ->waitForText('Verification technical details') ->assertNoJavaScriptErrors() ->assertSee('Open previous operation') ->assertSee(OperationRunLinks::advancedMonitoringLabel()); });