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", updatedAt: Date()))) await refreshTask.value #expect(await blocker.startedCount() == 2) #expect(allowNavigationTimeoutRetries == [true, true]) #expect(store.openAIDashboard?.creditsRemaining == 25) #expect(store.lastOpenAIDashboardError == nil) } @Test func `background navigation timeout skips immediate WebKit retry`() async throws { let settings = try self.makeSettingsStore( suite: "CodexManagedOpenAIWebRefreshTests-background-timeout-no-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: false, expectedGuard: expectedGuard) } await blocker.waitUntilStarted(count: 1) await blocker.resumeNext(with: .failure(URLError(.timedOut))) await refreshTask.value #expect(await blocker.startedCount() == 1) #expect(allowNavigationTimeoutRetries == [false]) #expect(await importTracker.callCount() == 0) #expect(store.openAIDashboard == nil) #expect(store.lastOpenAIDashboardError?.contains("timed out") == true) } @Test func `reset open A I web state blocks stale in flight dashboard completion`() async throws { let settings = try self.makeSettingsStore(suite: "CodexManagedOpenAIWebRefreshTests-reset-invalidates-task") 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() store._test_openAIDashboardLoaderOverride = { _, _, _, _ in try await blocker.awaitResult() } defer { store._test_openAIDashboardLoaderOverride = nil } let expectedGuard = store.currentCodexOpenAIWebRefreshGuard() let refreshTask = Task { await store.refreshOpenAIDashboardIfNeeded(force: true, expectedGuard: expectedGuard) } await blocker.waitUntilStarted() store.resetOpenAIWebState() #expect(store.openAIDashboardRefreshTaskToken == nil) await blocker.resumeNext(with: .success(OpenAIDashboardSnapshot( signedInEmail: managedAccount.email, codeReviewRemainingPercent: 85, creditEvents: [], dailyBreakdown: [], usageBreakdown: [], creditsPurchaseURL: nil, creditsRemaining: 12, accountPlan: "Pro", updatedAt: Date()))) await refreshTask.value #expect(store.openAIDashboard == nil) #expect(store.lastOpenAIDashboardError == nil) } @Test func `active refresh failure ignores stale import status from older task`() async throws { let settings = try self.makeSettingsStore(suite: "CodexManagedOpenAIWebRefreshTests-concurrent-import-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 `post import retry timeout exceeds normal retry timeout`() { #expect(UsageStore.openAIWebDashboardFetchTimeout(didImportCookies: false) == 25) #expect(UsageStore.openAIWebDashboardFetchTimeout(didImportCookies: true) == 25) #expect(UsageStore.openAIWebRetryDashboardFetchTimeout(afterCookieImport: false) == 8) #expect(UsageStore.openAIWebRetryDashboardFetchTimeout(afterCookieImport: true) == 25) } private func makeSettingsStore(suite: String) throws -> SettingsStore { let settings = testSettingsStore(suiteName: suite) let codexMetadata = try #require(ProviderDescriptorRegistry.metadata[.codex]) settings.setProviderEnabled(provider: .codex, metadata: codexMetadata, enabled: true) settings.providerDetectionCompleted = true settings.openAIWebAccessEnabled = true settings.codexCookieSource = .auto return settings } private static func writeCodexAuthFile(homeURL: URL, email: String, plan: String, accountId: String? = nil) throws { try FileManager.default.createDirectory(at: homeURL, withIntermediateDirectories: true) var tokens: [String: Any] = [ "accessToken": "access-token", "refreshToken": "refresh-token", "idToken": Self.fakeJWT(email: email, plan: plan, accountId: accountId), ] if let accountId { tokens["accountId"] = accountId } let data = try JSONSerialization.data(withJSONObject: ["tokens": tokens], options: [.sortedKeys]) try data.write(to: homeURL.appendingPathComponent("auth.json")) } private static func fakeJWT(email: String, plan: String, accountId: String? = nil) -> String { let header = (try? JSONSerialization.data(withJSONObject: ["alg": "none"])) ?? Data() var authClaims: [String: Any] = [ "chatgpt_plan_type": plan, ] if let accountId { authClaims["chatgpt_account_id"] = accountId } let payload = (try? JSONSerialization.data(withJSONObject: [ "email": email, "chatgpt_plan_type": plan, "https://api.openai.com/auth": authClaims, ])) ?? Data() func base64URL(_ data: Data) -> String { data.base64EncodedString() .replacingOccurrences(of: "=", with: "") .replacingOccurrences(of: "+", with: "-") .replacingOccurrences(of: "/", with: "_") } return "\(base64URL(header)).\(base64URL(payload))." } private static func codexSnapshot(email: String, usedPercent: Double) -> UsageSnapshot { UsageSnapshot( primary: RateWindow(usedPercent: usedPercent, windowMinutes: 300, resetsAt: nil, resetDescription: nil), secondary: nil, updatedAt: Date(), identity: ProviderIdentitySnapshot( providerID: .codex, accountEmail: email, accountOrganization: nil, loginMethod: "Pro")) } } private enum ManagedDashboardTestError: LocalizedError { case networkTimeout var errorDescription: String? { switch self { case .networkTimeout: "Network timeout" } } } actor RefreshCompletionProbe { private(set) var isCompleted = false func markCompleted() { self.isCompleted = true } func waitUntilCompleted(timeout: Duration = .seconds(5)) async -> Bool { let startedAt = ContinuousClock.now while !self.isCompleted { if startedAt.duration(to: .now) >= timeout { return false } try? await Task.sleep(for: .milliseconds(50)) } return true } } actor BlockingManagedOpenAIDashboardLoader { private typealias ResultContinuation = CheckedContinuation, Never> private var continuations: [(id: UUID, continuation: ResultContinuation)] = [] private var startWaiters: [(count: Int, continuation: CheckedContinuation)] = [] private var started: Int = 0 private var cancelledIDs: Set = [] private var rejectsNewCalls = false func awaitResult() async throws -> OpenAIDashboardSnapshot { let id = UUID() let result = await withTaskCancellationHandler { await withCheckedContinuation { (continuation: ResultContinuation) in if self.rejectsNewCalls || Task.isCancelled { continuation.resume(returning: .failure(CancellationError())) } else { self.continuations.append((id: id, continuation: continuation)) self.started += 1 self.resumeReadyStartWaiters() } } } onCancel: { Task { await self.cancel(id: id) } } return try result.get() } func waitUntilStarted(count: Int = 1) async { if self.started >= count { return } await withCheckedContinuation { continuation in self.startWaiters.append((count: count, continuation: continuation)) } } func waitUntilStartedWithin(count: Int = 1, timeout: Duration = .seconds(5)) async -> Bool { let startedAt = ContinuousClock.now while self.started < count { if startedAt.duration(to: .now) >= timeout { return false } try? await Task.sleep(for: .milliseconds(50)) } return true } func startedCount() -> Int { self.started } func resumeNext(with result: Result) { guard !self.continuations.isEmpty else { return } let record = self.continuations.removeFirst() self.cancelledIDs.remove(record.id) record.continuation.resume(returning: result) } func cancelAll() { self.rejectsNewCalls = true let continuations = self.continuations self.continuations.removeAll() self.cancelledIDs.removeAll() continuations.forEach { $0.continuation.resume(returning: .failure(CancellationError())) } } private func resumeReadyStartWaiters() { var remaining: [(count: Int, continuation: CheckedContinuation)] = [] for waiter in self.startWaiters { if self.started >= waiter.count { waiter.continuation.resume() } else { remaining.append(waiter) } } self.startWaiters = remaining } private func cancel(id: UUID) { guard self.continuations.contains(where: { $0.id == id }) else { return } _ = self.cancelledIDs.insert(id) } } actor BlockingCreditsLoader { private typealias ResultContinuation = CheckedContinuation, Never> private var continuations: [(id: UUID, continuation: ResultContinuation)] = [] private var startWaiters: [(count: Int, continuation: CheckedContinuation)] = [] private var started = 0 private var cancellations = 0 private var cancelledIDs: Set = [] private var rejectsNewCalls = false func awaitResult() async throws -> CreditsSnapshot { let id = UUID() let result = await withTaskCancellationHandler { await withCheckedContinuation { (continuation: ResultContinuation) in if self.rejectsNewCalls || Task.isCancelled { continuation.resume(returning: .failure(CancellationError())) } else { self.continuations.append((id: id, continuation: continuation)) self.started += 1 self.resumeReadyStartWaiters() } } } onCancel: { Task { await self.cancel(id: id) } } return try result.get() } func waitUntilStarted(count: Int = 1) async { if self.started >= count { return } await withCheckedContinuation { continuation in self.startWaiters.append((count: count, continuation: continuation)) } } func waitUntilStartedWithin(count: Int = 1, timeout: Duration = .seconds(5)) async -> Bool { let deadline = ContinuousClock.now + timeout while self.started < count { if ContinuousClock.now >= deadline { return false } try? await Task.sleep(for: .milliseconds(50)) } return true } func startedCount() -> Int { self.started } func cancellationCount() -> Int { self.cancellations } func waitUntilCancellationCount(_ count: Int, timeout: Duration = .seconds(5)) async -> Bool { let deadline = ContinuousClock.now + timeout while self.cancellations < count { if ContinuousClock.now >= deadline { return false } try? await Task.sleep(for: .milliseconds(50)) } return true } func resumeNext(with result: Result) { guard !self.continuations.isEmpty else { return } let record = self.continuations.removeFirst() self.cancelledIDs.remove(record.id) record.continuation.resume(returning: result) } func resumeLast(with result: Result) { guard !self.continuations.isEmpty else { return } let record = self.continuations.removeLast() self.cancelledIDs.remove(record.id) record.continuation.resume(returning: result) } func cancelAll() { self.rejectsNewCalls = true let continuations = self.continuations self.continuations.removeAll() self.cancelledIDs.removeAll() continuations.forEach { $0.continuation.resume(returning: .failure(CancellationError())) } } private func resumeReadyStartWaiters() { var remaining: [(count: Int, continuation: CheckedContinuation)] = [] for waiter in self.startWaiters { if self.started >= waiter.count { waiter.continuation.resume() } else { remaining.append(waiter) } } self.startWaiters = remaining } private func cancel(id: UUID) { guard self.continuations.contains(where: { $0.id == id }), self.cancelledIDs.insert(id).inserted else { return } self.cancellations += 1 } } private actor OpenAIDashboardImportCallTracker { private var calls: Int = 0 private var waiters: [(count: Int, continuation: CheckedContinuation)] = [] func recordCall() -> Int { self.calls += 1 self.resumeReadyWaiters() return self.calls } func waitUntilCalls(count: Int) async { if self.calls >= count { return } await withCheckedContinuation { continuation in self.waiters.append((count: count, continuation: continuation)) } } func callCount() -> Int { self.calls } private func resumeReadyWaiters() { var remaining: [(count: Int, continuation: CheckedContinuation)] = [] for waiter in self.waiters { if self.calls >= waiter.count { waiter.continuation.resume() } else { remaining.append(waiter) } } self.waiters = remaining } }