import CodexBarCoreimport Foundationimport Testing@testable import CodexBar extension CodexAccountScopedRefreshTests { @Test func `dashboard refresh accepted via unresolved routing fallback during account scoped refresh`() async throws { let settings = self.makeSettingsStore( suite: "CodexAccountScopedRefreshTests-dashboard-unresolved-routing-fallback") let isolatedHome = FileManager.default.temporaryDirectory .appendingPathComponent("codex-dashboard-unresolved-routing-\(UUID().uuidString)", isDirectory: true) try? FileManager.default.createDirectory(at: isolatedHome, withIntermediateDirectories: true) let codexMetadata = try #require(ProviderDescriptorRegistry.metadata[.codex]) settings.refreshFrequency = .manual settings.setProviderEnabled(provider: .codex, metadata: codexMetadata, enabled: true) settings.openAIWebAccessEnabled = true settings.codexCookieSource = .auto settings.codexActiveSource = .liveSystem settings._test_liveSystemCodexAccount = nil settings._test_codexReconciliationEnvironment = ["CODEX_HOME": isolatedHome.path] defer { settings._test_codexReconciliationEnvironment = nil try? FileManager.default.removeItem(at: isolatedHome) } let store = self.makeUsageStore(settings: settings) store.lastKnownLiveSystemCodexEmail = nil self.installImmediateCodexProvider( on: store, snapshot: self.codexSnapshot(email: "work@company.com", usedPercent: 12)) store._test_codexCreditsLoaderOverride = { self.credits(remaining: 55) } defer { store._test_codexCreditsLoaderOverride = nil } var observedTargetEmail: String? store._test_openAIDashboardLoaderOverride = { accountEmail, _, _, _ in observedTargetEmail = accountEmail #expect(store.currentCodexOpenAIWebRefreshGuard().source == .liveSystem) #expect(store.currentCodexOpenAIWebRefreshGuard().identity == .unresolved) return self.dashboard(email: "work@company.com", creditsRemaining: 33, usedPercent: 12) } defer { store._test_openAIDashboardLoaderOverride = nil } await store.refreshCodexAccountScopedState(allowDisabled: true) #expect(observedTargetEmail == "work@company.com") #expect(store.currentCodexOpenAIWebRefreshGuard().identity == .unresolved) #expect(store.openAIDashboard?.signedInEmail == "work@company.com") #expect(store.lastOpenAIDashboardSnapshot?.signedInEmail == "work@company.com") #expect(store.openAIDashboardRequiresLogin == false) #expect(store.lastOpenAIDashboardError == nil) #expect(store.snapshots[.codex]?.accountEmail(for: .codex) == "work@company.com") #expect(store.lastSourceLabels[.codex] == "test-codex") #expect(store.credits?.remaining == 55) #expect(store.lastCreditsSource == .api) } @Test func `dashboard fail closed clears dashboard derived usage credits cache and visible dashboard`() async throws { OpenAIDashboardCacheStore.clear() defer { OpenAIDashboardCacheStore.clear() } let settings = self.makeSettingsStore(suite: "CodexAccountScopedRefreshTests-dashboard-fail-closed-cleanup") let managedHome = FileManager.default.temporaryDirectory .appendingPathComponent(UUID().uuidString, isDirectory: true) defer { try? FileManager.default.removeItem(at: managedHome) } try Self.writeCodexAuthFile( homeURL: managedHome, email: "managed@example.com", plan: "pro", accountId: "acct-managed") let managedAccount = ManagedCodexAccount( id: UUID(), email: "managed@example.com", managedHomePath: managedHome.path, createdAt: 1, updatedAt: 1, lastAuthenticatedAt: 1) let managedStoreURL = try self.makeManagedAccountStoreURL(accounts: [managedAccount]) defer { settings._test_managedCodexAccountStoreURL = nil settings._test_activeManagedCodexAccount = nil try? FileManager.default.removeItem(at: managedStoreURL) } settings.refreshFrequency = .manual settings.codexCookieSource = .auto settings._test_managedCodexAccountStoreURL = managedStoreURL settings._test_activeManagedCodexAccount = managedAccount settings.codexActiveSource = .managedAccount(id: managedAccount.id) let store = self.makeUsageStore(settings: settings) store._setSnapshotForTesting( self.codexSnapshot(email: "managed@example.com", usedPercent: 20), provider: .codex) store.lastSourceLabels[.codex] = "openai-web" let staleCredits = self.credits(remaining: 20) store.credits = staleCredits store.lastCreditsSnapshot = staleCredits store.lastCreditsSnapshotAccountKey = "managed@example.com" store.lastCreditsSource = .dashboardWeb store.openAIDashboard = self.dashboard(email: "managed@example.com", creditsRemaining: 20, usedPercent: 20) store.lastOpenAIDashboardSnapshot = store.openAIDashboard OpenAIDashboardCacheStore.save(OpenAIDashboardCache( accountEmail: "managed@example.com", snapshot: self.dashboard(email: "managed@example.com", creditsRemaining: 20, usedPercent: 20))) await store.applyOpenAIDashboard( self.dashboard(email: "other@example.com", creditsRemaining: 9, usedPercent: 35), targetEmail: "managed@example.com") #expect(store.openAIDashboard == nil) #expect(store.lastOpenAIDashboardSnapshot == nil) #expect(store.snapshots[.codex] == nil) #expect(store.credits == nil) #expect(store.lastCreditsSource == .none) #expect(OpenAIDashboardCacheStore.load() == nil) #expect(store.openAIDashboardRequiresLogin == true) #expect(store.lastOpenAIDashboardError?.contains("OpenAI dashboard signed in as other@example.com") == true) } @Test func `dashboard fail closed cleanup applies after same account managed token rotation`() async throws { OpenAIDashboardCacheStore.clear() defer { OpenAIDashboardCacheStore.clear() } let settings = self.makeSettingsStore( suite: "CodexAccountScopedRefreshTests-dashboard-fail-closed-token-rotation-cleanup") let managedHome = FileManager.default.temporaryDirectory .appendingPathComponent(UUID().uuidString, isDirectory: true) defer { try? FileManager.default.removeItem(at: managedHome) } try Self.writeCodexAuthFile( homeURL: managedHome, email: "managed@example.com", plan: "pro", accountId: "acct-managed") let oldFingerprint = try #require(CodexAuthFingerprint.fingerprint(homePath: managedHome.path)) let managedAccount = ManagedCodexAccount( id: UUID(), email: "managed@example.com", providerAccountID: "acct-managed", workspaceLabel: "Managed", workspaceAccountID: "acct-managed", authFingerprint: oldFingerprint, managedHomePath: managedHome.path, createdAt: 1, updatedAt: 1, lastAuthenticatedAt: 1) let managedStoreURL = try self.makeManagedAccountStoreURL(accounts: [managedAccount]) defer { settings._test_managedCodexAccountStoreURL = nil settings._test_activeManagedCodexAccount = nil try? FileManager.default.removeItem(at: managedStoreURL) } settings.refreshFrequency = .manual settings.codexCookieSource = .auto settings._test_managedCodexAccountStoreURL = managedStoreURL settings._test_activeManagedCodexAccount = managedAccount settings.codexActiveSource = .managedAccount(id: managedAccount.id) let store = self.makeUsageStore(settings: settings) let expectedGuard = store.freshCodexOpenAIWebRefreshGuard() #expect(expectedGuard.authFingerprint == oldFingerprint) store._setSnapshotForTesting( self.codexSnapshot(email: "managed@example.com", usedPercent: 20), provider: .codex) store.lastSourceLabels[.codex] = "openai-web" let staleCredits = self.credits(remaining: 20) store.credits = staleCredits store.lastCreditsSnapshot = staleCredits store.lastCreditsSnapshotAccountKey = "managed@example.com" store.lastCreditsSource = .dashboardWeb store.openAIDashboard = self.dashboard(email: "managed@example.com", creditsRemaining: 20, usedPercent: 20) store.lastOpenAIDashboardSnapshot = store.openAIDashboard OpenAIDashboardCacheStore.save(OpenAIDashboardCache( accountEmail: "managed@example.com", snapshot: self.dashboard(email: "managed@example.com", creditsRemaining: 20, usedPercent: 20))) try Self.writeCodexAuthFile( homeURL: managedHome, email: "managed@example.com", plan: "team", accountId: "acct-managed") let newFingerprint = try #require(CodexAuthFingerprint.fingerprint(homePath: managedHome.path)) #expect(newFingerprint != oldFingerprint) let currentGuard = store.freshCodexOpenAIWebRefreshGuard() #expect(currentGuard.identity == expectedGuard.identity) #expect(currentGuard.accountKey == expectedGuard.accountKey) #expect(currentGuard.authFingerprint == newFingerprint) await store.applyOpenAIDashboard( self.dashboard(email: "other@example.com", creditsRemaining: 9, usedPercent: 35), targetEmail: "managed@example.com", expectedGuard: expectedGuard) #expect(store.openAIDashboard == nil) #expect(store.lastOpenAIDashboardSnapshot == nil) #expect(store.snapshots[.codex] == nil) #expect(store.credits == nil) #expect(store.lastCreditsSource == .none) #expect(OpenAIDashboardCacheStore.load() == nil) #expect(store.openAIDashboardRequiresLogin == true) #expect(store.lastOpenAIDashboardError?.contains("OpenAI dashboard signed in as other@example.com") == true) } @Test func `dashboard fail closed cleanup applies after same live account email changes during token rotation`() async { OpenAIDashboardCacheStore.clear() defer { OpenAIDashboardCacheStore.clear() } let settings = self.makeSettingsStore( suite: "CodexAccountScopedRefreshTests-dashboard-fail-closed-live-email-rotation-cleanup") settings.refreshFrequency = .manual settings.codexCookieSource = .auto settings.codexActiveSource = .liveSystem settings._test_liveSystemCodexAccount = ObservedSystemCodexAccount( email: "alpha@example.com", authFingerprint: "old-token-material", codexHomePath: "/Users/test/.codex", observedAt: Date(), identity: .providerAccount(id: "acct-alpha")) defer { settings._test_liveSystemCodexAccount = nil } let store = self.makeUsageStore(settings: settings) let expectedGuard = store.freshCodexOpenAIWebRefreshGuard() #expect(expectedGuard.accountKey == "alpha@example.com") #expect(expectedGuard.authFingerprint == "old-token-material") store._setSnapshotForTesting( self.codexSnapshot(email: "alpha@example.com", usedPercent: 20), provider: .codex) store.lastSourceLabels[.codex] = "openai-web" let staleCredits = self.credits(remaining: 20) store.credits = staleCredits store.lastCreditsSnapshot = staleCredits store.lastCreditsSnapshotAccountKey = "alpha@example.com" store.lastCreditsSource = .dashboardWeb store.openAIDashboard = self.dashboard(email: "alpha@example.com", creditsRemaining: 20, usedPercent: 20) store.lastOpenAIDashboardSnapshot = store.openAIDashboard OpenAIDashboardCacheStore.save(OpenAIDashboardCache( accountEmail: "alpha@example.com", snapshot: self.dashboard(email: "alpha@example.com", creditsRemaining: 20, usedPercent: 20))) settings._test_liveSystemCodexAccount = ObservedSystemCodexAccount( email: "beta@example.com", authFingerprint: "new-token-material", codexHomePath: "/Users/test/.codex", observedAt: Date(), identity: .providerAccount(id: "acct-alpha")) let currentGuard = store.freshCodexOpenAIWebRefreshGuard() #expect(currentGuard.identity == expectedGuard.identity) #expect(currentGuard.accountKey == "beta@example.com") #expect(currentGuard.authFingerprint == "new-token-material") await store.applyOpenAIDashboard( self.dashboard(email: "alpha@example.com", creditsRemaining: 9, usedPercent: 35), targetEmail: "alpha@example.com", expectedGuard: expectedGuard) #expect(store.openAIDashboard == nil) #expect(store.lastOpenAIDashboardSnapshot == nil) #expect(store.snapshots[.codex] == nil) #expect(store.credits == nil) #expect(store.lastCreditsSource == .none) #expect(OpenAIDashboardCacheStore.load() == nil) #expect(store.openAIDashboardRequiresLogin == true) #expect(store.lastOpenAIDashboardError?.contains("OpenAI dashboard signed in as alpha@example.com") == true) }}
import CodexBarCore
import Foundation
import Testing
@testable import CodexBar
extension CodexAccountScopedRefreshTests {
@Test
func `dashboard refresh accepted via unresolved routing fallback during account scoped refresh`() async throws {
let settings = self.makeSettingsStore(
suite: "CodexAccountScopedRefreshTests-dashboard-unresolved-routing-fallback")
let isolatedHome = FileManager.default.temporaryDirectory
.appendingPathComponent("codex-dashboard-unresolved-routing-\(UUID().uuidString)", isDirectory: true)
try? FileManager.default.createDirectory(at: isolatedHome, withIntermediateDirectories: true)
let codexMetadata = try #require(ProviderDescriptorRegistry.metadata[.codex])
settings.refreshFrequency = .manual
settings.setProviderEnabled(provider: .codex, metadata: codexMetadata, enabled: true)
settings.openAIWebAccessEnabled = true
settings.codexCookieSource = .auto
settings.codexActiveSource = .liveSystem
settings._test_liveSystemCodexAccount = nil
settings._test_codexReconciliationEnvironment = ["CODEX_HOME": isolatedHome.path]
defer {
settings._test_codexReconciliationEnvironment = nil
try? FileManager.default.removeItem(at: isolatedHome)
}
let store = self.makeUsageStore(settings: settings)
store.lastKnownLiveSystemCodexEmail = nil
self.installImmediateCodexProvider(
on: store,
snapshot: self.codexSnapshot(email: "work@company.com", usedPercent: 12))
store._test_codexCreditsLoaderOverride = { self.credits(remaining: 55) }
defer { store._test_codexCreditsLoaderOverride = nil }
var observedTargetEmail: String?
store._test_openAIDashboardLoaderOverride = { accountEmail, _, _, _ in
observedTargetEmail = accountEmail
#expect(store.currentCodexOpenAIWebRefreshGuard().source == .liveSystem)
#expect(store.currentCodexOpenAIWebRefreshGuard().identity == .unresolved)
return self.dashboard(email: "work@company.com", creditsRemaining: 33, usedPercent: 12)
}
defer { store._test_openAIDashboardLoaderOverride = nil }
await store.refreshCodexAccountScopedState(allowDisabled: true)
#expect(observedTargetEmail == "work@company.com")
#expect(store.currentCodexOpenAIWebRefreshGuard().identity == .unresolved)
#expect(store.openAIDashboard?.signedInEmail == "work@company.com")
#expect(store.lastOpenAIDashboardSnapshot?.signedInEmail == "work@company.com")
#expect(store.openAIDashboardRequiresLogin == false)
#expect(store.lastOpenAIDashboardError == nil)
#expect(store.snapshots[.codex]?.accountEmail(for: .codex) == "work@company.com")
#expect(store.lastSourceLabels[.codex] == "test-codex")
#expect(store.credits?.remaining == 55)
#expect(store.lastCreditsSource == .api)
}
@Test
func `dashboard fail closed clears dashboard derived usage credits cache and visible dashboard`() async throws {
OpenAIDashboardCacheStore.clear()
defer { OpenAIDashboardCacheStore.clear() }
let settings = self.makeSettingsStore(suite: "CodexAccountScopedRefreshTests-dashboard-fail-closed-cleanup")
let managedHome = FileManager.default.temporaryDirectory
.appendingPathComponent(UUID().uuidString, isDirectory: true)
defer { try? FileManager.default.removeItem(at: managedHome) }
try Self.writeCodexAuthFile(
homeURL: managedHome,
email: "managed@example.com",
plan: "pro",
accountId: "acct-managed")
let managedAccount = ManagedCodexAccount(
id: UUID(),
email: "managed@example.com",
managedHomePath: managedHome.path,
createdAt: 1,
updatedAt: 1,
lastAuthenticatedAt: 1)
let managedStoreURL = try self.makeManagedAccountStoreURL(accounts: [managedAccount])
defer {
settings._test_managedCodexAccountStoreURL = nil
settings._test_activeManagedCodexAccount = nil
try? FileManager.default.removeItem(at: managedStoreURL)
}
settings.refreshFrequency = .manual
settings.codexCookieSource = .auto
settings._test_managedCodexAccountStoreURL = managedStoreURL
settings._test_activeManagedCodexAccount = managedAccount
settings.codexActiveSource = .managedAccount(id: managedAccount.id)
let store = self.makeUsageStore(settings: settings)
store._setSnapshotForTesting(
self.codexSnapshot(email: "managed@example.com", usedPercent: 20),
provider: .codex)
store.lastSourceLabels[.codex] = "openai-web"
let staleCredits = self.credits(remaining: 20)
store.credits = staleCredits
store.lastCreditsSnapshot = staleCredits
store.lastCreditsSnapshotAccountKey = "managed@example.com"
store.lastCreditsSource = .dashboardWeb
store.openAIDashboard = self.dashboard(email: "managed@example.com", creditsRemaining: 20, usedPercent: 20)
store.lastOpenAIDashboardSnapshot = store.openAIDashboard
OpenAIDashboardCacheStore.save(OpenAIDashboardCache(
accountEmail: "managed@example.com",
snapshot: self.dashboard(email: "managed@example.com", creditsRemaining: 20, usedPercent: 20)))
await store.applyOpenAIDashboard(
self.dashboard(email: "other@example.com", creditsRemaining: 9, usedPercent: 35),
targetEmail: "managed@example.com")
#expect(store.openAIDashboard == nil)
#expect(store.lastOpenAIDashboardSnapshot == nil)
#expect(store.snapshots[.codex] == nil)
#expect(store.credits == nil)
#expect(store.lastCreditsSource == .none)
#expect(OpenAIDashboardCacheStore.load() == nil)
#expect(store.openAIDashboardRequiresLogin == true)
#expect(store.lastOpenAIDashboardError?.contains("OpenAI dashboard signed in as other@example.com") == true)
}
@Test
func `dashboard fail closed cleanup applies after same account managed token rotation`() async throws {
OpenAIDashboardCacheStore.clear()
defer { OpenAIDashboardCacheStore.clear() }
let settings = self.makeSettingsStore(
suite: "CodexAccountScopedRefreshTests-dashboard-fail-closed-token-rotation-cleanup")
let managedHome = FileManager.default.temporaryDirectory
.appendingPathComponent(UUID().uuidString, isDirectory: true)
defer { try? FileManager.default.removeItem(at: managedHome) }
try Self.writeCodexAuthFile(
homeURL: managedHome,
email: "managed@example.com",
plan: "pro",
accountId: "acct-managed")
let oldFingerprint = try #require(CodexAuthFingerprint.fingerprint(homePath: managedHome.path))
let managedAccount = ManagedCodexAccount(
id: UUID(),
email: "managed@example.com",
providerAccountID: "acct-managed",
workspaceLabel: "Managed",
workspaceAccountID: "acct-managed",
authFingerprint: oldFingerprint,
managedHomePath: managedHome.path,
createdAt: 1,
updatedAt: 1,
lastAuthenticatedAt: 1)
let managedStoreURL = try self.makeManagedAccountStoreURL(accounts: [managedAccount])
defer {
settings._test_managedCodexAccountStoreURL = nil
settings._test_activeManagedCodexAccount = nil
try? FileManager.default.removeItem(at: managedStoreURL)
}
settings.refreshFrequency = .manual
settings.codexCookieSource = .auto
settings._test_managedCodexAccountStoreURL = managedStoreURL
settings._test_activeManagedCodexAccount = managedAccount
settings.codexActiveSource = .managedAccount(id: managedAccount.id)
let store = self.makeUsageStore(settings: settings)
let expectedGuard = store.freshCodexOpenAIWebRefreshGuard()
#expect(expectedGuard.authFingerprint == oldFingerprint)
store._setSnapshotForTesting(
self.codexSnapshot(email: "managed@example.com", usedPercent: 20),
provider: .codex)
store.lastSourceLabels[.codex] = "openai-web"
let staleCredits = self.credits(remaining: 20)
store.credits = staleCredits
store.lastCreditsSnapshot = staleCredits
store.lastCreditsSnapshotAccountKey = "managed@example.com"
store.lastCreditsSource = .dashboardWeb
store.openAIDashboard = self.dashboard(email: "managed@example.com", creditsRemaining: 20, usedPercent: 20)
store.lastOpenAIDashboardSnapshot = store.openAIDashboard
OpenAIDashboardCacheStore.save(OpenAIDashboardCache(
accountEmail: "managed@example.com",
snapshot: self.dashboard(email: "managed@example.com", creditsRemaining: 20, usedPercent: 20)))
try Self.writeCodexAuthFile(
homeURL: managedHome,
email: "managed@example.com",
plan: "team",
accountId: "acct-managed")
let newFingerprint = try #require(CodexAuthFingerprint.fingerprint(homePath: managedHome.path))
#expect(newFingerprint != oldFingerprint)
let currentGuard = store.freshCodexOpenAIWebRefreshGuard()
#expect(currentGuard.identity == expectedGuard.identity)
#expect(currentGuard.accountKey == expectedGuard.accountKey)
#expect(currentGuard.authFingerprint == newFingerprint)
await store.applyOpenAIDashboard(
self.dashboard(email: "other@example.com", creditsRemaining: 9, usedPercent: 35),
targetEmail: "managed@example.com",
expectedGuard: expectedGuard)
#expect(store.openAIDashboard == nil)
#expect(store.lastOpenAIDashboardSnapshot == nil)
#expect(store.snapshots[.codex] == nil)
#expect(store.credits == nil)
#expect(store.lastCreditsSource == .none)
#expect(OpenAIDashboardCacheStore.load() == nil)
#expect(store.openAIDashboardRequiresLogin == true)
#expect(store.lastOpenAIDashboardError?.contains("OpenAI dashboard signed in as other@example.com") == true)
}
@Test
func `dashboard fail closed cleanup applies after same live account email changes during token rotation`() async {
OpenAIDashboardCacheStore.clear()
defer { OpenAIDashboardCacheStore.clear() }
let settings = self.makeSettingsStore(
suite: "CodexAccountScopedRefreshTests-dashboard-fail-closed-live-email-rotation-cleanup")
settings.refreshFrequency = .manual
settings.codexCookieSource = .auto
settings.codexActiveSource = .liveSystem
settings._test_liveSystemCodexAccount = ObservedSystemCodexAccount(
email: "alpha@example.com",
authFingerprint: "old-token-material",
codexHomePath: "/Users/test/.codex",
observedAt: Date(),
identity: .providerAccount(id: "acct-alpha"))
defer {
settings._test_liveSystemCodexAccount = nil
}
let store = self.makeUsageStore(settings: settings)
let expectedGuard = store.freshCodexOpenAIWebRefreshGuard()
#expect(expectedGuard.accountKey == "alpha@example.com")
#expect(expectedGuard.authFingerprint == "old-token-material")
store._setSnapshotForTesting(
self.codexSnapshot(email: "alpha@example.com", usedPercent: 20),
provider: .codex)
store.lastSourceLabels[.codex] = "openai-web"
let staleCredits = self.credits(remaining: 20)
store.credits = staleCredits
store.lastCreditsSnapshot = staleCredits
store.lastCreditsSnapshotAccountKey = "alpha@example.com"
store.lastCreditsSource = .dashboardWeb
store.openAIDashboard = self.dashboard(email: "alpha@example.com", creditsRemaining: 20, usedPercent: 20)
store.lastOpenAIDashboardSnapshot = store.openAIDashboard
OpenAIDashboardCacheStore.save(OpenAIDashboardCache(
accountEmail: "alpha@example.com",
snapshot: self.dashboard(email: "alpha@example.com", creditsRemaining: 20, usedPercent: 20)))
settings._test_liveSystemCodexAccount = ObservedSystemCodexAccount(
email: "beta@example.com",
authFingerprint: "new-token-material",
codexHomePath: "/Users/test/.codex",
observedAt: Date(),
identity: .providerAccount(id: "acct-alpha"))
let currentGuard = store.freshCodexOpenAIWebRefreshGuard()
#expect(currentGuard.identity == expectedGuard.identity)
#expect(currentGuard.accountKey == "beta@example.com")
#expect(currentGuard.authFingerprint == "new-token-material")
await store.applyOpenAIDashboard(
self.dashboard(email: "alpha@example.com", creditsRemaining: 9, usedPercent: 35),
targetEmail: "alpha@example.com",
expectedGuard: expectedGuard)
#expect(store.openAIDashboard == nil)
#expect(store.lastOpenAIDashboardSnapshot == nil)
#expect(store.snapshots[.codex] == nil)
#expect(store.credits == nil)
#expect(store.lastCreditsSource == .none)
#expect(OpenAIDashboardCacheStore.load() == nil)
#expect(store.openAIDashboardRequiresLogin == true)
#expect(store.lastOpenAIDashboardError?.contains("OpenAI dashboard signed in as alpha@example.com") == true)
}
}