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

274 lines
13 KiB
Swift

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