import Testing@testable import CodexBarCLI@testable import CodexBarCore @Suitestruct CLIWebFallbackTests { private func makeContext( runtime: ProviderRuntime = .cli, sourceMode: ProviderSourceMode = .auto, settings: ProviderSettingsSnapshot? = nil) -> ProviderFetchContext { let browserDetection = BrowserDetection(cacheTTL: 0) return ProviderFetchContext( runtime: runtime, sourceMode: sourceMode, includeCredits: true, webTimeout: 60, webDebugDumpHTML: false, verbose: false, env: [:], settings: settings, fetcher: UsageFetcher(), claudeFetcher: ClaudeUsageFetcher(browserDetection: browserDetection), browserDetection: browserDetection) } private func makeClaudeSettingsSnapshot(cookieHeader: String?) -> ProviderSettingsSnapshot { ProviderSettingsSnapshot.make( claude: .init( usageDataSource: .auto, webExtrasEnabled: false, cookieSource: .manual, manualCookieHeader: cookieHeader)) } @Test func codexFallsBackWhenCookiesMissing() { let context = self.makeContext() let strategy = CodexWebDashboardStrategy() #expect(strategy.shouldFallback( on: OpenAIDashboardBrowserCookieImporter.ImportError.noCookiesFound, context: context)) #expect(strategy.shouldFallback( on: OpenAIDashboardBrowserCookieImporter.ImportError.noMatchingAccount(found: []), context: context)) #expect(strategy.shouldFallback( on: OpenAIDashboardBrowserCookieImporter.ImportError.browserAccessDenied(details: "no access"), context: context)) #expect(strategy.shouldFallback( on: OpenAIDashboardBrowserCookieImporter.ImportError.dashboardStillRequiresLogin, context: context)) #expect(strategy.shouldFallback( on: OpenAIDashboardFetcher.FetchError.loginRequired, context: context)) } @Test func codexFallsBackForDashboardDataErrorsInAuto() { let context = self.makeContext() let strategy = CodexWebDashboardStrategy() #expect(strategy.shouldFallback( on: OpenAIDashboardFetcher.FetchError.noDashboardData(body: "missing"), context: context)) } @Test func claudeFallsBackWhenNoSessionKey() { let context = self.makeContext() let strategy = ClaudeWebFetchStrategy(browserDetection: BrowserDetection(cacheTTL: 0)) #expect(strategy.shouldFallback(on: ClaudeWebAPIFetcher.FetchError.noSessionKeyFound, context: context)) #expect(strategy.shouldFallback(on: ClaudeWebAPIFetcher.FetchError.unauthorized, context: context)) } @Test func claudeCLIFallbackIsEnabledOnlyForAppAuto() { let strategy = ClaudeCLIFetchStrategy( useWebExtras: false, manualCookieHeader: nil, browserDetection: BrowserDetection(cacheTTL: 0)) let error = ClaudeUsageError.parseFailed("cli failed") let webAvailableSettings = self.makeClaudeSettingsSnapshot(cookieHeader: "sessionKey=sk-ant-test") let webUnavailableSettings = self.makeClaudeSettingsSnapshot(cookieHeader: "foo=bar") #expect(strategy.shouldFallback( on: error, context: self.makeContext(runtime: .app, sourceMode: .auto, settings: webAvailableSettings))) #expect(!strategy.shouldFallback( on: error, context: self.makeContext(runtime: .app, sourceMode: .auto, settings: webUnavailableSettings))) #expect(!strategy.shouldFallback(on: error, context: self.makeContext(runtime: .app, sourceMode: .cli))) #expect(!strategy.shouldFallback(on: error, context: self.makeContext(runtime: .app, sourceMode: .web))) #expect(!strategy.shouldFallback(on: error, context: self.makeContext(runtime: .app, sourceMode: .oauth))) #expect(!strategy.shouldFallback(on: error, context: self.makeContext(runtime: .cli, sourceMode: .auto))) } @Test func claudeWebFallbackIsDisabledForAppAuto() { let strategy = ClaudeWebFetchStrategy(browserDetection: BrowserDetection(cacheTTL: 0)) let error = ClaudeWebAPIFetcher.FetchError.unauthorized #expect(strategy.shouldFallback(on: error, context: self.makeContext(runtime: .cli, sourceMode: .auto))) #expect(!strategy.shouldFallback(on: error, context: self.makeContext(runtime: .app, sourceMode: .auto))) }}
import Testing
@testable import CodexBarCLI
@testable import CodexBarCore
@Suite
struct CLIWebFallbackTests {
private func makeContext(
runtime: ProviderRuntime = .cli,
sourceMode: ProviderSourceMode = .auto,
settings: ProviderSettingsSnapshot? = nil) -> ProviderFetchContext
{
let browserDetection = BrowserDetection(cacheTTL: 0)
return ProviderFetchContext(
runtime: runtime,
sourceMode: sourceMode,
includeCredits: true,
webTimeout: 60,
webDebugDumpHTML: false,
verbose: false,
env: [:],
settings: settings,
fetcher: UsageFetcher(),
claudeFetcher: ClaudeUsageFetcher(browserDetection: browserDetection),
browserDetection: browserDetection)
}
private func makeClaudeSettingsSnapshot(cookieHeader: String?) -> ProviderSettingsSnapshot {
ProviderSettingsSnapshot.make(
claude: .init(
usageDataSource: .auto,
webExtrasEnabled: false,
cookieSource: .manual,
manualCookieHeader: cookieHeader))
}
@Test
func codexFallsBackWhenCookiesMissing() {
let context = self.makeContext()
let strategy = CodexWebDashboardStrategy()
#expect(strategy.shouldFallback(
on: OpenAIDashboardBrowserCookieImporter.ImportError.noCookiesFound,
context: context))
#expect(strategy.shouldFallback(
on: OpenAIDashboardBrowserCookieImporter.ImportError.noMatchingAccount(found: []),
context: context))
#expect(strategy.shouldFallback(
on: OpenAIDashboardBrowserCookieImporter.ImportError.browserAccessDenied(details: "no access"),
context: context))
#expect(strategy.shouldFallback(
on: OpenAIDashboardBrowserCookieImporter.ImportError.dashboardStillRequiresLogin,
context: context))
#expect(strategy.shouldFallback(
on: OpenAIDashboardFetcher.FetchError.loginRequired,
context: context))
}
@Test
func codexFallsBackForDashboardDataErrorsInAuto() {
let context = self.makeContext()
let strategy = CodexWebDashboardStrategy()
#expect(strategy.shouldFallback(
on: OpenAIDashboardFetcher.FetchError.noDashboardData(body: "missing"),
context: context))
}
@Test
func claudeFallsBackWhenNoSessionKey() {
let context = self.makeContext()
let strategy = ClaudeWebFetchStrategy(browserDetection: BrowserDetection(cacheTTL: 0))
#expect(strategy.shouldFallback(on: ClaudeWebAPIFetcher.FetchError.noSessionKeyFound, context: context))
#expect(strategy.shouldFallback(on: ClaudeWebAPIFetcher.FetchError.unauthorized, context: context))
}
@Test
func claudeCLIFallbackIsEnabledOnlyForAppAuto() {
let strategy = ClaudeCLIFetchStrategy(
useWebExtras: false,
manualCookieHeader: nil,
browserDetection: BrowserDetection(cacheTTL: 0))
let error = ClaudeUsageError.parseFailed("cli failed")
let webAvailableSettings = self.makeClaudeSettingsSnapshot(cookieHeader: "sessionKey=sk-ant-test")
let webUnavailableSettings = self.makeClaudeSettingsSnapshot(cookieHeader: "foo=bar")
#expect(strategy.shouldFallback(
on: error,
context: self.makeContext(runtime: .app, sourceMode: .auto, settings: webAvailableSettings)))
#expect(!strategy.shouldFallback(
on: error,
context: self.makeContext(runtime: .app, sourceMode: .auto, settings: webUnavailableSettings)))
#expect(!strategy.shouldFallback(on: error, context: self.makeContext(runtime: .app, sourceMode: .cli)))
#expect(!strategy.shouldFallback(on: error, context: self.makeContext(runtime: .app, sourceMode: .web)))
#expect(!strategy.shouldFallback(on: error, context: self.makeContext(runtime: .app, sourceMode: .oauth)))
#expect(!strategy.shouldFallback(on: error, context: self.makeContext(runtime: .cli, sourceMode: .auto)))
}
@Test
func claudeWebFallbackIsDisabledForAppAuto() {
let strategy = ClaudeWebFetchStrategy(browserDetection: BrowserDetection(cacheTTL: 0))
let error = ClaudeWebAPIFetcher.FetchError.unauthorized
#expect(strategy.shouldFallback(on: error, context: self.makeContext(runtime: .cli, sourceMode: .auto)))
#expect(!strategy.shouldFallback(on: error, context: self.makeContext(runtime: .app, sourceMode: .auto)))
}
}