import Foundationimport Testing@testable import CodexBar@testable import CodexBarCore @Suite(.serialized)@MainActorstruct CodexManagedOpenAIWebRefreshTests { @Test func `regular refresh does not await OpenAI web scrape`() async throws { let settings = try self .makeSettingsStore(suite: "CodexManagedOpenAIWebRefreshTests-regular-refresh-nonblocking") settings.statusChecksEnabled = false if let codexMeta = ProviderRegistry.shared.metadata[.codex] { settings.setProviderEnabled(provider: .codex, metadata: codexMeta, enabled: true) } let managedHomeURL = FileManager.default.temporaryDirectory .appendingPathComponent(UUID().uuidString, isDirectory: true) try? Self.writeCodexAuthFile( homeURL: managedHomeURL, email: "managed@example.com", plan: "Pro") defer { try? FileManager.default.removeItem(at: managedHomeURL) } let managedAccount = ManagedCodexAccount( id: UUID(), email: "managed@example.com", managedHomePath: managedHomeURL.path, createdAt: 1, updatedAt: 1, lastAuthenticatedAt: 1) settings._test_activeManagedCodexAccount = managedAccount settings.codexActiveSource = .managedAccount(id: managedAccount.id) settings.openAIWebAccessEnabled = false defer { settings._test_activeManagedCodexAccount = nil } let store = UsageStore( fetcher: UsageFetcher(environment: [:]), browserDetection: BrowserDetection(cacheTTL: 0), settings: settings, startupBehavior: .testing) let blocker = BlockingManagedOpenAIDashboardLoader() let completion = RefreshCompletionProbe() store._test_providerRefreshOverride = { _ in } defer { store._test_providerRefreshOverride = nil } store._test_codexCreditsLoaderOverride = { CreditsSnapshot(remaining: 25, events: [], updatedAt: Date()) } defer { store._test_codexCreditsLoaderOverride = nil } await store.refresh(forceTokenUsage: false) settings.openAIWebAccessEnabled = true store._test_openAIDashboardLoaderOverride = { _, _, _, _ in try await blocker.awaitResult() } defer { store._test_openAIDashboardLoaderOverride = nil } store._test_openAIDashboardCookieImportOverride = { targetEmail, _, _, _, _ in OpenAIDashboardBrowserCookieImporter.ImportResult( sourceLabel: "Chrome", cookieCount: 2, signedInEmail: targetEmail, matchesCodexEmail: true) } defer { store._test_openAIDashboardCookieImportOverride = nil } let refreshTask = Task { await store.refresh(forceTokenUsage: false) await completion.markCompleted() } let didStart = await blocker.waitUntilStartedWithin(count: 1, timeout: .seconds(60)) #expect(didStart == true) if !didStart { refreshTask.cancel() return } let completed = await completion.waitUntilCompleted(timeout: .seconds(2)) #expect(completed == true) if !completed { refreshTask.cancel() await blocker.resumeNext(with: .failure(ManagedDashboardTestError.networkTimeout)) return } await refreshTask.value let backgroundTask = try #require(store.openAIDashboardBackgroundRefreshTask) #expect(await blocker.startedCount() == 1) await blocker.resumeNext(with: .success(OpenAIDashboardSnapshot( signedInEmail: managedAccount.email, codeReviewRemainingPercent: 95, creditEvents: [], dailyBreakdown: [], usageBreakdown: [], creditsPurchaseURL: nil, creditsRemaining: 25, accountPlan: "Pro", updatedAt: Date()))) await backgroundTask.value } @Test func `regular refresh does not await Codex credits fetch`() async throws { let settings = try self.makeSettingsStore( suite: "CodexManagedOpenAIWebRefreshTests-regular-refresh-nonblocking-credits") settings.statusChecksEnabled = false settings.openAIWebAccessEnabled = false if let codexMeta = ProviderRegistry.shared.metadata[.codex] { settings.setProviderEnabled(provider: .codex, metadata: codexMeta, enabled: true) } let managedHomeURL = FileManager.default.temporaryDirectory .appendingPathComponent(UUID().uuidString, isDirectory: true) try? Self.writeCodexAuthFile( homeURL: managedHomeURL, email: "managed@example.com", plan: "Pro") defer { try? FileManager.default.removeItem(at: managedHomeURL) } let managedAccount = ManagedCodexAccount( id: UUID(), email: "managed@example.com", managedHomePath: managedHomeURL.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) let blocker = BlockingCreditsLoader() let completion = RefreshCompletionProbe() store._test_providerRefreshOverride = { _ in } defer { store._test_providerRefreshOverride = nil } store._test_codexCreditsLoaderOverride = { try await blocker.awaitResult() } defer { store._test_codexCreditsLoaderOverride = nil } let refreshTask = Task { await store.refresh(forceTokenUsage: false) await completion.markCompleted() } await blocker.waitUntilStarted(count: 1) #expect(await blocker.startedCount() == 1) #expect(await completion.isCompleted == true) await blocker.resumeNext(with: .success(CreditsSnapshot(remaining: 25, events: [], updatedAt: Date()))) await refreshTask.value } @Test func `background credits refresh persists updated widget snapshot after refresh returns`() async throws { let settings = try self.makeSettingsStore( suite: "CodexManagedOpenAIWebRefreshTests-widget-background-credits") settings.statusChecksEnabled = false settings.openAIWebAccessEnabled = false if let codexMeta = ProviderRegistry.shared.metadata[.codex] { settings.setProviderEnabled(provider: .codex, metadata: codexMeta, enabled: true) } let managedHomeURL = FileManager.default.temporaryDirectory .appendingPathComponent(UUID().uuidString, isDirectory: true) try? Self.writeCodexAuthFile( homeURL: managedHomeURL, email: "managed@example.com", plan: "Pro") defer { try? FileManager.default.removeItem(at: managedHomeURL) } let managedAccount = ManagedCodexAccount( id: UUID(), email: "managed@example.com", managedHomePath: managedHomeURL.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) store.snapshots[.codex] = Self.codexSnapshot(email: managedAccount.email, usedPercent: 18) let publicationGuard = store.currentCodexAccountScopedRefreshGuard() store.lastCodexUsagePublicationGuard = publicationGuard store.lastCodexAccountScopedRefreshGuard = publicationGuard let creditsBlocker = BlockingCreditsLoader() let saver = BlockingWidgetSnapshotSaver() store._test_providerRefreshOverride = { _ in } defer { store._test_providerRefreshOverride = nil } store._test_codexCreditsLoaderOverride = { try await creditsBlocker.awaitResult() } defer { store._test_codexCreditsLoaderOverride = nil } store._test_widgetSnapshotSaveOverride = { snapshot in await saver.save(snapshot) } defer { store._test_widgetSnapshotSaveOverride = nil } let refreshTask = Task { await store.refresh(forceTokenUsage: false) } await refreshTask.value await saver.waitUntilStarted(count: 1) let firstSnapshots = await saver.savedSnapshots() let firstCodexEntry = try #require(firstSnapshots.first?.entries.first { $0.provider == .codex }) #expect(firstCodexEntry.creditsRemaining == nil) await saver.resumeNext() let backgroundTask = try #require(store.creditsRefreshTask) await creditsBlocker.waitUntilStarted(count: 1) await creditsBlocker.resumeNext(with: .success(CreditsSnapshot(remaining: 25, events: [], updatedAt: Date()))) await backgroundTask.value await saver.waitUntilStarted(count: 2) #expect(await saver.startedCount() == 2) let secondSnapshots = await saver.savedSnapshots() let secondCodexEntry = try #require(secondSnapshots.last?.entries.first { $0.provider == .codex }) #expect(secondCodexEntry.creditsRemaining == 25) await saver.resumeNext() await store.widgetSnapshotPersistTask?.value } @Test func `background dashboard refresh persists updated widget snapshot after refresh returns`() async throws { let settings = try self.makeSettingsStore( suite: "CodexManagedOpenAIWebRefreshTests-widget-background-dashboard") settings.statusChecksEnabled = false if let codexMeta = ProviderRegistry.shared.metadata[.codex] { settings.setProviderEnabled(provider: .codex, metadata: codexMeta, enabled: true) } let managedHomeURL = FileManager.default.temporaryDirectory .appendingPathComponent(UUID().uuidString, isDirectory: true) try? Self.writeCodexAuthFile( homeURL: managedHomeURL, email: "managed@example.com", plan: "Pro") defer { try? FileManager.default.removeItem(at: managedHomeURL) } let managedAccount = ManagedCodexAccount( id: UUID(), email: "managed@example.com", managedHomePath: managedHomeURL.path, createdAt: 1, updatedAt: 1, lastAuthenticatedAt: 1) settings._test_activeManagedCodexAccount = managedAccount settings.codexActiveSource = .managedAccount(id: managedAccount.id) settings.openAIWebAccessEnabled = false defer { settings._test_activeManagedCodexAccount = nil } let store = UsageStore( fetcher: UsageFetcher(environment: [:]), browserDetection: BrowserDetection(cacheTTL: 0), settings: settings, startupBehavior: .testing) let dashboardBlocker = BlockingManagedOpenAIDashboardLoader() let saver = RecordingWidgetSnapshotSaver() store._test_providerRefreshOverride = { _ in } defer { store._test_providerRefreshOverride = nil } store._test_codexCreditsLoaderOverride = { CreditsSnapshot(remaining: 25, events: [], updatedAt: Date()) } defer { store._test_codexCreditsLoaderOverride = nil } await store.refresh(forceTokenUsage: false) await store.widgetSnapshotPersistTask?.value settings.openAIWebAccessEnabled = true store.snapshots[.codex] = Self.codexSnapshot(email: managedAccount.email, usedPercent: 18) let publicationGuard = store.currentCodexAccountScopedRefreshGuard() store.lastCodexUsagePublicationGuard = publicationGuard store.lastCodexAccountScopedRefreshGuard = publicationGuard store.creditsRefreshTask = Task {} store.creditsRefreshTaskKey = store.codexCreditsRefreshKey( expectedGuard: store.currentCodexAccountScopedRefreshGuard()) store._test_openAIDashboardLoaderOverride = { _, _, _, _ in try await dashboardBlocker.awaitResult() } defer { store._test_openAIDashboardLoaderOverride = nil } store._test_widgetSnapshotSaveOverride = { snapshot in await saver.save(snapshot) } defer { store._test_widgetSnapshotSaveOverride = nil } let refreshTask = Task { await store.refresh(forceTokenUsage: false) } await refreshTask.value let didPersistInitialRefreshSnapshot = await saver.waitUntilSavedWithin(count: 1) #expect(didPersistInitialRefreshSnapshot) let firstSnapshots = await saver.savedSnapshots() #expect(firstSnapshots.first?.entries.first { $0.provider == .codex }?.codeReviewRemainingPercent == nil) let backgroundTask = try #require(store.openAIDashboardBackgroundRefreshTask) let didStartDashboardRefresh = await dashboardBlocker.waitUntilStartedWithin(count: 1) #expect(didStartDashboardRefresh) if didStartDashboardRefresh { await dashboardBlocker.resumeNext(with: .success(OpenAIDashboardSnapshot( signedInEmail: managedAccount.email, codeReviewRemainingPercent: 95, creditEvents: [], dailyBreakdown: [], usageBreakdown: [], creditsPurchaseURL: nil, creditsRemaining: 25, accountPlan: "Pro", updatedAt: Date()))) await backgroundTask.value } let didPersistDashboardSnapshot = await saver.waitUntilSavedWithin(count: 2) #expect(didPersistDashboardSnapshot) let secondSnapshots = await saver.savedSnapshots() #expect(secondSnapshots.count >= 2) } @Test func `manual cookie import bypasses same account refresh coalescing`() async throws { let settings = try self.makeSettingsStore( suite: "CodexManagedOpenAIWebRefreshTests-manual-import-bypass-coalesce") let managedHome = FileManager.default.temporaryDirectory .appendingPathComponent("codex-managed-openai-web-refresh-\(UUID().uuidString)", isDirectory: true) try Self.writeCodexAuthFile( homeURL: managedHome, email: "managed@example.com", plan: "Pro") defer { try? FileManager.default.removeItem(at: managedHome) } let managedAccount = ManagedCodexAccount( id: UUID(), email: "managed@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) let blocker = BlockingManagedOpenAIDashboardLoader() store._test_openAIDashboardLoaderOverride = { _, _, _, _ in try await blocker.awaitResult() } defer { store._test_openAIDashboardLoaderOverride = nil } store._test_openAIDashboardCookieImportOverride = { targetEmail, _, _, _, _ in OpenAIDashboardBrowserCookieImporter.ImportResult( sourceLabel: "Chrome", cookieCount: 2, signedInEmail: targetEmail, matchesCodexEmail: true) } defer { store._test_openAIDashboardCookieImportOverride = nil } let expectedGuard = store.currentCodexOpenAIWebRefreshGuard() let firstTask = Task { await store.refreshOpenAIDashboardIfNeeded(force: true, expectedGuard: expectedGuard) } await blocker.waitUntilStarted(count: 1) let manualImportTask = Task { await store.importOpenAIDashboardBrowserCookiesNow() } await blocker.waitUntilStarted(count: 2) await blocker.resumeNext(with: .success(OpenAIDashboardSnapshot( signedInEmail: managedAccount.email, codeReviewRemainingPercent: 70, creditEvents: [], dailyBreakdown: [], usageBreakdown: [], creditsPurchaseURL: nil, creditsRemaining: 1, accountPlan: "Free", updatedAt: Date()))) await blocker.resumeNext(with: .success(OpenAIDashboardSnapshot( signedInEmail: managedAccount.email, codeReviewRemainingPercent: 95, creditEvents: [], dailyBreakdown: [], usageBreakdown: [], creditsPurchaseURL: nil, creditsRemaining: 25, accountPlan: "Pro", updatedAt: Date()))) await firstTask.value await manualImportTask.value #expect(await blocker.startedCount() == 2) #expect(store.openAIDashboard?.creditsRemaining == 25) #expect(store.openAIDashboard?.accountPlan == "Pro") } @Test func `stale cookie import status does not override later unrelated refresh failure`() async throws { let settings = try self.makeSettingsStore(suite: "CodexManagedOpenAIWebRefreshTests-stale-cookie-status") 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) store.openAIDashboardCookieImportStatus = "OpenAI cookies are for other@example.com, not managed@example.com." store._test_openAIDashboardLoaderOverride = { _, _, _, _ in throw ManagedDashboardTestError.networkTimeout } defer { store._test_openAIDashboardLoaderOverride = nil } let expectedGuard = store.currentCodexOpenAIWebRefreshGuard() await store.refreshOpenAIDashboardIfNeeded(force: true, expectedGuard: expectedGuard) #expect(store.lastOpenAIDashboardError == ManagedDashboardTestError.networkTimeout.localizedDescription) } @Test func `navigation timeout imports cookies and retries dashboard refresh`() async throws { let settings = try self.makeSettingsStore(suite: "CodexManagedOpenAIWebRefreshTests-timeout-import-retry") 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 blocker = BlockingManagedOpenAIDashboardLoader() let importTracker = OpenAIDashboardImportCallTracker() var allowNavigationTimeoutRetries: [Bool] = [] store._test_openAIDashboardLoaderOverride = { _, _, allowNavigationTimeoutRetry, _ in allowNavigationTimeoutRetries.append(allowNavigationTimeoutRetry) return try await blocker.awaitResult() } defer { store._test_openAIDashboardLoaderOverride = nil } store._test_openAIDashboardCookieImportOverride = { targetEmail, _, _, _, _ in _ = await importTracker.recordCall() return OpenAIDashboardBrowserCookieImporter.ImportResult( sourceLabel: "Chrome", cookieCount: 2, signedInEmail: targetEmail, matchesCodexEmail: true) } defer { store._test_openAIDashboardCookieImportOverride = nil } let expectedGuard = store.currentCodexOpenAIWebRefreshGuard() let refreshTask = Task { await store.refreshOpenAIDashboardIfNeeded(force: true, expectedGuard: expectedGuard) } await blocker.waitUntilStarted(count: 1) await blocker.resumeNext(with: .failure(URLError(.timedOut))) await importTracker.waitUntilCalls(count: 1) await blocker.waitUntilStarted(count: 2) await blocker.resumeNext(with: .success(OpenAIDashboardSnapshot( signedInEmail: managedAccount.email, codeReviewRemainingPercent: 90, creditEvents: [], dailyBreakdown: [], usageBreakdown: [], creditsPurchaseURL: nil, creditsRemaining: 25, accountPlan: "Pro",Lines 1–500 of 972. Load more
import Foundation import Testing @testable import CodexBar @testable import CodexBarCore @Suite(.serialized) @MainActor struct CodexManagedOpenAIWebRefreshTests { @Test func `regular refresh does not await OpenAI web scrape`() async throws { let settings = try self .makeSettingsStore(suite: "CodexManagedOpenAIWebRefreshTests-regular-refresh-nonblocking") settings.statusChecksEnabled = false if let codexMeta = ProviderRegistry.shared.metadata[.codex] { settings.setProviderEnabled(provider: .codex, metadata: codexMeta, enabled: true) } let managedHomeURL = FileManager.default.temporaryDirectory .appendingPathComponent(UUID().uuidString, isDirectory: true) try? Self.writeCodexAuthFile( homeURL: managedHomeURL, email: "managed@example.com", plan: "Pro") defer { try? FileManager.default.removeItem(at: managedHomeURL) } let managedAccount = ManagedCodexAccount( id: UUID(), email: "managed@example.com", managedHomePath: managedHomeURL.path, createdAt: 1, updatedAt: 1, lastAuthenticatedAt: 1) settings._test_activeManagedCodexAccount = managedAccount settings.codexActiveSource = .managedAccount(id: managedAccount.id) settings.openAIWebAccessEnabled = false defer { settings._test_activeManagedCodexAccount = nil } let store = UsageStore( fetcher: UsageFetcher(environment: [:]), browserDetection: BrowserDetection(cacheTTL: 0), settings: settings, startupBehavior: .testing) let blocker = BlockingManagedOpenAIDashboardLoader() let completion = RefreshCompletionProbe() store._test_providerRefreshOverride = { _ in } defer { store._test_providerRefreshOverride = nil } store._test_codexCreditsLoaderOverride = { CreditsSnapshot(remaining: 25, events: [], updatedAt: Date()) } defer { store._test_codexCreditsLoaderOverride = nil } await store.refresh(forceTokenUsage: false) settings.openAIWebAccessEnabled = true store._test_openAIDashboardLoaderOverride = { _, _, _, _ in try await blocker.awaitResult() } defer { store._test_openAIDashboardLoaderOverride = nil } store._test_openAIDashboardCookieImportOverride = { targetEmail, _, _, _, _ in OpenAIDashboardBrowserCookieImporter.ImportResult( sourceLabel: "Chrome", cookieCount: 2, signedInEmail: targetEmail, matchesCodexEmail: true) } defer { store._test_openAIDashboardCookieImportOverride = nil } let refreshTask = Task { await store.refresh(forceTokenUsage: false) await completion.markCompleted() } let didStart = await blocker.waitUntilStartedWithin(count: 1, timeout: .seconds(60)) #expect(didStart == true) if !didStart { refreshTask.cancel() return } let completed = await completion.waitUntilCompleted(timeout: .seconds(2)) #expect(completed == true) if !completed { refreshTask.cancel() await blocker.resumeNext(with: .failure(ManagedDashboardTestError.networkTimeout)) return } await refreshTask.value let backgroundTask = try #require(store.openAIDashboardBackgroundRefreshTask) #expect(await blocker.startedCount() == 1) await blocker.resumeNext(with: .success(OpenAIDashboardSnapshot( signedInEmail: managedAccount.email, codeReviewRemainingPercent: 95, creditEvents: [], dailyBreakdown: [], usageBreakdown: [], creditsPurchaseURL: nil, creditsRemaining: 25, accountPlan: "Pro", updatedAt: Date()))) await backgroundTask.value } @Test func `regular refresh does not await Codex credits fetch`() async throws { let settings = try self.makeSettingsStore( suite: "CodexManagedOpenAIWebRefreshTests-regular-refresh-nonblocking-credits") settings.statusChecksEnabled = false settings.openAIWebAccessEnabled = false if let codexMeta = ProviderRegistry.shared.metadata[.codex] { settings.setProviderEnabled(provider: .codex, metadata: codexMeta, enabled: true) } let managedHomeURL = FileManager.default.temporaryDirectory .appendingPathComponent(UUID().uuidString, isDirectory: true) try? Self.writeCodexAuthFile( homeURL: managedHomeURL, email: "managed@example.com", plan: "Pro") defer { try? FileManager.default.removeItem(at: managedHomeURL) } let managedAccount = ManagedCodexAccount( id: UUID(), email: "managed@example.com", managedHomePath: managedHomeURL.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) let blocker = BlockingCreditsLoader() let completion = RefreshCompletionProbe() store._test_providerRefreshOverride = { _ in } defer { store._test_providerRefreshOverride = nil } store._test_codexCreditsLoaderOverride = { try await blocker.awaitResult() } defer { store._test_codexCreditsLoaderOverride = nil } let refreshTask = Task { await store.refresh(forceTokenUsage: false) await completion.markCompleted() } await blocker.waitUntilStarted(count: 1) #expect(await blocker.startedCount() == 1) #expect(await completion.isCompleted == true) await blocker.resumeNext(with: .success(CreditsSnapshot(remaining: 25, events: [], updatedAt: Date()))) await refreshTask.value } @Test func `background credits refresh persists updated widget snapshot after refresh returns`() async throws { let settings = try self.makeSettingsStore( suite: "CodexManagedOpenAIWebRefreshTests-widget-background-credits") settings.statusChecksEnabled = false settings.openAIWebAccessEnabled = false if let codexMeta = ProviderRegistry.shared.metadata[.codex] { settings.setProviderEnabled(provider: .codex, metadata: codexMeta, enabled: true) } let managedHomeURL = FileManager.default.temporaryDirectory .appendingPathComponent(UUID().uuidString, isDirectory: true) try? Self.writeCodexAuthFile( homeURL: managedHomeURL, email: "managed@example.com", plan: "Pro") defer { try? FileManager.default.removeItem(at: managedHomeURL) } let managedAccount = ManagedCodexAccount( id: UUID(), email: "managed@example.com", managedHomePath: managedHomeURL.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) store.snapshots[.codex] = Self.codexSnapshot(email: managedAccount.email, usedPercent: 18) let publicationGuard = store.currentCodexAccountScopedRefreshGuard() store.lastCodexUsagePublicationGuard = publicationGuard store.lastCodexAccountScopedRefreshGuard = publicationGuard let creditsBlocker = BlockingCreditsLoader() let saver = BlockingWidgetSnapshotSaver() store._test_providerRefreshOverride = { _ in } defer { store._test_providerRefreshOverride = nil } store._test_codexCreditsLoaderOverride = { try await creditsBlocker.awaitResult() } defer { store._test_codexCreditsLoaderOverride = nil } store._test_widgetSnapshotSaveOverride = { snapshot in await saver.save(snapshot) } defer { store._test_widgetSnapshotSaveOverride = nil } let refreshTask = Task { await store.refresh(forceTokenUsage: false) } await refreshTask.value await saver.waitUntilStarted(count: 1) let firstSnapshots = await saver.savedSnapshots() let firstCodexEntry = try #require(firstSnapshots.first?.entries.first { $0.provider == .codex }) #expect(firstCodexEntry.creditsRemaining == nil) await saver.resumeNext() let backgroundTask = try #require(store.creditsRefreshTask) await creditsBlocker.waitUntilStarted(count: 1) await creditsBlocker.resumeNext(with: .success(CreditsSnapshot(remaining: 25, events: [], updatedAt: Date()))) await backgroundTask.value await saver.waitUntilStarted(count: 2) #expect(await saver.startedCount() == 2) let secondSnapshots = await saver.savedSnapshots() let secondCodexEntry = try #require(secondSnapshots.last?.entries.first { $0.provider == .codex }) #expect(secondCodexEntry.creditsRemaining == 25) await saver.resumeNext() await store.widgetSnapshotPersistTask?.value } @Test func `background dashboard refresh persists updated widget snapshot after refresh returns`() async throws { let settings = try self.makeSettingsStore( suite: "CodexManagedOpenAIWebRefreshTests-widget-background-dashboard") settings.statusChecksEnabled = false if let codexMeta = ProviderRegistry.shared.metadata[.codex] { settings.setProviderEnabled(provider: .codex, metadata: codexMeta, enabled: true) } let managedHomeURL = FileManager.default.temporaryDirectory .appendingPathComponent(UUID().uuidString, isDirectory: true) try? Self.writeCodexAuthFile( homeURL: managedHomeURL, email: "managed@example.com", plan: "Pro") defer { try? FileManager.default.removeItem(at: managedHomeURL) } let managedAccount = ManagedCodexAccount( id: UUID(), email: "managed@example.com", managedHomePath: managedHomeURL.path, createdAt: 1, updatedAt: 1, lastAuthenticatedAt: 1) settings._test_activeManagedCodexAccount = managedAccount settings.codexActiveSource = .managedAccount(id: managedAccount.id) settings.openAIWebAccessEnabled = false defer { settings._test_activeManagedCodexAccount = nil } let store = UsageStore( fetcher: UsageFetcher(environment: [:]), browserDetection: BrowserDetection(cacheTTL: 0), settings: settings, startupBehavior: .testing) let dashboardBlocker = BlockingManagedOpenAIDashboardLoader() let saver = RecordingWidgetSnapshotSaver() store._test_providerRefreshOverride = { _ in } defer { store._test_providerRefreshOverride = nil } store._test_codexCreditsLoaderOverride = { CreditsSnapshot(remaining: 25, events: [], updatedAt: Date()) } defer { store._test_codexCreditsLoaderOverride = nil } await store.refresh(forceTokenUsage: false) await store.widgetSnapshotPersistTask?.value settings.openAIWebAccessEnabled = true store.snapshots[.codex] = Self.codexSnapshot(email: managedAccount.email, usedPercent: 18) let publicationGuard = store.currentCodexAccountScopedRefreshGuard() store.lastCodexUsagePublicationGuard = publicationGuard store.lastCodexAccountScopedRefreshGuard = publicationGuard store.creditsRefreshTask = Task {} store.creditsRefreshTaskKey = store.codexCreditsRefreshKey( expectedGuard: store.currentCodexAccountScopedRefreshGuard()) store._test_openAIDashboardLoaderOverride = { _, _, _, _ in try await dashboardBlocker.awaitResult() } defer { store._test_openAIDashboardLoaderOverride = nil } store._test_widgetSnapshotSaveOverride = { snapshot in await saver.save(snapshot) } defer { store._test_widgetSnapshotSaveOverride = nil } let refreshTask = Task { await store.refresh(forceTokenUsage: false) } await refreshTask.value let didPersistInitialRefreshSnapshot = await saver.waitUntilSavedWithin(count: 1) #expect(didPersistInitialRefreshSnapshot) let firstSnapshots = await saver.savedSnapshots() #expect(firstSnapshots.first?.entries.first { $0.provider == .codex }?.codeReviewRemainingPercent == nil) let backgroundTask = try #require(store.openAIDashboardBackgroundRefreshTask) let didStartDashboardRefresh = await dashboardBlocker.waitUntilStartedWithin(count: 1) #expect(didStartDashboardRefresh) if didStartDashboardRefresh { await dashboardBlocker.resumeNext(with: .success(OpenAIDashboardSnapshot( signedInEmail: managedAccount.email, codeReviewRemainingPercent: 95, creditEvents: [], dailyBreakdown: [], usageBreakdown: [], creditsPurchaseURL: nil, creditsRemaining: 25, accountPlan: "Pro", updatedAt: Date()))) await backgroundTask.value } let didPersistDashboardSnapshot = await saver.waitUntilSavedWithin(count: 2) #expect(didPersistDashboardSnapshot) let secondSnapshots = await saver.savedSnapshots() #expect(secondSnapshots.count >= 2) } @Test func `manual cookie import bypasses same account refresh coalescing`() async throws { let settings = try self.makeSettingsStore( suite: "CodexManagedOpenAIWebRefreshTests-manual-import-bypass-coalesce") let managedHome = FileManager.default.temporaryDirectory .appendingPathComponent("codex-managed-openai-web-refresh-\(UUID().uuidString)", isDirectory: true) try Self.writeCodexAuthFile( homeURL: managedHome, email: "managed@example.com", plan: "Pro") defer { try? FileManager.default.removeItem(at: managedHome) } let managedAccount = ManagedCodexAccount( id: UUID(), email: "managed@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) let blocker = BlockingManagedOpenAIDashboardLoader() store._test_openAIDashboardLoaderOverride = { _, _, _, _ in try await blocker.awaitResult() } defer { store._test_openAIDashboardLoaderOverride = nil } store._test_openAIDashboardCookieImportOverride = { targetEmail, _, _, _, _ in OpenAIDashboardBrowserCookieImporter.ImportResult( sourceLabel: "Chrome", cookieCount: 2, signedInEmail: targetEmail, matchesCodexEmail: true) } defer { store._test_openAIDashboardCookieImportOverride = nil } let expectedGuard = store.currentCodexOpenAIWebRefreshGuard() let firstTask = Task { await store.refreshOpenAIDashboardIfNeeded(force: true, expectedGuard: expectedGuard) } await blocker.waitUntilStarted(count: 1) let manualImportTask = Task { await store.importOpenAIDashboardBrowserCookiesNow() } await blocker.waitUntilStarted(count: 2) await blocker.resumeNext(with: .success(OpenAIDashboardSnapshot( signedInEmail: managedAccount.email, codeReviewRemainingPercent: 70, creditEvents: [], dailyBreakdown: [], usageBreakdown: [], creditsPurchaseURL: nil, creditsRemaining: 1, accountPlan: "Free", updatedAt: Date()))) await blocker.resumeNext(with: .success(OpenAIDashboardSnapshot( signedInEmail: managedAccount.email, codeReviewRemainingPercent: 95, creditEvents: [], dailyBreakdown: [], usageBreakdown: [], creditsPurchaseURL: nil, creditsRemaining: 25, accountPlan: "Pro", updatedAt: Date()))) await firstTask.value await manualImportTask.value #expect(await blocker.startedCount() == 2) #expect(store.openAIDashboard?.creditsRemaining == 25) #expect(store.openAIDashboard?.accountPlan == "Pro") } @Test func `stale cookie import status does not override later unrelated refresh failure`() async throws { let settings = try self.makeSettingsStore(suite: "CodexManagedOpenAIWebRefreshTests-stale-cookie-status") 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) store.openAIDashboardCookieImportStatus = "OpenAI cookies are for other@example.com, not managed@example.com." store._test_openAIDashboardLoaderOverride = { _, _, _, _ in throw ManagedDashboardTestError.networkTimeout } defer { store._test_openAIDashboardLoaderOverride = nil } let expectedGuard = store.currentCodexOpenAIWebRefreshGuard() await store.refreshOpenAIDashboardIfNeeded(force: true, expectedGuard: expectedGuard) #expect(store.lastOpenAIDashboardError == ManagedDashboardTestError.networkTimeout.localizedDescription) } @Test func `navigation timeout imports cookies and retries dashboard refresh`() async throws { let settings = try self.makeSettingsStore(suite: "CodexManagedOpenAIWebRefreshTests-timeout-import-retry") 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 blocker = BlockingManagedOpenAIDashboardLoader() let importTracker = OpenAIDashboardImportCallTracker() var allowNavigationTimeoutRetries: [Bool] = [] store._test_openAIDashboardLoaderOverride = { _, _, allowNavigationTimeoutRetry, _ in allowNavigationTimeoutRetries.append(allowNavigationTimeoutRetry) return try await blocker.awaitResult() } defer { store._test_openAIDashboardLoaderOverride = nil } store._test_openAIDashboardCookieImportOverride = { targetEmail, _, _, _, _ in _ = await importTracker.recordCall() return OpenAIDashboardBrowserCookieImporter.ImportResult( sourceLabel: "Chrome", cookieCount: 2, signedInEmail: targetEmail, matchesCodexEmail: true) } defer { store._test_openAIDashboardCookieImportOverride = nil } let expectedGuard = store.currentCodexOpenAIWebRefreshGuard() let refreshTask = Task { await store.refreshOpenAIDashboardIfNeeded(force: true, expectedGuard: expectedGuard) } await blocker.waitUntilStarted(count: 1) await blocker.resumeNext(with: .failure(URLError(.timedOut))) await importTracker.waitUntilCalls(count: 1) await blocker.waitUntilStarted(count: 2) await blocker.resumeNext(with: .success(OpenAIDashboardSnapshot( signedInEmail: managedAccount.email, codeReviewRemainingPercent: 90, creditEvents: [], dailyBreakdown: [], usageBreakdown: [], creditsPurchaseURL: nil, creditsRemaining: 25, accountPlan: "Pro",