mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-08-14 19:14:28 +00:00
Kimi Code tokens live ~15 min and only the CLI renews them, so the load state sits in .terminalFailure as its dominant steady state between CLI uses. The Plan tab and tab-strip chip flapped to a reconnect screen every cycle even with a good last snapshot on hand. Extract the display decision into a pure KimiQuotaPresentation helper: terminal-with-data shows the usage bars (flagged idle) and only the no-data case falls through to reconnect. loadedBody stamps an 'as of <time>' caption once a snapshot is older than 10 min, in every state that renders it. The chip's kimiQuotaSummary downgrades terminal-with-data to .stale so the bar and popover keep the last-known rows instead of the reconnect card. Settings' connect/disconnect pane still explains the terminal reason. Adds KimiQuotaPresentationTests.
68 lines
3.2 KiB
Swift
68 lines
3.2 KiB
Swift
import Foundation
|
|
import Testing
|
|
@testable import CodeBurnMenubar
|
|
|
|
/// Kimi Code tokens live ~15 min and only the CLI renews them, so
|
|
/// `.terminalFailure` is the dominant steady state between CLI uses. These
|
|
/// tests pin the display decision: a terminal login with a snapshot on hand
|
|
/// must keep showing the bars (with a quiet idle caption), and only the
|
|
/// no-data case falls through to the reconnect screen.
|
|
@Suite("Kimi quota presentation")
|
|
struct KimiQuotaPresentationTests {
|
|
typealias Presentation = KimiQuotaPresentation
|
|
|
|
@Test("terminal failure with a snapshot keeps the usage bars, flagged idle")
|
|
func terminalWithUsageShowsIdleUsage() {
|
|
let content = Presentation.planContent(loadState: .terminalFailure(reason: "expired"), hasUsage: true)
|
|
#expect(content == .usage(idle: true))
|
|
}
|
|
|
|
@Test("terminal failure with no snapshot falls through to reconnect")
|
|
func terminalWithoutUsageShowsReconnect() {
|
|
let content = Presentation.planContent(loadState: .terminalFailure(reason: "expired"), hasUsage: false)
|
|
#expect(content == .reconnect(reason: "expired"))
|
|
}
|
|
|
|
@Test("loaded with a snapshot shows usage without the idle caption")
|
|
func loadedShowsPlainUsage() {
|
|
#expect(Presentation.planContent(loadState: .loaded, hasUsage: true) == .usage(idle: false))
|
|
}
|
|
|
|
@Test("transient failure keeps the last snapshot, else shows the retry screen")
|
|
func transientFailureFallsBackToUsage() {
|
|
#expect(Presentation.planContent(loadState: .transientFailure(retryAt: nil), hasUsage: true) == .usage(idle: false))
|
|
#expect(Presentation.planContent(loadState: .transientFailure(retryAt: nil), hasUsage: false) == .transientFailed)
|
|
}
|
|
|
|
@Test("credential-absent states route to the connect prompt")
|
|
func credentialStatesRouteToNoCredentials() {
|
|
#expect(Presentation.planContent(loadState: .notBootstrapped, hasUsage: false) == .noCredentials)
|
|
#expect(Presentation.planContent(loadState: .noCredentials, hasUsage: false) == .noCredentials)
|
|
}
|
|
|
|
@Test("dormant and bootstrapping render the loading state")
|
|
func dormantAndBootstrappingLoad() {
|
|
#expect(Presentation.planContent(loadState: .dormant, hasUsage: false) == .loading)
|
|
#expect(Presentation.planContent(loadState: .bootstrapping, hasUsage: false) == .loading)
|
|
}
|
|
|
|
@Test("loading with a snapshot shows usage; without one, the loading state")
|
|
func loadingPrefersExistingSnapshot() {
|
|
#expect(Presentation.planContent(loadState: .loading, hasUsage: true) == .usage(idle: false))
|
|
#expect(Presentation.planContent(loadState: .loading, hasUsage: false) == .loading)
|
|
}
|
|
|
|
@Test("a fresh snapshot is not stamped stale")
|
|
func freshSnapshotIsNotStale() {
|
|
let now = Date()
|
|
let fetchedAt = now.addingTimeInterval(-60) // 1 min old
|
|
#expect(Presentation.isStale(fetchedAt: fetchedAt, now: now) == false)
|
|
}
|
|
|
|
@Test("a snapshot older than the threshold is stamped stale")
|
|
func oldSnapshotIsStale() {
|
|
let now = Date()
|
|
let fetchedAt = now.addingTimeInterval(-11 * 60) // 11 min old
|
|
#expect(Presentation.isStale(fetchedAt: fetchedAt, now: now) == true)
|
|
}
|
|
}
|