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

882 lines
39 KiB
Swift

import Foundation
import Testing
@testable import CodexBar
@testable import CodexBarCore
@Suite(.serialized)
@MainActor
struct CodexManagedOpenAIWebTests {
@Test
func `managed codex open A I web uses active managed identity and cache scope`() {
KeychainCacheStore.setTestStoreForTesting(true)
defer { KeychainCacheStore.setTestStoreForTesting(false) }
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-managed")
let managedAccount = ManagedCodexAccount(
id: UUID(),
email: "managed@example.com",
managedHomePath: "/tmp/managed-codex-home",
createdAt: 1,
updatedAt: 1,
lastAuthenticatedAt: 1)
settings._test_activeManagedCodexAccount = managedAccount
settings.codexActiveSource = .managedAccount(id: managedAccount.id)
defer { settings._test_activeManagedCodexAccount = nil }
let otherAccountID = UUID()
CookieHeaderCache.store(
provider: .codex,
scope: .managedAccount(otherAccountID),
cookieHeader: "auth=other-account",
sourceLabel: "Chrome")
CookieHeaderCache.store(
provider: .codex,
cookieHeader: "auth=provider-global",
sourceLabel: "Safari")
defer {
CookieHeaderCache.clear(provider: .codex, scope: .managedAccount(otherAccountID))
CookieHeaderCache.clear(provider: .codex)
}
let store = UsageStore(
fetcher: UsageFetcher(environment: [:]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
#expect(store.codexAccountEmailForOpenAIDashboard() == "managed@example.com")
#expect(store.codexCookieCacheScopeForOpenAIWeb() == .managedAccount(managedAccount.id))
#expect(CookieHeaderCache.load(provider: .codex, scope: store.codexCookieCacheScopeForOpenAIWeb()) == nil)
}
@Test
func `managed codex open A I web targets runtime auth backed email for selected account`() throws {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-managed-runtime-email")
let managedHome = FileManager.default.temporaryDirectory
.appendingPathComponent(UUID().uuidString, isDirectory: true)
defer { try? FileManager.default.removeItem(at: managedHome) }
try Self.writeCodexAuthFile(
homeURL: managedHome,
email: "renamed@example.com",
plan: "pro",
accountId: "acct-managed")
let managedAccount = ManagedCodexAccount(
id: UUID(),
email: "legacy@example.com",
managedHomePath: managedHome.path,
createdAt: 1,
updatedAt: 1,
lastAuthenticatedAt: 1)
settings._test_activeManagedCodexAccount = managedAccount
settings.codexActiveSource = .managedAccount(id: managedAccount.id)
defer { settings._test_activeManagedCodexAccount = nil }
let store = UsageStore(
fetcher: UsageFetcher(environment: [:]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
#expect(store.codexAccountEmailForOpenAIDashboard() == "renamed@example.com")
#expect(store.codexAccountEmailForOpenAIDashboard() != managedAccount.email)
#expect(store.currentCodexOpenAIWebRefreshGuard().accountKey == "renamed@example.com")
#expect(store.currentCodexOpenAIWebRefreshGuard().identity == .providerAccount(id: "acct-managed"))
}
@Test
func `live system codex open A I web uses live identity and no managed cache scope`() {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-live-system")
let managedAccount = ManagedCodexAccount(
id: UUID(),
email: "managed@example.com",
managedHomePath: "/tmp/managed-codex-home",
createdAt: 1,
updatedAt: 1,
lastAuthenticatedAt: 1)
let liveAccount = ObservedSystemCodexAccount(
email: "system@example.com",
codexHomePath: "/tmp/live-codex-home",
observedAt: Date())
settings._test_activeManagedCodexAccount = managedAccount
settings._test_liveSystemCodexAccount = liveAccount
settings.codexActiveSource = .liveSystem
defer {
settings._test_activeManagedCodexAccount = nil
settings._test_liveSystemCodexAccount = nil
}
let store = UsageStore(
fetcher: UsageFetcher(environment: ["CODEX_HOME": liveAccount.codexHomePath]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
#expect(store.codexAccountEmailForOpenAIDashboard() == liveAccount.email)
#expect(store.codexAccountEmailForOpenAIDashboard() != managedAccount.email)
#expect(store.codexCookieCacheScopeForOpenAIWeb() == nil)
}
@Test
func `live system codex open A I web does not reuse stale managed snapshot email after source switch`() {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-live-system-stale-managed-snapshot")
let isolatedHome = FileManager.default.temporaryDirectory
.appendingPathComponent("codex-openai-web-empty-\(UUID().uuidString)", isDirectory: true)
try? FileManager.default.createDirectory(at: isolatedHome, withIntermediateDirectories: true)
let managedAccount = ManagedCodexAccount(
id: UUID(),
email: "managed@example.com",
managedHomePath: "/tmp/managed-codex-home",
createdAt: 1,
updatedAt: 1,
lastAuthenticatedAt: 1)
settings._test_activeManagedCodexAccount = managedAccount
settings._test_codexReconciliationEnvironment = ["CODEX_HOME": isolatedHome.path]
settings.codexActiveSource = .liveSystem
defer {
settings._test_activeManagedCodexAccount = nil
settings._test_codexReconciliationEnvironment = nil
try? FileManager.default.removeItem(at: isolatedHome)
}
let store = UsageStore(
fetcher: UsageFetcher(environment: [:]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
store._setSnapshotForTesting(
UsageSnapshot(
primary: nil,
secondary: nil,
updatedAt: Date(),
identity: ProviderIdentitySnapshot(
providerID: .codex,
accountEmail: managedAccount.email,
accountOrganization: nil,
loginMethod: nil)),
provider: .codex)
#expect(store.codexAccountEmailForOpenAIDashboard() == nil)
#expect(store.codexAccountEmailForOpenAIDashboard() != managedAccount.email)
#expect(store.codexCookieCacheScopeForOpenAIWeb() == nil)
}
@Test
func `live system codex open A I web reuses last known live email without allowing any account`() async {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-live-system-last-known-email")
let isolatedHome = FileManager.default.temporaryDirectory
.appendingPathComponent("codex-openai-web-last-known-\(UUID().uuidString)", isDirectory: true)
try? FileManager.default.createDirectory(at: isolatedHome, withIntermediateDirectories: true)
let liveAccount = ObservedSystemCodexAccount(
email: "live@example.com",
codexHomePath: "/tmp/live-codex-home",
observedAt: Date())
settings._test_liveSystemCodexAccount = liveAccount
settings._test_codexReconciliationEnvironment = ["CODEX_HOME": isolatedHome.path]
settings.codexActiveSource = .liveSystem
let store = UsageStore(
fetcher: UsageFetcher(environment: [:]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
#expect(store.codexAccountEmailForOpenAIDashboard() == liveAccount.email)
settings._test_liveSystemCodexAccount = nil
defer {
settings._test_liveSystemCodexAccount = nil
settings._test_codexReconciliationEnvironment = nil
try? FileManager.default.removeItem(at: isolatedHome)
}
store.openAIDashboard = OpenAIDashboardSnapshot(
signedInEmail: "managed@example.com",
codeReviewRemainingPercent: 100,
creditEvents: [],
dailyBreakdown: [],
usageBreakdown: [],
creditsPurchaseURL: nil,
updatedAt: Date())
store.lastOpenAIDashboardCookieImportEmail = "managed-import@example.com"
var observedTargetEmail: String?
var observedAllowAnyAccount: Bool?
store._test_openAIDashboardCookieImportOverride = { targetEmail, allowAnyAccount, _, _, _ in
observedTargetEmail = targetEmail
observedAllowAnyAccount = allowAnyAccount
return OpenAIDashboardBrowserCookieImporter.ImportResult(
sourceLabel: "test",
cookieCount: 1,
signedInEmail: targetEmail,
matchesCodexEmail: true)
}
defer { store._test_openAIDashboardCookieImportOverride = nil }
let targetEmail = store.codexAccountEmailForOpenAIDashboard()
let imported = await store.importOpenAIDashboardCookiesIfNeeded(targetEmail: targetEmail, force: true)
#expect(targetEmail == liveAccount.email)
#expect(targetEmail != "managed@example.com")
#expect(targetEmail != "managed-import@example.com")
#expect(imported == liveAccount.email)
#expect(observedTargetEmail == liveAccount.email)
#expect(observedAllowAnyAccount == false)
}
@Test
func `successful dashboard apply preserves cached open A I web view for same account`() async {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-preserve-cache-on-success")
let managedAccount = ManagedCodexAccount(
id: UUID(),
email: "managed@example.com",
managedHomePath: "/tmp/managed-codex-home",
createdAt: 1,
updatedAt: 1,
lastAuthenticatedAt: 1)
settings._test_activeManagedCodexAccount = managedAccount
settings.codexActiveSource = .managedAccount(id: managedAccount.id)
defer { settings._test_activeManagedCodexAccount = nil }
OpenAIDashboardWebsiteDataStore.clearCacheForTesting()
let cache = OpenAIDashboardWebViewCache.shared
cache.clearAllForTesting()
defer {
cache.clearAllForTesting()
OpenAIDashboardWebsiteDataStore.clearCacheForTesting()
}
let store = UsageStore(
fetcher: UsageFetcher(environment: [:]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
let websiteDataStore = OpenAIDashboardWebsiteDataStore.store(forAccountEmail: managedAccount.email)
cache.cacheEntryForTesting(websiteDataStore: websiteDataStore)
#expect(cache.hasCachedEntry(for: websiteDataStore))
await store.applyOpenAIDashboard(
OpenAIDashboardSnapshot(
signedInEmail: managedAccount.email,
codeReviewRemainingPercent: 90,
creditEvents: [],
dailyBreakdown: [],
usageBreakdown: [],
creditsPurchaseURL: nil,
creditsRemaining: 10,
accountPlan: "Pro",
updatedAt: Date()),
targetEmail: managedAccount.email)
#expect(cache.hasCachedEntry(for: websiteDataStore))
#expect(cache.entryCount == 1)
}
@Test
func `dashboard refresh does not target stale last known live email`() async {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-live-system-refresh-strict-target")
let isolatedHome = FileManager.default.temporaryDirectory
.appendingPathComponent("codex-openai-web-refresh-strict-\(UUID().uuidString)", isDirectory: true)
try? FileManager.default.createDirectory(at: isolatedHome, withIntermediateDirectories: true)
let liveAccount = ObservedSystemCodexAccount(
email: "old@example.com",
codexHomePath: "/tmp/live-codex-home",
observedAt: Date())
settings._test_liveSystemCodexAccount = liveAccount
settings._test_codexReconciliationEnvironment = ["CODEX_HOME": isolatedHome.path]
settings.codexActiveSource = .liveSystem
let store = UsageStore(
fetcher: UsageFetcher(environment: [:]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
#expect(store.codexAccountEmailForOpenAIDashboard() == liveAccount.email)
settings._test_liveSystemCodexAccount = nil
defer {
settings._test_liveSystemCodexAccount = nil
settings._test_codexReconciliationEnvironment = nil
try? FileManager.default.removeItem(at: isolatedHome)
}
var observedTargetEmail: String?
store._test_openAIDashboardLoaderOverride = { accountEmail, _, _, _ in
observedTargetEmail = accountEmail
return OpenAIDashboardSnapshot(
signedInEmail: "new@example.com",
codeReviewRemainingPercent: 88,
creditEvents: [],
dailyBreakdown: [],
usageBreakdown: [],
creditsPurchaseURL: nil,
primaryLimit: RateWindow(usedPercent: 12, windowMinutes: 300, resetsAt: nil, resetDescription: nil),
secondaryLimit: nil,
creditsRemaining: 22,
accountPlan: "Pro",
updatedAt: Date())
}
defer { store._test_openAIDashboardLoaderOverride = nil }
let expectedGuard = store.currentCodexOpenAIWebRefreshGuard()
#expect(expectedGuard.accountKey == nil)
await store.refreshOpenAIDashboardIfNeeded(force: true, expectedGuard: expectedGuard)
#expect(observedTargetEmail == nil)
#expect(store.openAIDashboard == nil)
#expect(store.openAIDashboardRequiresLogin == true)
#expect(store.lastOpenAIDashboardError?.contains("could not be verified") == true)
#expect(store.lastKnownLiveSystemCodexEmail == "old@example.com")
}
@Test
func `dashboard refresh targets usage discovered live email before reconciliation catches up`() async {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-live-system-usage-discovered-target")
let isolatedHome = FileManager.default.temporaryDirectory
.appendingPathComponent("codex-openai-web-usage-discovered-\(UUID().uuidString)", isDirectory: true)
try? FileManager.default.createDirectory(at: isolatedHome, withIntermediateDirectories: true)
settings._test_codexReconciliationEnvironment = ["CODEX_HOME": isolatedHome.path]
settings.codexActiveSource = .liveSystem
defer {
settings._test_codexReconciliationEnvironment = nil
try? FileManager.default.removeItem(at: isolatedHome)
}
let store = UsageStore(
fetcher: UsageFetcher(environment: [:]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
store._setSnapshotForTesting(
UsageSnapshot(
primary: nil,
secondary: nil,
updatedAt: Date(),
identity: ProviderIdentitySnapshot(
providerID: .codex,
accountEmail: "usage@example.com",
accountOrganization: nil,
loginMethod: nil)),
provider: .codex)
store.lastSourceLabels[.codex] = "codex-cli"
var observedTargetEmail: String?
store._test_openAIDashboardLoaderOverride = { accountEmail, _, _, _ in
observedTargetEmail = accountEmail
return OpenAIDashboardSnapshot(
signedInEmail: "usage@example.com",
codeReviewRemainingPercent: 88,
creditEvents: [],
dailyBreakdown: [],
usageBreakdown: [],
creditsPurchaseURL: nil,
primaryLimit: RateWindow(usedPercent: 12, windowMinutes: 300, resetsAt: nil, resetDescription: nil),
secondaryLimit: nil,
creditsRemaining: 22,
accountPlan: "Pro",
updatedAt: Date())
}
defer { store._test_openAIDashboardLoaderOverride = nil }
let expectedGuard = store.currentCodexOpenAIWebRefreshGuard()
#expect(expectedGuard.accountKey == nil)
await store.refreshOpenAIDashboardIfNeeded(force: true, expectedGuard: expectedGuard)
#expect(observedTargetEmail == "usage@example.com")
#expect(store.openAIDashboard?.signedInEmail == "usage@example.com")
}
@Test
func `usage discovered live email still surfaces open A I web login guidance during reconciliation lag`() async {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-live-system-usage-discovered-failure")
let isolatedHome = FileManager.default.temporaryDirectory
.appendingPathComponent("codex-openai-web-usage-discovered-failure-\(UUID().uuidString)", isDirectory: true)
try? FileManager.default.createDirectory(at: isolatedHome, withIntermediateDirectories: true)
settings._test_codexReconciliationEnvironment = ["CODEX_HOME": isolatedHome.path]
settings.codexActiveSource = .liveSystem
defer {
settings._test_codexReconciliationEnvironment = nil
try? FileManager.default.removeItem(at: isolatedHome)
}
let store = UsageStore(
fetcher: UsageFetcher(environment: [:]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
store._setSnapshotForTesting(
UsageSnapshot(
primary: nil,
secondary: nil,
updatedAt: Date(),
identity: ProviderIdentitySnapshot(
providerID: .codex,
accountEmail: "usage@example.com",
accountOrganization: nil,
loginMethod: nil)),
provider: .codex)
store.lastSourceLabels[.codex] = "codex-cli"
let expectedGuard = store.currentCodexOpenAIWebRefreshGuard()
#expect(expectedGuard.accountKey == nil)
await store.applyOpenAIDashboardLoginRequiredFailure(
expectedGuard: expectedGuard,
routingTargetEmail: "usage@example.com")
#expect(store.openAIDashboardRequiresLogin == true)
#expect(store.lastOpenAIDashboardError?.contains("requires a signed-in chatgpt.com session") == true)
}
@Test
func `open A I web import uses managed account target when live account differs`() async {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-targeting-active-vs-live")
let managedAccount = ManagedCodexAccount(
id: UUID(),
email: "managed@example.com",
managedHomePath: "/tmp/managed-codex-home",
createdAt: 1,
updatedAt: 1,
lastAuthenticatedAt: 1)
let liveAccount = ObservedSystemCodexAccount(
email: "system@example.com",
codexHomePath: "/tmp/live-codex-home",
observedAt: Date())
let expectedScope = CookieHeaderCache.Scope.managedAccount(managedAccount.id)
let expectedEmail = managedAccount.email
var observedTargetEmail: String?
var observedScope: CookieHeaderCache.Scope?
var observedCookieSource: ProviderCookieSource?
var observedAllowAnyAccount = false
settings._test_activeManagedCodexAccount = managedAccount
settings._test_liveSystemCodexAccount = liveAccount
settings.codexActiveSource = .managedAccount(id: managedAccount.id)
defer {
settings._test_activeManagedCodexAccount = nil
settings._test_liveSystemCodexAccount = nil
}
let snapshot = UsageSnapshot(
primary: nil,
secondary: nil,
updatedAt: Date(),
identity: ProviderIdentitySnapshot(
providerID: .codex,
accountEmail: liveAccount.email,
accountOrganization: nil,
loginMethod: nil))
let store = UsageStore(
fetcher: UsageFetcher(environment: ["CODEX_HOME": liveAccount.codexHomePath]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
store._setSnapshotForTesting(snapshot, provider: .codex)
store._test_openAIDashboardCookieImportOverride = { targetEmail, allowAnyAccount, cookieSource, scope, _ in
observedTargetEmail = targetEmail
observedScope = scope
observedCookieSource = cookieSource
observedAllowAnyAccount = allowAnyAccount
return OpenAIDashboardBrowserCookieImporter.ImportResult(
sourceLabel: "test",
cookieCount: 1,
signedInEmail: targetEmail,
matchesCodexEmail: targetEmail == expectedEmail)
}
defer { store._test_openAIDashboardCookieImportOverride = nil }
let importerTarget = store.codexAccountEmailForOpenAIDashboard()
let imported = await store.importOpenAIDashboardCookiesIfNeeded(targetEmail: importerTarget, force: true)
#expect(importerTarget == expectedEmail)
#expect(importerTarget != liveAccount.email)
#expect(imported == expectedEmail)
#expect(observedTargetEmail == expectedEmail)
#expect(observedScope == expectedScope)
#expect(observedAllowAnyAccount == false)
#expect(observedCookieSource == .auto)
#expect(store.codexCookieCacheScopeForOpenAIWeb() == expectedScope)
}
@Test
func `open A I web prefers live identity when managed and live share email`() {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-same-email-prefers-live")
let managedAccount = ManagedCodexAccount(
id: UUID(),
email: "person@example.com",
managedHomePath: "/tmp/managed-codex-home",
createdAt: 1,
updatedAt: 1,
lastAuthenticatedAt: 1)
let liveAccount = ObservedSystemCodexAccount(
email: "PERSON@example.com",
codexHomePath: "/tmp/live-codex-home",
observedAt: Date())
settings._test_activeManagedCodexAccount = managedAccount
settings._test_liveSystemCodexAccount = liveAccount
settings.codexActiveSource = .managedAccount(id: managedAccount.id)
defer {
settings._test_activeManagedCodexAccount = nil
settings._test_liveSystemCodexAccount = nil
}
let store = UsageStore(
fetcher: UsageFetcher(environment: ["CODEX_HOME": liveAccount.codexHomePath]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
#expect(settings.codexResolvedActiveSource == .liveSystem)
#expect(store.codexAccountEmailForOpenAIDashboard() == "person@example.com")
#expect(store.codexCookieCacheScopeForOpenAIWeb() == nil)
}
@Test
func `unmanaged codex open A I web falls back to provider global cache scope`() {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-unmanaged")
let store = UsageStore(
fetcher: UsageFetcher(environment: [:]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
#expect(store.codexCookieCacheScopeForOpenAIWeb() == nil)
}
@Test
func `unreadable managed codex store fails closed for open A I web`() async {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-unreadable-store")
settings._test_unreadableManagedCodexAccountStore = true
settings.codexActiveSource = .managedAccount(id: UUID())
defer { settings._test_unreadableManagedCodexAccountStore = false }
let store = UsageStore(
fetcher: UsageFetcher(environment: [:]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
#expect(store.codexCookieCacheScopeForOpenAIWeb() == .managedStoreUnreadable)
#expect(store.codexAccountEmailForOpenAIDashboard() == nil)
let imported = await store.importOpenAIDashboardCookiesIfNeeded(targetEmail: nil, force: true)
#expect(imported == nil)
#expect(store.openAIDashboard == nil)
#expect(store.openAIDashboardRequiresLogin == true)
#expect(store.openAIDashboardCookieImportStatus?.contains("Managed Codex account data is unavailable") == true)
await store.refreshOpenAIDashboardIfNeeded(force: true)
#expect(store.openAIDashboard == nil)
#expect(store.openAIDashboardRequiresLogin == true)
#expect(store.lastOpenAIDashboardError?.contains("Managed Codex account data is unavailable") == true)
}
@Test
func `missing managed codex open A I web target fails closed`() async {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-missing-managed-target")
let storedAccount = ManagedCodexAccount(
id: UUID(),
email: "stored@example.com",
managedHomePath: "/tmp/stored-managed-home",
createdAt: 1,
updatedAt: 1,
lastAuthenticatedAt: 1)
let storeURL = FileManager.default.temporaryDirectory
.appendingPathComponent("codex-openai-web-\(UUID().uuidString).json")
let managedStore = FileManagedCodexAccountStore(fileURL: storeURL)
try? managedStore.storeAccounts(ManagedCodexAccountSet(
version: FileManagedCodexAccountStore.currentVersion,
accounts: [storedAccount]))
settings._test_managedCodexAccountStoreURL = storeURL
settings.codexActiveSource = .managedAccount(id: UUID())
defer {
settings._test_managedCodexAccountStoreURL = nil
try? FileManager.default.removeItem(at: storeURL)
}
let store = UsageStore(
fetcher: UsageFetcher(environment: [:]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
var importWasCalled = false
store._test_openAIDashboardCookieImportOverride = { _, _, _, _, _ in
importWasCalled = true
return OpenAIDashboardBrowserCookieImporter.ImportResult(
sourceLabel: "test",
cookieCount: 1,
signedInEmail: "unexpected@example.com",
matchesCodexEmail: true)
}
defer { store._test_openAIDashboardCookieImportOverride = nil }
store.openAIDashboard = OpenAIDashboardSnapshot(
signedInEmail: "stale-dashboard@example.com",
codeReviewRemainingPercent: 100,
creditEvents: [],
dailyBreakdown: [],
usageBreakdown: [],
creditsPurchaseURL: nil,
updatedAt: Date())
store.lastOpenAIDashboardCookieImportEmail = "stale-import@example.com"
#expect(store.codexAccountEmailForOpenAIDashboard() == nil)
#expect(store.codexCookieCacheScopeForOpenAIWeb() != nil)
#expect(store.codexCookieCacheScopeForOpenAIWeb() != .managedStoreUnreadable)
let imported = await store.importOpenAIDashboardCookiesIfNeeded(targetEmail: nil, force: true)
#expect(imported == nil)
#expect(importWasCalled == false)
#expect(store.openAIDashboard == nil)
#expect(store.openAIDashboardRequiresLogin == true)
#expect(store.openAIDashboardCookieImportStatus?
.contains("selected managed Codex account is unavailable") == true)
await store.refreshOpenAIDashboardIfNeeded(force: true)
#expect(importWasCalled == false)
#expect(store.openAIDashboard == nil)
#expect(store.lastOpenAIDashboardError?.contains("selected managed Codex account is unavailable") == true)
}
@Test
func `managed codex mismatch fail closed blocks stale dashboard restoration`() async {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-mismatch")
let managedAccount = ManagedCodexAccount(
id: UUID(),
email: "managed@example.com",
managedHomePath: "/tmp/managed-codex-home",
createdAt: 1,
updatedAt: 1,
lastAuthenticatedAt: 1)
settings._test_activeManagedCodexAccount = managedAccount
settings.codexActiveSource = .managedAccount(id: managedAccount.id)
defer { settings._test_activeManagedCodexAccount = nil }
let store = UsageStore(
fetcher: UsageFetcher(environment: [:]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
let staleSnapshot = OpenAIDashboardSnapshot(
signedInEmail: managedAccount.email,
codeReviewRemainingPercent: 100,
creditEvents: [],
dailyBreakdown: [],
usageBreakdown: [],
creditsPurchaseURL: nil,
updatedAt: Date())
await store.applyOpenAIDashboard(staleSnapshot, targetEmail: managedAccount.email)
await store.applyOpenAIDashboard(
OpenAIDashboardSnapshot(
signedInEmail: "other@example.com",
codeReviewRemainingPercent: 100,
creditEvents: [],
dailyBreakdown: [],
usageBreakdown: [],
creditsPurchaseURL: nil,
updatedAt: Date()),
targetEmail: managedAccount.email)
#expect(store.openAIDashboard == nil)
#expect(store.lastOpenAIDashboardSnapshot == nil)
#expect(store.openAIDashboardRequiresLogin == true)
#expect(store.lastOpenAIDashboardError?.contains("OpenAI dashboard signed in as other@example.com") == true)
await store.applyOpenAIDashboardFailure(message: "No dashboard data")
#expect(store.openAIDashboard == nil)
#expect(store.lastOpenAIDashboardError == "No dashboard data")
await store.applyOpenAIDashboardLoginRequiredFailure()
#expect(store.openAIDashboard == nil)
#expect(store.openAIDashboardRequiresLogin == true)
#expect(store.lastOpenAIDashboardError?.contains("requires a signed-in chatgpt.com session") == true)
}
@Test
func `managed codex import mismatch fail closed blocks stale dashboard restoration`() async {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-import-mismatch")
let managedAccount = ManagedCodexAccount(
id: UUID(),
email: "managed@example.com",
managedHomePath: "/tmp/managed-codex-home",
createdAt: 1,
updatedAt: 1,
lastAuthenticatedAt: 1)
settings._test_activeManagedCodexAccount = managedAccount
defer { settings._test_activeManagedCodexAccount = nil }
let store = UsageStore(
fetcher: UsageFetcher(environment: [:]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
store._test_openAIDashboardCookieImportOverride = { _, _, _, _, _ in
throw OpenAIDashboardBrowserCookieImporter.ImportError.noMatchingAccount(
found: [.init(sourceLabel: "Chrome", email: "other@example.com")])
}
let staleSnapshot = OpenAIDashboardSnapshot(
signedInEmail: managedAccount.email,
codeReviewRemainingPercent: 100,
creditEvents: [],
dailyBreakdown: [],
usageBreakdown: [],
creditsPurchaseURL: nil,
updatedAt: Date())
await store.applyOpenAIDashboard(staleSnapshot, targetEmail: managedAccount.email)
let imported = await store.importOpenAIDashboardCookiesIfNeeded(
targetEmail: managedAccount.email,
force: true)
#expect(imported == nil)
#expect(store.openAIDashboard == nil)
#expect(store.openAIDashboardRequiresLogin == true)
#expect(
store.openAIDashboardCookieImportStatus ==
"OpenAI cookies are for other@example.com, not managed@example.com.")
await store.applyOpenAIDashboardFailure(message: "No dashboard data")
#expect(store.openAIDashboard == nil)
#expect(store.lastOpenAIDashboardError == "No dashboard data")
await store.applyOpenAIDashboardLoginRequiredFailure()
#expect(store.openAIDashboard == nil)
#expect(store.openAIDashboardRequiresLogin == true)
#expect(store.lastOpenAIDashboardError?.contains("requires a signed-in chatgpt.com session") == true)
}
@Test
func `missing managed target failure handlers do not resurrect stale dashboard state`() async {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-missing-target-failure-handlers")
let isolatedHome = FileManager.default.temporaryDirectory
.appendingPathComponent("codex-openai-web-missing-target-\(UUID().uuidString)", isDirectory: true)
try? FileManager.default.createDirectory(at: isolatedHome, withIntermediateDirectories: true)
settings._test_codexReconciliationEnvironment = ["CODEX_HOME": isolatedHome.path]
settings.codexActiveSource = .managedAccount(id: UUID())
defer {
settings._test_codexReconciliationEnvironment = nil
try? FileManager.default.removeItem(at: isolatedHome)
}
let store = UsageStore(
fetcher: UsageFetcher(environment: [:]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
let staleSnapshot = OpenAIDashboardSnapshot(
signedInEmail: "stale@example.com",
codeReviewRemainingPercent: 100,
creditEvents: [],
dailyBreakdown: [],
usageBreakdown: [],
creditsPurchaseURL: nil,
updatedAt: Date())
await store.applyOpenAIDashboard(staleSnapshot, targetEmail: "stale@example.com")
await store.applyOpenAIDashboardFailure(message: "No dashboard data")
#expect(store.openAIDashboard == nil)
#expect(store.lastOpenAIDashboardSnapshot == nil)
#expect(store.lastOpenAIDashboardError?.contains("selected managed Codex account is unavailable") == true)
await store.applyOpenAIDashboard(staleSnapshot, targetEmail: "stale@example.com")
await store.applyOpenAIDashboardLoginRequiredFailure()
#expect(store.openAIDashboard == nil)
#expect(store.lastOpenAIDashboardSnapshot == nil)
#expect(store.openAIDashboardRequiresLogin == true)
#expect(store.lastOpenAIDashboardError?.contains("selected managed Codex account is unavailable") == true)
}
@Test
func `managed codex refresh stops after cookie mismatch instead of retrying web view`() async {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-mismatch-aborts-retry")
let managedAccount = ManagedCodexAccount(
id: UUID(),
email: "ratulsarna@gmail.com",
managedHomePath: "/tmp/managed-codex-home",
createdAt: 1,
updatedAt: 1,
lastAuthenticatedAt: 1)
settings._test_activeManagedCodexAccount = managedAccount
settings.codexActiveSource = .managedAccount(id: managedAccount.id)
defer { settings._test_activeManagedCodexAccount = nil }
let store = UsageStore(
fetcher: UsageFetcher(environment: [:]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
var loaderCalls = 0
store._test_openAIDashboardLoaderOverride = { _, _, _, _ in
loaderCalls += 1
throw OpenAIDashboardFetcher.FetchError.loginRequired
}
defer { store._test_openAIDashboardLoaderOverride = nil }
store._test_openAIDashboardCookieImportOverride = { _, _, _, _, _ in
throw OpenAIDashboardBrowserCookieImporter.ImportError.noMatchingAccount(
found: [.init(sourceLabel: "Chrome", email: "rdsarna@gmail.com")])
}
defer { store._test_openAIDashboardCookieImportOverride = nil }
let expectedGuard = store.currentCodexOpenAIWebRefreshGuard()
await store.refreshOpenAIDashboardIfNeeded(force: true, expectedGuard: expectedGuard)
#expect(loaderCalls == 1)
#expect(
store.lastOpenAIDashboardError ==
"OpenAI cookies are for rdsarna@gmail.com, not ratulsarna@gmail.com. " +
"Switch chatgpt.com account, then refresh OpenAI cookies.")
#expect(store.openAIDashboard == nil)
}
@Test
func `managed codex refresh reports no matching web session without fake account`() async {
let settings = self.makeSettingsStore(suite: "CodexManagedOpenAIWebTests-no-matching-web-session")
let managedAccount = ManagedCodexAccount(
id: UUID(),
email: "ratulsarna@gmail.com",
managedHomePath: "/tmp/managed-codex-home",
createdAt: 1,
updatedAt: 1,
lastAuthenticatedAt: 1)
settings._test_activeManagedCodexAccount = managedAccount
settings.codexActiveSource = .managedAccount(id: managedAccount.id)
defer { settings._test_activeManagedCodexAccount = nil }
let store = UsageStore(
fetcher: UsageFetcher(environment: [:]),
browserDetection: BrowserDetection(cacheTTL: 0),
settings: settings,
startupBehavior: .testing)
store._test_openAIDashboardLoaderOverride = { _, _, _, _ in
throw OpenAIDashboardFetcher.FetchError.loginRequired
}
defer { store._test_openAIDashboardLoaderOverride = nil }
store._test_openAIDashboardCookieImportOverride = { _, _, _, _, _ in
throw OpenAIDashboardBrowserCookieImporter.ImportError.noMatchingAccount(found: [])
}
defer { store._test_openAIDashboardCookieImportOverride = nil }
let expectedGuard = store.currentCodexOpenAIWebRefreshGuard()
await store.refreshOpenAIDashboardIfNeeded(force: true, expectedGuard: expectedGuard)
#expect(
store.lastOpenAIDashboardError ==
"No matching OpenAI web session found for ratulsarna@gmail.com. " +
"Sign in to chatgpt.com as ratulsarna@gmail.com, then refresh OpenAI cookies.")
#expect(store.openAIDashboard == nil)
}
}