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

180 lines
7.5 KiB
Swift

import AppKit
import CodexBarCore
import Foundation
import Testing
@testable import CodexBar
@MainActor
struct MenuCardOverrideIsolationTests {
@Test
func `nil snapshot account card does not inherit ambient Claude costs`() throws {
let suite = "MenuCardOverrideIsolationTests-\(UUID().uuidString)"
let defaults = try #require(UserDefaults(suiteName: suite))
defaults.removePersistentDomain(forName: suite)
let settings = SettingsStore(
userDefaults: defaults,
configStore: testConfigStore(suiteName: suite),
zaiTokenStore: NoopZaiTokenStore(),
syntheticTokenStore: NoopSyntheticTokenStore())
settings.costUsageEnabled = true
let fetcher = UsageFetcher()
let store = UsageStore(fetcher: fetcher, browserDetection: BrowserDetection(cacheTTL: 0), settings: settings)
store._setTokenSnapshotForTesting(
CostUsageTokenSnapshot(
sessionTokens: 123,
sessionCostUSD: 0.12,
last30DaysTokens: 456,
last30DaysCostUSD: 1.23,
daily: [],
updatedAt: Date()),
provider: .claude)
let controller = StatusItemController(
store: store,
settings: settings,
account: fetcher.loadAccountInfo(),
updater: DisabledUpdaterController(),
preferencesSelection: PreferencesSelection(),
statusBar: .system)
let model = try #require(controller.menuCardModel(
for: .claude,
errorOverride: "Token expired",
forceOverrideCard: true,
accountOverride: AccountInfo(email: "account@example.com", plan: nil)))
#expect(model.tokenUsage == nil)
#expect(model.email == "account@example.com")
}
@Test
func `account card without its own error does not inherit the ambient Claude error`() throws {
let suite = "MenuCardOverrideIsolationTests-\(UUID().uuidString)"
let defaults = try #require(UserDefaults(suiteName: suite))
defaults.removePersistentDomain(forName: suite)
let settings = SettingsStore(
userDefaults: defaults,
configStore: testConfigStore(suiteName: suite),
zaiTokenStore: NoopZaiTokenStore(),
syntheticTokenStore: NoopSyntheticTokenStore())
let fetcher = UsageFetcher()
let store = UsageStore(fetcher: fetcher, browserDetection: BrowserDetection(cacheTTL: 0), settings: settings)
store._setErrorForTesting("Claude OAuth credentials unavailable", provider: .claude)
let controller = StatusItemController(
store: store,
settings: settings,
account: fetcher.loadAccountInfo(),
updater: DisabledUpdaterController(),
preferencesSelection: PreferencesSelection(),
statusBar: .system)
let accountSnapshot = UsageSnapshot(
primary: RateWindow(usedPercent: 25, windowMinutes: 300, resetsAt: nil, resetDescription: nil),
secondary: nil,
updatedAt: Date(),
identity: ProviderIdentitySnapshot(
providerID: .claude,
accountEmail: "account@example.com",
accountOrganization: nil,
loginMethod: "claude-swap"))
let model = try #require(controller.menuCardModel(
for: .claude,
snapshotOverride: accountSnapshot,
accountOverride: AccountInfo(email: "account@example.com", plan: nil)))
#expect(model.subtitleStyle != .error)
#expect(!model.subtitleText.contains("Claude OAuth credentials unavailable"))
let liveModel = try #require(controller.menuCardModel(for: .claude))
#expect(liveModel.subtitleStyle == .error)
#expect(liveModel.subtitleText == "Claude OAuth credentials unavailable")
}
@Test
func `failed stacked token account card keeps its configured label`() throws {
let suite = "MenuCardOverrideIsolationTests-\(UUID().uuidString)"
let defaults = try #require(UserDefaults(suiteName: suite))
defaults.removePersistentDomain(forName: suite)
let settings = SettingsStore(
userDefaults: defaults,
configStore: testConfigStore(suiteName: suite),
zaiTokenStore: NoopZaiTokenStore(),
syntheticTokenStore: NoopSyntheticTokenStore())
let fetcher = UsageFetcher()
let store = UsageStore(fetcher: fetcher, browserDetection: BrowserDetection(cacheTTL: 0), settings: settings)
let controller = StatusItemController(
store: store,
settings: settings,
account: fetcher.loadAccountInfo(),
updater: DisabledUpdaterController(),
preferencesSelection: PreferencesSelection(),
statusBar: .system)
let account = ProviderTokenAccount(
id: UUID(),
label: "Rejected group",
token: "fixture",
addedAt: 0,
lastUsed: nil)
let accountSnapshot = TokenAccountUsageSnapshot(
account: account,
snapshot: nil,
error: "sub2api rejected the API key.",
sourceLabel: nil,
cacheKey: "fixture-cache")
let model = try #require(controller.tokenAccountMenuCardModel(
for: .sub2api,
accountSnapshot: accountSnapshot))
#expect(model.email == "Rejected group")
#expect(model.subtitleStyle == .error)
}
@Test
func `successful stacked token account card prefers fetched identity over configured label`() throws {
let suite = "MenuCardOverrideIsolationTests-\(UUID().uuidString)"
let defaults = try #require(UserDefaults(suiteName: suite))
defaults.removePersistentDomain(forName: suite)
let settings = SettingsStore(
userDefaults: defaults,
configStore: testConfigStore(suiteName: suite),
zaiTokenStore: NoopZaiTokenStore(),
syntheticTokenStore: NoopSyntheticTokenStore())
let fetcher = UsageFetcher()
let store = UsageStore(fetcher: fetcher, browserDetection: BrowserDetection(cacheTTL: 0), settings: settings)
let controller = StatusItemController(
store: store,
settings: settings,
account: fetcher.loadAccountInfo(),
updater: DisabledUpdaterController(),
preferencesSelection: PreferencesSelection(),
statusBar: .system)
let account = ProviderTokenAccount(
id: UUID(),
label: "Configured group",
token: "fixture",
addedAt: 0,
lastUsed: nil)
let usage = UsageSnapshot(
primary: RateWindow(usedPercent: 25, windowMinutes: 300, resetsAt: nil, resetDescription: nil),
secondary: nil,
updatedAt: Date(),
identity: ProviderIdentitySnapshot(
providerID: .sub2api,
accountEmail: "fetched@example.com",
accountOrganization: nil,
loginMethod: nil))
let accountSnapshot = TokenAccountUsageSnapshot(
account: account,
snapshot: usage,
error: nil,
sourceLabel: "api",
cacheKey: "fixture-cache")
let model = try #require(controller.tokenAccountMenuCardModel(
for: .sub2api,
accountSnapshot: accountSnapshot))
#expect(model.email == "fetched@example.com")
}
}