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

220 lines
9.2 KiB
Swift

import AppKit
import CodexBarCore
import Foundation
import Testing
@testable import CodexBar
@MainActor
@Suite(.serialized)
struct CodexWeeklyCapSurfaceTests {
@Test
func `menu card session metric shows weekly cap and reset`() throws {
let now = Date(timeIntervalSince1970: 1_800_000_000)
let metadata = try #require(ProviderDefaults.metadata[.codex])
let weeklyReset = now.addingTimeInterval(4 * 24 * 60 * 60)
let snapshot = UsageSnapshot(
primary: RateWindow(
usedPercent: 1,
windowMinutes: 300,
resetsAt: now.addingTimeInterval(3 * 60 * 60),
resetDescription: nil),
secondary: RateWindow(
usedPercent: 100,
windowMinutes: 10080,
resetsAt: weeklyReset,
resetDescription: nil),
updatedAt: now.addingTimeInterval(-2 * 60 * 60))
let projection = CodexConsumerProjection.make(
surface: .liveCard,
context: CodexConsumerProjection.Context(
snapshot: snapshot,
rawUsageError: nil,
liveCredits: nil,
rawCreditsError: nil,
liveDashboard: nil,
rawDashboardError: nil,
dashboardAttachmentAuthorized: false,
dashboardRequiresLogin: false,
now: now))
let model = UsageMenuCardView.Model.make(.init(
provider: .codex,
metadata: metadata,
snapshot: snapshot,
codexProjection: projection,
credits: nil,
creditsError: nil,
dashboard: nil,
dashboardError: nil,
tokenSnapshot: nil,
tokenError: nil,
account: AccountInfo(email: nil, plan: nil),
isRefreshing: false,
lastError: nil,
usageBarsShowUsed: false,
resetTimeDisplayStyle: .countdown,
tokenCostUsageEnabled: false,
showOptionalCreditsAndExtraUsage: true,
hidePersonalInfo: false,
now: now))
let session = try #require(model.metrics.first { $0.id == "primary" })
let weekly = try #require(model.metrics.first { $0.id == "secondary" })
#expect(session.percent == 0)
#expect(session.resetText == weekly.resetText)
#expect(session.resetText != nil)
}
@Test
func `primary menu bar metric and credits follow binding weekly reset`() {
let settings = SettingsStore(
configStore: testConfigStore(suiteName: "CodexWeeklyCapSurfaceTests-menu-bar"),
zaiTokenStore: NoopZaiTokenStore())
settings.statusChecksEnabled = false
settings.refreshFrequency = .manual
settings.mergeIcons = true
settings.selectedMenuProvider = .codex
settings.setMenuBarMetricPreference(.primary, for: .codex)
if let codexMeta = ProviderRegistry.shared.metadata[.codex] {
settings.setProviderEnabled(provider: .codex, metadata: codexMeta, enabled: true)
}
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)
defer { controller.releaseStatusItemsForTesting() }
let now = Date(timeIntervalSince1970: 1_800_000_000)
let weeklyReset = now.addingTimeInterval(3600)
let sessionReset = now.addingTimeInterval(1800)
let snapshot = UsageSnapshot(
primary: RateWindow(
usedPercent: 1,
windowMinutes: 300,
resetsAt: sessionReset,
resetDescription: nil),
secondary: RateWindow(
usedPercent: 100,
windowMinutes: 10080,
resetsAt: weeklyReset,
resetDescription: nil),
updatedAt: now.addingTimeInterval(-7200))
store.credits = CreditsSnapshot(remaining: 80, events: [], updatedAt: now)
let capped = controller.menuBarMetricWindow(for: .codex, snapshot: snapshot, now: now)
let reset = controller.menuBarMetricWindow(for: .codex, snapshot: snapshot, now: weeklyReset)
let cappedCredits = controller.menuBarCreditsRemainingForIcon(
provider: .codex,
snapshot: snapshot,
now: now)
let resetCredits = controller.menuBarCreditsRemainingForIcon(
provider: .codex,
snapshot: snapshot,
now: weeklyReset)
#expect(capped?.remainingPercent == 0)
#expect(capped?.resetsAt == weeklyReset)
#expect(reset?.remainingPercent == 99)
#expect(reset?.resetsAt == sessionReset)
#expect(cappedCredits == 80)
#expect(resetCredits == nil)
}
@Test
func `combined menu bar modes ignore exhausted weekly lane after its reset`() throws {
let settings = SettingsStore(
configStore: testConfigStore(suiteName: "CodexWeeklyCapSurfaceTests-combined-reset"),
zaiTokenStore: NoopZaiTokenStore(),
syntheticTokenStore: NoopSyntheticTokenStore())
settings.statusChecksEnabled = false
settings.refreshFrequency = .manual
settings.mergeIcons = true
settings.selectedMenuProvider = .codex
settings.usageBarsShowUsed = false
settings.resetTimesShowAbsolute = false
settings.setMenuBarMetricPreference(.primaryAndSecondary, for: .codex)
if let codexMeta = ProviderRegistry.shared.metadata[.codex] {
settings.setProviderEnabled(provider: .codex, metadata: codexMeta, enabled: true)
}
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)
defer { controller.releaseStatusItemsForTesting() }
let now = Date(timeIntervalSince1970: 1_800_000_000)
let sessionReset = now.addingTimeInterval(3600)
let snapshot = UsageSnapshot(
primary: RateWindow(
usedPercent: 1,
windowMinutes: 300,
resetsAt: sessionReset,
resetDescription: nil),
secondary: RateWindow(
usedPercent: 100,
windowMinutes: 10080,
resetsAt: now,
resetDescription: nil),
updatedAt: now.addingTimeInterval(-7200))
store._setSnapshotForTesting(snapshot, provider: .codex)
let selected = try #require(controller.menuBarMetricWindow(for: .codex, snapshot: snapshot, now: now))
#expect(selected.remainingPercent == 99)
#expect(selected.resetsAt == sessionReset)
settings.menuBarDisplayMode = .percent
#expect(controller.menuBarDisplayText(for: .codex, snapshot: snapshot, now: now) == "5h 99%")
settings.menuBarDisplayMode = .pace
#expect(controller.menuBarDisplayText(for: .codex, snapshot: snapshot, now: now) == "99%")
settings.menuBarDisplayMode = .both
#expect(controller.menuBarDisplayText(for: .codex, snapshot: snapshot, now: now) == "99%")
settings.menuBarDisplayMode = .resetTime
#expect(controller.menuBarDisplayText(for: .codex, snapshot: snapshot, now: now) == "↻ in 1h")
settings.setMenuBarMetricPreference(.primary, for: .codex)
settings.menuBarDisplayMode = .percent
let expiredSessionSnapshot = UsageSnapshot(
primary: RateWindow(
usedPercent: 100,
windowMinutes: 300,
resetsAt: now,
resetDescription: nil),
secondary: RateWindow(
usedPercent: 40,
windowMinutes: 10080,
resetsAt: now.addingTimeInterval(7 * 24 * 60 * 60),
resetDescription: nil),
updatedAt: now.addingTimeInterval(-7200))
store._setSnapshotForTesting(expiredSessionSnapshot, provider: .codex)
store.credits = CreditsSnapshot(remaining: 80, events: [], updatedAt: now)
let resetPrimary = try #require(controller.menuBarMetricWindow(
for: .codex,
snapshot: expiredSessionSnapshot,
now: now))
let resetIcon = IconRemainingResolver.resolvedRemaining(
snapshot: expiredSessionSnapshot,
style: .codex,
now: now)
#expect(resetPrimary.remainingPercent == 60)
#expect(controller.menuBarDisplayText(for: .codex, snapshot: expiredSessionSnapshot, now: now) == "60%")
#expect(resetIcon.primary == 60)
#expect(resetIcon.secondary == nil)
#expect(store.codexConsumerProjection(surface: .menuBar, now: now).menuBarFallback == .none)
}
}