Files
steipete--codexbar/Tests/CodexBarTests/CodexDashboardAuthorityTests.swift
2026-07-13 12:22:33 +08:00

476 lines
21 KiB
Swift

import CodexBarCore
import Testing
struct CodexDashboardAuthorityTests {
@Test
func `email only wrong email returns fail closed`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .emailOnly(normalizedEmail: "owner@example.com"),
expectedScopedEmail: nil,
trustedCurrentUsageEmail: nil,
dashboardSignedInEmail: "other@example.com",
knownOwners: [
CodexDashboardKnownOwnerCandidate(
identity: .emailOnly(normalizedEmail: "owner@example.com"),
normalizedEmail: "owner@example.com"),
]),
routing: CodexDashboardRoutingHints(
targetEmail: "owner@example.com",
lastKnownDashboardRoutingEmail: nil))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .failClosed)
#expect(decision.reason == .wrongEmail(expected: "owner@example.com", actual: "other@example.com"))
}
@Test
func `provider account wrong email returns fail closed`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .providerAccount(id: "acct-owner"),
expectedScopedEmail: "owner@example.com",
trustedCurrentUsageEmail: nil,
dashboardSignedInEmail: "other@example.com",
knownOwners: [
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-owner"),
normalizedEmail: "owner@example.com"),
]),
routing: CodexDashboardRoutingHints(
targetEmail: "owner@example.com",
lastKnownDashboardRoutingEmail: "stale@example.com"))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .failClosed)
#expect(decision.reason == .wrongEmail(expected: "owner@example.com", actual: "other@example.com"))
}
@Test
func `email only same email ambiguity returns display only`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .emailOnly(normalizedEmail: "shared@example.com"),
expectedScopedEmail: nil,
trustedCurrentUsageEmail: nil,
dashboardSignedInEmail: "shared@example.com",
knownOwners: [
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-alpha"),
normalizedEmail: "shared@example.com"),
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-beta"),
normalizedEmail: "shared@example.com"),
]),
routing: CodexDashboardRoutingHints(
targetEmail: "shared@example.com",
lastKnownDashboardRoutingEmail: "shared@example.com"))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .displayOnly)
#expect(decision.reason == .sameEmailAmbiguity(email: "shared@example.com"))
}
@Test
func `provider account exact owner match returns attach`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .providerAccount(id: "acct-owner"),
expectedScopedEmail: "OWNER@example.com",
trustedCurrentUsageEmail: nil,
dashboardSignedInEmail: "owner@example.com",
knownOwners: [
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-owner"),
normalizedEmail: "OWNER@example.com"),
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-other"),
normalizedEmail: "other@example.com"),
]),
routing: CodexDashboardRoutingHints(
targetEmail: "route@example.com",
lastKnownDashboardRoutingEmail: "stale@example.com"))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .attach)
#expect(decision.reason == .exactProviderAccountMatch)
}
@Test
func `provider account exact owner ignores duplicate profile isolation`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .providerAccount(id: "acct-owner"),
expectedScopedEmail: "owner@example.com",
trustedCurrentUsageEmail: nil,
dashboardSignedInEmail: "owner@example.com",
knownOwners: [
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-owner"),
normalizedEmail: "owner@example.com",
sourceIsolationIdentifier: "profile-a"),
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-owner"),
normalizedEmail: "owner@example.com",
sourceIsolationIdentifier: "profile-b"),
]),
routing: CodexDashboardRoutingHints(
targetEmail: "owner@example.com",
lastKnownDashboardRoutingEmail: nil))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .attach)
#expect(decision.reason == .exactProviderAccountMatch)
}
@Test
func `email only owners retain profile isolation ambiguity`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .emailOnly(normalizedEmail: "shared@example.com"),
expectedScopedEmail: "shared@example.com",
trustedCurrentUsageEmail: nil,
dashboardSignedInEmail: "shared@example.com",
knownOwners: [
CodexDashboardKnownOwnerCandidate(
identity: .emailOnly(normalizedEmail: "shared@example.com"),
normalizedEmail: "shared@example.com",
sourceIsolationIdentifier: "profile-a"),
CodexDashboardKnownOwnerCandidate(
identity: .emailOnly(normalizedEmail: "shared@example.com"),
normalizedEmail: "shared@example.com",
sourceIsolationIdentifier: "profile-b"),
]),
routing: CodexDashboardRoutingHints(
targetEmail: "shared@example.com",
lastKnownDashboardRoutingEmail: nil))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .displayOnly)
#expect(decision.reason == .sameEmailAmbiguity(email: "shared@example.com"))
}
@Test
func `provider account exact owner stays display only when email has another owner`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .providerAccount(id: "acct-current"),
expectedScopedEmail: "shared@example.com",
trustedCurrentUsageEmail: nil,
dashboardSignedInEmail: "shared@example.com",
knownOwners: [
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-current"),
normalizedEmail: "shared@example.com"),
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-other"),
normalizedEmail: "shared@example.com"),
]),
routing: CodexDashboardRoutingHints(
targetEmail: "shared@example.com",
lastKnownDashboardRoutingEmail: nil))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .displayOnly)
#expect(decision.reason == .sameEmailAmbiguity(email: "shared@example.com"))
}
@Test
func `provider account same email ambiguity without exact match returns display only`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .providerAccount(id: "acct-current"),
expectedScopedEmail: "shared@example.com",
trustedCurrentUsageEmail: nil,
dashboardSignedInEmail: "shared@example.com",
knownOwners: [
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-alpha"),
normalizedEmail: "shared@example.com"),
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-beta"),
normalizedEmail: "shared@example.com"),
]),
routing: CodexDashboardRoutingHints(
targetEmail: "shared@example.com",
lastKnownDashboardRoutingEmail: nil))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .displayOnly)
#expect(decision.reason == .sameEmailAmbiguity(email: "shared@example.com"))
}
@Test
func `provider account nil scoped email with dashboard collision returns fail closed`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .providerAccount(id: "acct-current"),
expectedScopedEmail: nil,
trustedCurrentUsageEmail: "shared@example.com",
dashboardSignedInEmail: "shared@example.com",
knownOwners: [
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-alpha"),
normalizedEmail: "shared@example.com"),
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-beta"),
normalizedEmail: "shared@example.com"),
]),
routing: CodexDashboardRoutingHints(
targetEmail: "shared@example.com",
lastKnownDashboardRoutingEmail: nil))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .failClosed)
#expect(decision.reason == .providerAccountMissingScopedEmail)
}
@Test
func `unresolved trusted continuity without competing owner returns attach`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .unresolved,
expectedScopedEmail: nil,
trustedCurrentUsageEmail: "owner@example.com",
dashboardSignedInEmail: "owner@example.com",
knownOwners: [
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-owner"),
normalizedEmail: "owner@example.com"),
]),
routing: CodexDashboardRoutingHints(
targetEmail: "owner@example.com",
lastKnownDashboardRoutingEmail: "route@example.com"))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .attach)
#expect(decision.reason == .trustedContinuityNoCompetingOwner)
}
@Test
func `unresolved trusted continuity with competing owner returns display only`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .unresolved,
expectedScopedEmail: nil,
trustedCurrentUsageEmail: "shared@example.com",
dashboardSignedInEmail: "shared@example.com",
knownOwners: [
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-alpha"),
normalizedEmail: "shared@example.com"),
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-beta"),
normalizedEmail: "shared@example.com"),
]),
routing: CodexDashboardRoutingHints(
targetEmail: "shared@example.com",
lastKnownDashboardRoutingEmail: "route@example.com"))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .displayOnly)
#expect(decision.reason == .sameEmailAmbiguity(email: "shared@example.com"))
}
@Test
func `unresolved without trusted evidence returns fail closed`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .unresolved,
expectedScopedEmail: nil,
trustedCurrentUsageEmail: nil,
dashboardSignedInEmail: "owner@example.com",
knownOwners: []),
routing: CodexDashboardRoutingHints(
targetEmail: "owner@example.com",
lastKnownDashboardRoutingEmail: nil))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .failClosed)
#expect(decision.reason == .unresolvedWithoutTrustedEvidence)
}
@Test
func `missing dashboard signed in email returns fail closed`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .providerAccount(id: "acct-owner"),
expectedScopedEmail: "owner@example.com",
trustedCurrentUsageEmail: "owner@example.com",
dashboardSignedInEmail: nil,
knownOwners: [
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-owner"),
normalizedEmail: "owner@example.com"),
]),
routing: CodexDashboardRoutingHints(
targetEmail: "owner@example.com",
lastKnownDashboardRoutingEmail: nil))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .failClosed)
#expect(decision.reason == .missingDashboardSignedInEmail)
}
@Test
func `live web attach exposes usage credits guard and history effects`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .providerAccount(id: "acct-owner"),
expectedScopedEmail: "owner@example.com",
trustedCurrentUsageEmail: nil,
dashboardSignedInEmail: "owner@example.com",
knownOwners: [
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-owner"),
normalizedEmail: "owner@example.com"),
]),
routing: CodexDashboardRoutingHints(
targetEmail: nil,
lastKnownDashboardRoutingEmail: nil))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .attach)
#expect(decision.allowedEffects == Set([
.usageBackfill,
.creditsAttachment,
.refreshGuardSeed,
.historicalBackfill,
]))
#expect(decision.cleanup.isEmpty)
}
@Test
func `cached dashboard attach exposes cached reuse only`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .cachedDashboard,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .emailOnly(normalizedEmail: "owner@example.com"),
expectedScopedEmail: nil,
trustedCurrentUsageEmail: nil,
dashboardSignedInEmail: "owner@example.com",
knownOwners: [
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-owner"),
normalizedEmail: "owner@example.com"),
]),
routing: CodexDashboardRoutingHints(
targetEmail: "owner@example.com",
lastKnownDashboardRoutingEmail: nil))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .attach)
#expect(decision.allowedEffects == Set([.cachedDashboardReuse]))
#expect(decision.cleanup.isEmpty)
}
@Test
func `display only emits full cleanup set`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .emailOnly(normalizedEmail: "shared@example.com"),
expectedScopedEmail: nil,
trustedCurrentUsageEmail: nil,
dashboardSignedInEmail: "shared@example.com",
knownOwners: [
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-alpha"),
normalizedEmail: "shared@example.com"),
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-beta"),
normalizedEmail: "shared@example.com"),
]),
routing: CodexDashboardRoutingHints(
targetEmail: nil,
lastKnownDashboardRoutingEmail: nil))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .displayOnly)
#expect(decision.allowedEffects.isEmpty)
#expect(decision.cleanup == Set(CodexDashboardCleanup.allCases))
}
@Test
func `fail closed emits full cleanup set`() {
let input = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: CodexDashboardOwnershipProofContext(
currentIdentity: .unresolved,
expectedScopedEmail: nil,
trustedCurrentUsageEmail: nil,
dashboardSignedInEmail: "owner@example.com",
knownOwners: []),
routing: CodexDashboardRoutingHints(
targetEmail: nil,
lastKnownDashboardRoutingEmail: nil))
let decision = CodexDashboardAuthority.evaluate(input)
#expect(decision.disposition == .failClosed)
#expect(decision.allowedEffects.isEmpty)
#expect(decision.cleanup == Set(CodexDashboardCleanup.allCases))
}
@Test
func `routing hints do not change evaluation result`() {
let proof = CodexDashboardOwnershipProofContext(
currentIdentity: .providerAccount(id: "acct-owner"),
expectedScopedEmail: "owner@example.com",
trustedCurrentUsageEmail: nil,
dashboardSignedInEmail: "owner@example.com",
knownOwners: [
CodexDashboardKnownOwnerCandidate(
identity: .providerAccount(id: "acct-owner"),
normalizedEmail: "owner@example.com"),
])
let baseInput = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: proof,
routing: CodexDashboardRoutingHints(
targetEmail: "owner@example.com",
lastKnownDashboardRoutingEmail: "owner@example.com"))
let conflictingRoutingInput = CodexDashboardAuthorityInput(
sourceKind: .liveWeb,
proof: proof,
routing: CodexDashboardRoutingHints(
targetEmail: "wrong@example.com",
lastKnownDashboardRoutingEmail: "stale@example.com"))
let baseDecision = CodexDashboardAuthority.evaluate(baseInput)
let conflictingDecision = CodexDashboardAuthority.evaluate(conflictingRoutingInput)
#expect(baseDecision == conflictingDecision)
}
}