value); [$readonly] = createUserWithTenant(tenant: $tenant, role: WorkspaceRole::Readonly->value); $finding = Finding::factory()->for($tenant)->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'managed_environment_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $owner->getKey(), 'owner_user_id' => (int) $owner->getKey(), 'status' => FindingException::STATUS_PENDING, 'current_validity_state' => FindingException::VALIDITY_MISSING_SUPPORT, 'request_reason' => 'Boundary denial proof', 'requested_at' => now(), 'review_due_at' => now()->addDays(7), 'evidence_summary' => ['reference_count' => 0], ]); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); foreach (['approve', 'reject'] as $ability) { $response = Gate::forUser($readonly)->inspect($ability, $exception); expect($response->denied())->toBeTrue() ->and($response->status())->not->toBe(404); } }); it('denies same-workspace wrong-environment finding exceptions as not found', function (): void { $workspace = Workspace::factory()->create(); $allowedTenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); $deniedTenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); $user = User::factory()->create(); $owner = User::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $user->getKey(), 'role' => WorkspaceRole::Manager->value, ]); ManagedEnvironmentMembership::query()->create([ 'managed_environment_id' => (int) $allowedTenant->getKey(), 'user_id' => (int) $user->getKey(), 'role' => WorkspaceRole::Readonly->value, 'source' => 'manual', ]); app(CapabilityResolver::class)->clearCache(); app(ManagedEnvironmentAccessScopeResolver::class)->clearCache(); $finding = Finding::factory()->for($deniedTenant)->create([ 'workspace_id' => (int) $workspace->getKey(), ]); $exception = FindingException::query()->create([ 'workspace_id' => (int) $workspace->getKey(), 'managed_environment_id' => (int) $deniedTenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $owner->getKey(), 'owner_user_id' => (int) $owner->getKey(), 'status' => FindingException::STATUS_PENDING, 'current_validity_state' => FindingException::VALIDITY_MISSING_SUPPORT, 'request_reason' => 'Wrong environment boundary proof', 'requested_at' => now(), 'review_due_at' => now()->addDays(7), 'evidence_summary' => ['reference_count' => 0], ]); $allowedTenant->makeCurrent(); session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); app(WorkspaceContext::class)->rememberLastEnvironmentId((int) $workspace->getKey(), (int) $allowedTenant->getKey()); $response = Gate::forUser($user)->inspect('view', $exception); expect($response->denied())->toBeTrue() ->and($response->status())->toBe(404); });