import Foundation import Testing @testable import CodexBar @testable import CodexBarCLI @testable import CodexBarCore @Suite(.serialized) @MainActor struct CodexDashboardWorkedExampleParityTests { @Test func `worked example A wrong email app and CLI both reject and retire owned state`() async throws { try await self.withIsolatedDashboardCache { OpenAIDashboardCacheStore.clear() defer { OpenAIDashboardCacheStore.clear() } let store = self.makeAppStore(suite: "CodexDashboardWorkedExampleParityTests-example-a") store.settings._test_liveSystemCodexAccount = self.liveAccount( email: "work@company.com", identity: .emailOnly(normalizedEmail: "work@company.com")) store.settings.codexActiveSource = .liveSystem let attachedDashboard = self.makeDashboard( email: "work@company.com", creditsRemaining: 42, usedPercent: 20) let attachedCredits = self.credits(remaining: 42) store._setSnapshotForTesting( self.codexSnapshot(email: "work@company.com", usedPercent: 20), provider: .codex) store.lastSourceLabels[.codex] = "openai-web" store.credits = attachedCredits store.lastCreditsSnapshot = attachedCredits store.lastCreditsSnapshotAccountKey = "work@company.com" store.lastCreditsSource = .dashboardWeb store.openAIDashboard = attachedDashboard store.lastOpenAIDashboardSnapshot = attachedDashboard store.lastOpenAIDashboardTargetEmail = "work@company.com" OpenAIDashboardCacheStore.save(OpenAIDashboardCache( accountEmail: "work@company.com", snapshot: attachedDashboard)) await store.applyOpenAIDashboard( self.makeDashboard( email: "personal@gmail.com", creditsRemaining: 9, usedPercent: 35), targetEmail: "work@company.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) let authHome = try self.makeAuthHome( email: "work@company.com", accountId: "acct-work") defer { try? FileManager.default.removeItem(at: authHome) } let cliContext = self.makeCLIContext( authHome: authHome, knownOwners: [ CodexDashboardKnownOwnerCandidate( identity: .providerAccount(id: "acct-work"), normalizedEmail: "work@company.com"), ]) let wrongEmailDashboard = self.makeDashboard( email: "personal@gmail.com", creditsRemaining: 9, usedPercent: 35) do { _ = try CodexWebDashboardStrategy.makeAuthorizedDashboardResultForTesting( dashboard: wrongEmailDashboard, context: cliContext, routingTargetEmail: "work@company.com") Issue.record("Expected OpenAIWebCodexError.policyRejected") } catch let error as OpenAIWebCodexError { if case let .policyRejected(decision) = error { #expect(decision.reason == .wrongEmail(expected: "work@company.com", actual: "personal@gmail.com")) } else { Issue.record("Expected policyRejected, got \(error)") } } catch { Issue.record("Expected OpenAIWebCodexError.policyRejected, got \(error)") } OpenAIDashboardCacheStore.save(OpenAIDashboardCache( accountEmail: "personal@gmail.com", snapshot: wrongEmailDashboard)) let restored = CodexBarCLI.loadOpenAIDashboardIfAvailable( usage: self.makeUsage(email: "work@company.com"), sourceLabel: "codex-cli", context: cliContext) #expect(restored == nil) #expect(OpenAIDashboardCacheStore.load() == nil) } } @Test func `worked example B same email ambiguity is display only in app and non attach in CLI`() async throws { try await self.withIsolatedDashboardCache { OpenAIDashboardCacheStore.clear() defer { OpenAIDashboardCacheStore.clear() } let managedHome = try self.makeAuthHome( email: "work@company.com", accountId: "acct-managed") defer { try? FileManager.default.removeItem(at: managedHome) } let managedAccount = ManagedCodexAccount( id: UUID(), email: "work@company.com", managedHomePath: managedHome.path, createdAt: 1, updatedAt: 1, lastAuthenticatedAt: 1) let managedStoreURL = try self.makeManagedAccountStoreURL(accounts: [managedAccount]) defer { try? FileManager.default.removeItem(at: managedStoreURL) } let store = self.makeAppStore(suite: "CodexDashboardWorkedExampleParityTests-example-b") store.settings._test_managedCodexAccountStoreURL = managedStoreURL store.settings._test_liveSystemCodexAccount = self.liveAccount( email: "work@company.com", identity: .emailOnly(normalizedEmail: "work@company.com")) store.settings.codexActiveSource = .liveSystem await store.applyOpenAIDashboard( self.makeDashboard( email: "work@company.com", creditsRemaining: 14, usedPercent: 30, includeUsageBreakdown: true), targetEmail: "work@company.com") try await Task.sleep(for: .milliseconds(250)) #expect(store.openAIDashboard?.signedInEmail == "work@company.com") #expect(store.snapshots[.codex] == nil) #expect(store.credits == nil) #expect(OpenAIDashboardCacheStore.load() == nil) #expect(store.codexHistoricalDataset == nil) let cliAuthHome = try self.makeAuthHome(email: "work@company.com") defer { try? FileManager.default.removeItem(at: cliAuthHome) } let ambiguousOwners = [ CodexDashboardKnownOwnerCandidate( identity: .providerAccount(id: "acct-alpha"), normalizedEmail: "work@company.com"), CodexDashboardKnownOwnerCandidate( identity: .providerAccount(id: "acct-beta"), normalizedEmail: "work@company.com"), ] let cliContext = self.makeCLIContext( authHome: cliAuthHome, knownOwners: ambiguousOwners) let dashboard = self.makeDashboard( email: "work@company.com", creditsRemaining: 14, usedPercent: 30, includeUsageBreakdown: true) let expectedDecision = CodexDashboardAuthority.evaluate( CodexCLIDashboardAuthorityContext.makeLiveWebInput( dashboard: dashboard, context: cliContext, routingTargetEmail: "work@company.com")) do { _ = try CodexWebDashboardStrategy.makeAuthorizedDashboardResultForTesting( dashboard: dashboard, context: cliContext, routingTargetEmail: "work@company.com") Issue.record("Expected CodexDashboardPolicyError.displayOnly") } catch let error as CodexDashboardPolicyError { #expect(error == .displayOnly(expectedDecision)) } catch { Issue.record("Expected CodexDashboardPolicyError.displayOnly, got \(error)") } OpenAIDashboardCacheStore.save(OpenAIDashboardCache( accountEmail: "work@company.com", snapshot: dashboard)) let restored = CodexBarCLI.loadOpenAIDashboardIfAvailable( usage: self.makeUsage(email: "work@company.com"), sourceLabel: "codex-cli", context: cliContext) #expect(restored == nil) #expect(OpenAIDashboardCacheStore.load() == nil) } } @Test func `worked example C unresolved but proven continuity attaches in app and CLI`() async { await self.withIsolatedDashboardCache { OpenAIDashboardCacheStore.clear() defer { OpenAIDashboardCacheStore.clear() } let emptyHome = self.makeEmptyHome() defer { try? FileManager.default.removeItem(at: emptyHome) } let store = self.makeAppStore(suite: "CodexDashboardWorkedExampleParityTests-example-c") store.settings._test_codexReconciliationEnvironment = ["CODEX_HOME": emptyHome.path] store.settings._test_liveSystemCodexAccount = nil store.settings.codexActiveSource = .liveSystem store._setSnapshotForTesting( self.codexSnapshot(email: "work@company.com", usedPercent: 12), provider: .codex) store.lastSourceLabels[.codex] = "codex-cli" let dashboard = self.makeDashboard( email: "work@company.com", creditsRemaining: 33, usedPercent: 12) let appAuthority = store.evaluateCodexDashboardAuthority( dashboard: dashboard, sourceKind: .liveWeb, routingTargetEmail: "work@company.com") await store.applyOpenAIDashboard(dashboard, targetEmail: "work@company.com") #expect(store.openAIDashboard?.signedInEmail == "work@company.com") #expect(store.credits?.remaining == 33) #expect(store.lastCreditsSource == .dashboardWeb) #expect(store.lastCodexAccountScopedRefreshGuard?.accountKey == "work@company.com") #expect(store.openAIDashboardRequiresLogin == false) #expect(store.lastOpenAIDashboardError == nil) let cliContext = self.makeCLIContext(authHome: emptyHome, knownOwners: []) OpenAIDashboardCacheStore.save(OpenAIDashboardCache( accountEmail: "stale-route@example.com", snapshot: dashboard)) let restored = CodexBarCLI.loadOpenAIDashboardIfAvailable( usage: self.makeUsage(email: "work@company.com"), sourceLabel: "codex-cli", context: cliContext) let cliInput = CodexCLIDashboardAuthorityContext.makeCachedDashboardInput( dashboard: dashboard, cachedAccountEmail: "stale-route@example.com", usage: self.makeUsage(email: "work@company.com"), sourceLabel: "codex-cli", context: cliContext) let cliDecision = CodexDashboardAuthority.evaluate(cliInput) #expect(restored == dashboard) #expect(appAuthority.decision.disposition == .attach) #expect(cliDecision.disposition == .attach) #expect(appAuthority.decision.reason == .trustedContinuityNoCompetingOwner) #expect(cliDecision.reason == .trustedContinuityNoCompetingOwner) } } @Test func `worked example D prior attach downgrades to ambiguity and retires old owned state`() async throws { try await self.withIsolatedDashboardCache { OpenAIDashboardCacheStore.clear() defer { OpenAIDashboardCacheStore.clear() } let store = self.makeAppStore(suite: "CodexDashboardWorkedExampleParityTests-example-d") store.settings._test_liveSystemCodexAccount = self.liveAccount( email: "shared@example.com", identity: .emailOnly(normalizedEmail: "shared@example.com")) store.settings.codexActiveSource = .liveSystem let initialDashboard = self.makeDashboard( email: "shared@example.com", creditsRemaining: 21, usedPercent: 18) await store.applyOpenAIDashboard(initialDashboard, targetEmail: "shared@example.com") #expect(store.openAIDashboard?.signedInEmail == "shared@example.com") #expect(store.snapshots[.codex]?.accountEmail(for: .codex) == "shared@example.com") #expect(store.credits?.remaining == 21) #expect(store.lastSourceLabels[.codex] == "openai-web") #expect(OpenAIDashboardCacheStore.load()?.accountEmail == "shared@example.com") let managedHome = try self.makeAuthHome( email: "shared@example.com", accountId: "acct-managed") defer { try? FileManager.default.removeItem(at: managedHome) } let managedAccount = ManagedCodexAccount( id: UUID(), email: "shared@example.com", managedHomePath: managedHome.path, createdAt: 1, updatedAt: 1, lastAuthenticatedAt: 1) let managedStoreURL = try self.makeManagedAccountStoreURL(accounts: [managedAccount]) defer { try? FileManager.default.removeItem(at: managedStoreURL) } store.settings._test_managedCodexAccountStoreURL = managedStoreURL await store.applyOpenAIDashboard( self.makeDashboard( email: "shared@example.com", creditsRemaining: 9, usedPercent: 35, includeUsageBreakdown: true), targetEmail: "shared@example.com") #expect(store.openAIDashboard?.signedInEmail == "shared@example.com") #expect(store.lastOpenAIDashboardSnapshot?.signedInEmail == "shared@example.com") #expect(store.snapshots[.codex] == nil) #expect(store.credits == nil) #expect(store.lastCreditsSource == .none) #expect(OpenAIDashboardCacheStore.load() == nil) OpenAIDashboardCacheStore.clear() let cliAuthHome = try self.makeAuthHome(email: "shared@example.com") defer { try? FileManager.default.removeItem(at: cliAuthHome) } let attachableContext = self.makeCLIContext( authHome: cliAuthHome, knownOwners: [ CodexDashboardKnownOwnerCandidate( identity: .providerAccount(id: "acct-alpha"), normalizedEmail: "shared@example.com"), ]) OpenAIDashboardCacheStore.save(OpenAIDashboardCache( accountEmail: "shared@example.com", snapshot: initialDashboard)) let initiallyRestored = CodexBarCLI.loadOpenAIDashboardIfAvailable( usage: self.makeUsage(email: "shared@example.com"), sourceLabel: "codex-cli", context: attachableContext) #expect(initiallyRestored == initialDashboard) let ambiguousContext = self.makeCLIContext( authHome: cliAuthHome, knownOwners: [ CodexDashboardKnownOwnerCandidate( identity: .providerAccount(id: "acct-alpha"), normalizedEmail: "shared@example.com"), CodexDashboardKnownOwnerCandidate( identity: .providerAccount(id: "acct-beta"), normalizedEmail: "shared@example.com"), ]) let downgradedRestored = CodexBarCLI.loadOpenAIDashboardIfAvailable( usage: self.makeUsage(email: "shared@example.com"), sourceLabel: "codex-cli", context: ambiguousContext) #expect(downgradedRestored == nil) #expect(OpenAIDashboardCacheStore.load() == nil) } } private func withIsolatedDashboardCache( _ operation: () async throws -> T) async rethrows -> T { let cacheURL = FileManager.default.temporaryDirectory .appendingPathComponent("codexbar-dashboard-\(UUID().uuidString).json") defer { try? FileManager.default.removeItem(at: cacheURL) } return try await OpenAIDashboardCacheStore.$cacheURLOverride.withValue(cacheURL) { try await operation() } } private func makeDashboard( email: String, creditsRemaining: Double, usedPercent: Double, includeUsageBreakdown: Bool = false) -> OpenAIDashboardSnapshot { let updatedAt = Date(timeIntervalSince1970: 2000) let creditEvents = [ CreditEvent( date: Date(timeIntervalSince1970: 1000), service: "codex", creditsUsed: 3), ] let usageBreakdown = includeUsageBreakdown ? self.makeUsageBreakdown(endingAt: updatedAt, days: 35, dailyCredits: 10) : [] return OpenAIDashboardSnapshot( signedInEmail: email, codeReviewRemainingPercent: 75, codeReviewLimit: RateWindow( usedPercent: 25, windowMinutes: 60, resetsAt: Date(timeIntervalSince1970: 3600), resetDescription: nil), creditEvents: creditEvents, dailyBreakdown: OpenAIDashboardSnapshot.makeDailyBreakdown(from: creditEvents, maxDays: 30), usageBreakdown: usageBreakdown, creditsPurchaseURL: nil, primaryLimit: RateWindow( usedPercent: usedPercent, windowMinutes: 300, resetsAt: Date(timeIntervalSince1970: 7200), resetDescription: nil), secondaryLimit: includeUsageBreakdown ? RateWindow( usedPercent: usedPercent, windowMinutes: 10080, resetsAt: updatedAt.addingTimeInterval(2 * 24 * 60 * 60), resetDescription: nil) : nil, creditsRemaining: creditsRemaining, accountPlan: "pro", updatedAt: updatedAt) } private func makeAppStore(suite: String) -> UsageStore { let defaults = UserDefaults(suiteName: suite)! defaults.removePersistentDomain(forName: suite) let settings = SettingsStore( userDefaults: defaults, configStore: testConfigStore(suiteName: suite), zaiTokenStore: NoopZaiTokenStore(), syntheticTokenStore: NoopSyntheticTokenStore()) settings._test_activeManagedCodexAccount = nil settings._test_activeManagedCodexRemoteHomePath = nil settings._test_unreadableManagedCodexAccountStore = false settings._test_managedCodexAccountStoreURL = nil settings._test_liveSystemCodexAccount = nil settings._test_codexReconciliationEnvironment = nil settings.historicalTrackingEnabled = true let historyURL = FileManager.default.temporaryDirectory .appendingPathComponent(UUID().uuidString) .appendingPathComponent("usage-history.jsonl") let planStore = testPlanUtilizationHistoryStore( suiteName: "CodexDashboardWorkedExampleParityTests-\(UUID().uuidString)") let store = UsageStore( fetcher: UsageFetcher(environment: [:]), browserDetection: BrowserDetection(cacheTTL: 0), settings: settings, historicalUsageHistoryStore: HistoricalUsageHistoryStore(fileURL: historyURL), planUtilizationHistoryStore: planStore) store._cancelPlanUtilizationHistoryLoadForTesting() return store } private func makeCLIContext( authHome: URL?, knownOwners: [CodexDashboardKnownOwnerCandidate]) -> ProviderFetchContext { let env = authHome.map { ["CODEX_HOME": $0.path] } ?? [:] let browserDetection = BrowserDetection(cacheTTL: 0) return ProviderFetchContext( runtime: .cli, sourceMode: .auto, includeCredits: true, webTimeout: 60, webDebugDumpHTML: false, verbose: false, env: env, settings: ProviderSettingsSnapshot.make( codex: .init( usageDataSource: .auto, cookieSource: .auto, manualCookieHeader: nil, dashboardAuthorityKnownOwners: knownOwners)), fetcher: UsageFetcher(environment: env), claudeFetcher: ClaudeUsageFetcher(browserDetection: browserDetection), browserDetection: browserDetection) } private func makeAuthHome(email: String?, accountId: String? = nil) throws -> URL { let homeURL = FileManager.default.temporaryDirectory.appendingPathComponent( UUID().uuidString, isDirectory: true) try self.writeCodexAuthFile(homeURL: homeURL, email: email, accountId: accountId) return homeURL } private func makeEmptyHome() -> URL { let homeURL = FileManager.default.temporaryDirectory.appendingPathComponent( UUID().uuidString, isDirectory: true) try? FileManager.default.createDirectory(at: homeURL, withIntermediateDirectories: true) return homeURL } private func writeCodexAuthFile( homeURL: URL, email: String?, accountId: String?) throws { try FileManager.default.createDirectory(at: homeURL, withIntermediateDirectories: true) var tokens: [String: Any] = [ "accessToken": "access-token", "refreshToken": "refresh-token", "idToken": Self.fakeJWT(email: email, accountId: accountId), ] if let accountId { tokens["accountId"] = accountId } let auth = ["tokens": tokens] let data = try JSONSerialization.data(withJSONObject: auth) try data.write(to: homeURL.appendingPathComponent("auth.json")) } private static func fakeJWT(email: String?, accountId: String?) -> String { let header = (try? JSONSerialization.data(withJSONObject: ["alg": "none"])) ?? Data() var authClaims: [String: Any] = [ "chatgpt_plan_type": "pro", ] if let accountId { authClaims["chatgpt_account_id"] = accountId } var claims: [String: Any] = [ "chatgpt_plan_type": "pro", "https://api.openai.com/auth": authClaims, ] if let email { claims["email"] = email } let payload = (try? JSONSerialization.data(withJSONObject: claims)) ?? Data() func base64URL(_ data: Data) -> String { data.base64EncodedString() .replacingOccurrences(of: "=", with: "") .replacingOccurrences(of: "+", with: "-") .replacingOccurrences(of: "/", with: "_") } return "\(base64URL(header)).\(base64URL(payload))." } private func makeManagedAccountStoreURL(accounts: [ManagedCodexAccount]) throws -> URL { let storeURL = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) let store = FileManagedCodexAccountStore(fileURL: storeURL) try store.storeAccounts(ManagedCodexAccountSet( version: FileManagedCodexAccountStore.currentVersion, accounts: accounts)) return storeURL } private func liveAccount(email: String, identity: CodexIdentity = .unresolved) -> ObservedSystemCodexAccount { ObservedSystemCodexAccount( email: email, codexHomePath: "/Users/test/.codex", observedAt: Date(), identity: identity) } private func codexSnapshot(email: String, usedPercent: Double) -> UsageSnapshot { UsageSnapshot( primary: RateWindow( usedPercent: usedPercent, windowMinutes: 300, resetsAt: nil, resetDescription: nil), secondary: nil, updatedAt: Date(timeIntervalSince1970: 2000), identity: ProviderIdentitySnapshot( providerID: .codex, accountEmail: email, accountOrganization: nil, loginMethod: "Pro")) } private func credits(remaining: Double) -> CreditsSnapshot { CreditsSnapshot(remaining: remaining, events: [], updatedAt: Date(timeIntervalSince1970: 2000)) } private func makeUsage(email: String?) -> UsageSnapshot { UsageSnapshot( primary: RateWindow( usedPercent: 10, windowMinutes: 300, resetsAt: Date(timeIntervalSince1970: 7200), resetDescription: nil), secondary: nil, updatedAt: Date(timeIntervalSince1970: 2000), identity: ProviderIdentitySnapshot( providerID: .codex, accountEmail: email, accountOrganization: nil, loginMethod: nil)) } private func makeUsageBreakdown( endingAt endDate: Date, days: Int, dailyCredits: Double) -> [OpenAIDashboardDailyBreakdown] { let formatter = DateFormatter() formatter.locale = Locale(identifier: "en_US_POSIX") formatter.timeZone = .current formatter.dateFormat = "yyyy-MM-dd" let calendar = Calendar(identifier: .gregorian) let endDay = calendar.startOfDay(for: endDate) return (0..