Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Tests/CodexBarTests/SpendDashboardControllerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ struct SpendDashboardControllerTests {
#expect(controller.selectedDays == 30)
}

private static let fixtureNow = Date(timeIntervalSince1970: 1_784_179_200)
private nonisolated static let fixtureNow = Date(timeIntervalSince1970: 1_784_179_200)

private static func dashboardController(
settings: SettingsStore,
Expand All @@ -767,7 +767,8 @@ struct SpendDashboardControllerTests {
store: store,
mode: mode,
now: Self.fixtureNow)
})
},
nowProvider: { Self.fixtureNow })
}

private static func controller(gate: SpendDashboardLoaderGate) -> SpendDashboardController {
Expand Down
67 changes: 30 additions & 37 deletions Tests/CodexBarTests/SpendDashboardTokenProvenanceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,8 @@ struct SpendDashboardTokenProvenanceTests {
#expect(store.tokenSnapshotPublicationRevision(for: .mistral) == 0)
}

@Test
func `cached token account activation does not prove a forced refresh`() async throws {
let now = Date(timeIntervalSince1970: 1_784_179_200)
@Test(arguments: Self.monthBoundaryDates)
func `cached token account activation does not prove a forced refresh`(now: Date) async throws {
let (settings, store) = Self.makeStore(provider: .mistral)
settings.addTokenAccount(provider: .mistral, label: "Fixture", token: "fixture")
let account = try #require(settings.effectiveSelectedTokenAccount(for: .mistral))
Expand All @@ -125,16 +124,7 @@ struct SpendDashboardTokenProvenanceTests {
store.activateCachedTokenAccountSnapshot(provider: .mistral, accountID: account.id)
#expect(store.tokenSnapshotPublicationRevision(for: .mistral) == baselineRevision)
store._test_providerRefreshOverride = { _ in }
let controller = SpendDashboardController(
userDefaults: settings.userDefaults,
requestBuilder: { mode in
await SpendDashboardSource.makeRequest(
settings: settings,
store: store,
mode: mode,
now: now)
},
nowProvider: { now })
let controller = Self.dashboardController(settings: settings, store: store, now: now)
controller.update(configuration: SpendDashboardSource.configuration(settings: settings, store: store))
await Self.waitUntil { !controller.isRefreshing }
#expect(controller.model.groups.first?.totalCost == 3)
Expand All @@ -147,26 +137,16 @@ struct SpendDashboardTokenProvenanceTests {
#expect(store.tokenSnapshotPublicationRevision(for: .mistral) == baselineRevision)
}

@Test
func `forced successful empty publication removes prior spend without warning`() async {
let now = Date(timeIntervalSince1970: 1_784_203_200)
@Test(arguments: Self.monthBoundaryDates)
func `forced successful empty publication removes prior spend without warning`(now: Date) async {
let (settings, store) = Self.makeStore(provider: .bedrock)
var loadCount = 0
store._test_tokenUsageSnapshotLoaderOverride = { _, _, _, _, _ in
loadCount += 1
return loadCount == 1 ? Self.tokenSnapshot(cost: 4) : Self.emptyTokenSnapshot()
}
await store.refreshTokenUsageNow(for: .bedrock, force: true)
let controller = SpendDashboardController(
userDefaults: settings.userDefaults,
requestBuilder: { mode in
await SpendDashboardSource.makeRequest(
settings: settings,
store: store,
mode: mode,
now: now)
},
nowProvider: { now })
let controller = Self.dashboardController(settings: settings, store: store, now: now)
controller.update(configuration: SpendDashboardSource.configuration(settings: settings, store: store))
await Self.waitUntil { !controller.isRefreshing }
#expect(controller.model.groups.first?.totalCost == 4)
Expand All @@ -185,7 +165,6 @@ struct SpendDashboardTokenProvenanceTests {

@Test
func `first open accepts current empty publication without redundant refresh`() async {
let now = Date(timeIntervalSince1970: 1_784_179_200)
let (settings, store) = Self.makeStore(provider: .bedrock)
var loadCount = 0
store._test_tokenUsageSnapshotLoaderOverride = { _, _, _, _, _ in
Expand All @@ -194,16 +173,7 @@ struct SpendDashboardTokenProvenanceTests {
}
await store.refreshTokenUsageNow(for: .bedrock, force: true)
let publicationRevision = store.tokenSnapshotPublicationRevision(for: .bedrock)
let controller = SpendDashboardController(
userDefaults: settings.userDefaults,
requestBuilder: { mode in
await SpendDashboardSource.makeRequest(
settings: settings,
store: store,
mode: mode,
now: now)
},
nowProvider: { now })
let controller = Self.dashboardController(settings: settings, store: store, now: Self.fixtureNow)

controller.update(configuration: SpendDashboardSource.configuration(settings: settings, store: store))
await Self.waitUntil { !controller.isRefreshing }
Expand Down Expand Up @@ -310,6 +280,29 @@ struct SpendDashboardTokenProvenanceTests {
#expect(store.tokenSnapshotForCurrentProviderConfig(for: .claude)?.snapshot == snapshot)
}

private static let fixtureNow = Date(timeIntervalSince1970: 1_784_179_200)
private nonisolated static let monthBoundaryDates = [
Date(timeIntervalSince1970: 1_785_542_399), // 2026-07-31 23:59:59 UTC
Date(timeIntervalSince1970: 1_785_542_400), // 2026-08-01 00:00:00 UTC
]

private static func dashboardController(
settings: SettingsStore,
store: UsageStore,
now: Date) -> SpendDashboardController
{
SpendDashboardController(
userDefaults: settings.userDefaults,
requestBuilder: { mode in
await SpendDashboardSource.makeRequest(
settings: settings,
store: store,
mode: mode,
now: now)
},
nowProvider: { now })
}

private static func makeStore(provider: UsageProvider) -> (SettingsStore, UsageStore) {
let settings = testSettingsStore(suiteName: "SpendDashboardTokenProvenanceTests-\(provider.rawValue)")
settings.costUsageEnabled = true
Expand Down
3 changes: 2 additions & 1 deletion TestsLinux/CLICardsClaudeSwapTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ struct CLICardsClaudeSwapTests {
let directory = FileManager.default.temporaryDirectory
.appendingPathComponent("cards-claude-swap-tests-\(UUID().uuidString)", isDirectory: true)
try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
defer { try? FileManager.default.removeItem(at: directory) }
let executable = directory.appendingPathComponent("cswap")
let invocationMarker = directory.appendingPathComponent("invoked", isDirectory: true)
let duplicateMarker = directory.appendingPathComponent("duplicate")
Expand All @@ -371,7 +372,7 @@ struct CLICardsClaudeSwapTests {
]}
JSON
"""
try script.write(to: executable, atomically: true, encoding: .utf8)
try Data(script.utf8).write(to: executable)
try FileManager.default.setAttributes([.posixPermissions: 0o755], ofItemAtPath: executable.path)

let output = await CLIClaudeSwapCards.fetch(
Expand Down