142 lines
4.5 KiB
TypeScript
142 lines
4.5 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import {
|
|
getInactiveProviderUsage,
|
|
getUsageBarState,
|
|
hasActiveProviderUsage,
|
|
hasRenderableUsage,
|
|
type AccountsSnapshot,
|
|
type InactiveAccountUsage,
|
|
type ProviderRateLimits
|
|
} from './account-usage-state'
|
|
|
|
function makeLimits(overrides: Partial<ProviderRateLimits> = {}): ProviderRateLimits {
|
|
return {
|
|
provider: 'claude',
|
|
session: null,
|
|
weekly: null,
|
|
monthly: null,
|
|
updatedAt: 0,
|
|
error: null,
|
|
status: 'idle',
|
|
...overrides
|
|
}
|
|
}
|
|
|
|
function makeSnapshot(
|
|
overrides: {
|
|
claudeLimits?: ProviderRateLimits | null
|
|
codexLimits?: ProviderRateLimits | null
|
|
claudeAccounts?: AccountsSnapshot['claude']['accounts']
|
|
codexAccounts?: AccountsSnapshot['codex']['accounts']
|
|
inactiveClaudeAccounts?: InactiveAccountUsage[]
|
|
inactiveCodexAccounts?: InactiveAccountUsage[]
|
|
} = {}
|
|
): AccountsSnapshot {
|
|
return {
|
|
claude: { accounts: overrides.claudeAccounts ?? [], activeAccountId: null },
|
|
codex: { accounts: overrides.codexAccounts ?? [], activeAccountId: null },
|
|
rateLimits: {
|
|
claude: overrides.claudeLimits ?? null,
|
|
codex: overrides.codexLimits ?? null,
|
|
inactiveClaudeAccounts: overrides.inactiveClaudeAccounts ?? [],
|
|
inactiveCodexAccounts: overrides.inactiveCodexAccounts ?? []
|
|
}
|
|
}
|
|
}
|
|
|
|
describe('hasActiveProviderUsage', () => {
|
|
it('is false when there are no rate limits at all', () => {
|
|
expect(hasActiveProviderUsage(null)).toBe(false)
|
|
})
|
|
|
|
it('is true when a session window has data', () => {
|
|
expect(
|
|
hasActiveProviderUsage(
|
|
makeLimits({
|
|
status: 'ok',
|
|
session: { usedPercent: 12, windowMinutes: 300, resetsAt: null, resetDescription: null }
|
|
})
|
|
)
|
|
).toBe(true)
|
|
})
|
|
|
|
it('is true when a successful fetch returned ok even with empty windows', () => {
|
|
expect(hasActiveProviderUsage(makeLimits({ status: 'ok' }))).toBe(true)
|
|
})
|
|
|
|
it('is false for an unavailable/error provider with no window data (no creds)', () => {
|
|
expect(hasActiveProviderUsage(makeLimits({ status: 'unavailable' }))).toBe(false)
|
|
expect(hasActiveProviderUsage(makeLimits({ status: 'error', error: 'nope' }))).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('hasRenderableUsage', () => {
|
|
it('is true when the provider has at least one managed account', () => {
|
|
const snapshot = makeSnapshot({
|
|
claudeAccounts: [{ id: 'a', email: 'x@y.z' }]
|
|
})
|
|
expect(hasRenderableUsage(snapshot, 'claude')).toBe(true)
|
|
})
|
|
|
|
// The bug: system-default auth has zero managed accounts but real usage data,
|
|
// and the home screen used to hide it entirely.
|
|
it('is true with zero managed accounts when active rate-limit data exists (system default)', () => {
|
|
const snapshot = makeSnapshot({
|
|
codexLimits: makeLimits({
|
|
provider: 'codex',
|
|
status: 'ok',
|
|
session: { usedPercent: 40, windowMinutes: 300, resetsAt: null, resetDescription: null }
|
|
})
|
|
})
|
|
expect(hasRenderableUsage(snapshot, 'codex')).toBe(true)
|
|
})
|
|
|
|
it('is false with zero accounts and no usable rate-limit data', () => {
|
|
const snapshot = makeSnapshot({
|
|
claudeLimits: makeLimits({ status: 'unavailable' })
|
|
})
|
|
expect(hasRenderableUsage(snapshot, 'claude')).toBe(false)
|
|
expect(hasRenderableUsage(makeSnapshot(), 'claude')).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('getInactiveProviderUsage', () => {
|
|
it('returns inactive usage using the runtime rateLimits payload shape', () => {
|
|
const limits = makeLimits({
|
|
status: 'ok',
|
|
session: { usedPercent: 52, windowMinutes: 300, resetsAt: null, resetDescription: null }
|
|
})
|
|
const snapshot = makeSnapshot({
|
|
inactiveClaudeAccounts: [
|
|
{ accountId: 'account-1', rateLimits: limits, updatedAt: 123, isFetching: false }
|
|
]
|
|
})
|
|
|
|
expect(getInactiveProviderUsage(snapshot, 'claude', 'account-1')?.rateLimits).toBe(limits)
|
|
})
|
|
})
|
|
|
|
describe('getUsageBarState', () => {
|
|
it('keeps stale window data visible during a transient error', () => {
|
|
const bar = getUsageBarState(
|
|
makeLimits({
|
|
status: 'error',
|
|
error: 'temporarily unavailable',
|
|
session: { usedPercent: 72, windowMinutes: 300, resetsAt: null, resetDescription: null }
|
|
}),
|
|
'session'
|
|
)
|
|
|
|
expect(bar).toEqual({ usedPercent: 72, unavailable: false, loading: false })
|
|
})
|
|
|
|
it('shows loading for a fetching provider without a window', () => {
|
|
expect(getUsageBarState(makeLimits({ status: 'fetching' }), 'weekly')).toEqual({
|
|
usedPercent: null,
|
|
unavailable: false,
|
|
loading: true
|
|
})
|
|
})
|
|
})
|