codeburn/app/renderer/sections/Optimize.test.tsx
iamtoruk 300e949951 feat(app): refresh cadence, instant switching, cache coherence, telemetry v1
Performance and coherence:
- Settings > General 'Refresh every' (Manual/30s/1m/3m/5m/10m), live via
  RefreshCadenceContext; Manual polls only on demand
- usePolled memoKey LRU: provider/period switches paint the last-good
  result instantly with a switching hairline while refreshing quietly
- quota TTL 5min + honest rate-limited copy on 429 backoff
- version-suffixed cache files (session-cache.v5.json, daily-cache.v12,
  auto-minted on future bumps); legacy files never written or deleted,
  adopted once when versions match: old and new binaries coexist
  without clobbering (field-observed menubar-vs-desktop ping-pong)
- advisory hydration lock: concurrent cold starts share one scan
  (wait-then-read-warm), stale/dead locks self-heal, never a
  correctness gate

Telemetry v1 + onboarding (desktop only, per owner decisions):
- first-launch onboarding (3 feature screens + consent); region-split
  default (EU/EEA/UK/CH off, elsewhere on, unknown off); nothing sends
  before consent completion or while off; dev builds never send
- anonymous install UUID, rotated on opt-out; day-granularity events,
  cost buckets only; whitelisted names; 200-event queue, 5min flush
- Settings > Privacy live toggle replaces the static claim

Zero computed-number changes. App 316/316, root 1805.

Wire contract targets api.codeburn.app/v1/telemetry (Worker follows).
2026-07-16 11:47:05 -07:00

250 lines
12 KiB
TypeScript

// @vitest-environment jsdom
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import type { MenubarPayload, OptimizeJsonReport, YieldJsonReport } from '../lib/types'
import { Optimize, OptimizeContent } from './Optimize'
const { getOverview, getOptimizeReport, getYield } = vi.hoisted(() => ({
getOverview: vi.fn(),
getOptimizeReport: vi.fn(),
getYield: vi.fn(),
}))
vi.mock('../lib/ipc', async orig => {
const actual = await orig<typeof import('../lib/ipc')>()
return { ...actual, codeburn: { getOverview, getOptimizeReport, getYield } }
})
function makePayload(): MenubarPayload {
return {
generated: '2026-07-10T19:00:00.000Z',
current: {
label: 'Last 30 days', cost: 612.48, calls: 1220, sessions: 88, oneShotRate: null,
inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0,
cacheHitPercent: 0, codexCredits: 0, topActivities: [], topModels: [],
localModelSavings: { totalUSD: 0, calls: 0, byModel: [], byProvider: [] },
providers: {}, topProjects: [], modelEfficiency: [], topSessions: [],
retryTax: { totalUSD: 0, retries: 0, editTurns: 0, byModel: [] },
routingWaste: { totalSavingsUSD: 0, baselineModel: '', baselineCostPerEdit: 0, byModel: [] },
tools: [], skills: [], subagents: [], mcpServers: [],
},
optimize: {
findingCount: 3,
savingsUSD: 94.4,
topFindings: [
{ title: 'Opus is doing your small talk', impact: 'high', savingsUSD: 9.1 },
{ title: 'Cache hit is low in agentseal-dash', impact: 'medium', savingsUSD: 8.7 },
{ title: 'Batch tiny requests', impact: 'low', savingsUSD: 2.4 },
],
},
history: { daily: [] },
}
}
function makeOptimizeReport(): OptimizeJsonReport {
return {
period: { label: 'Last 30 days', start: '2026-06-11', end: '2026-07-10' },
summary: {
healthScore: 72, healthGrade: 'C', findingCount: 3, periodCostUSD: 612.48,
sessions: 88, calls: 1220, potentialSavingsTokens: 184_000,
potentialSavingsCostUSD: 94.4, potentialSavingsPercent: 15.4, costRateUSD: 0.0005,
},
findings: [
{
id: 'cost-outliers', title: 'Opus is doing your small talk',
explanation: 'Small conversational requests are running on an expensive model.',
severity: 'high', trend: 'active', tokensSaved: 18_200, estimatedSavingsUSD: 9.1,
fix: { type: 'paste', label: 'Paste into CLAUDE.md', text: 'Use Sonnet for routine questions.', destination: 'claude-md' },
},
{
id: 'context-heavy-sessions', title: 'Cache hit is low in agentseal-dash',
explanation: 'Repeated context is not being served from cache.', severity: 'medium',
trend: null, tokensSaved: 17_400, estimatedSavingsUSD: 8.7,
fix: { type: 'command', label: 'Run this command', text: 'codeburn cache inspect' },
},
{
id: 'warmup-heavy', title: 'Batch tiny requests', explanation: 'Many short sessions repeat setup work.',
severity: 'low', trend: 'improving', tokensSaved: 4_800, estimatedSavingsUSD: 2.4,
fix: { type: 'file-content', label: 'Create configuration', path: '~/.codeburn/config.json', content: '{"batch":true}' },
},
],
}
}
function makeYield(): YieldJsonReport {
return {
period: { label: 'Last 30 days', start: '2026-06-11', end: '2026-07-10' },
summary: {
productive: { costUSD: 440, sessions: 19, costPercent: 72, sessionPercent: 70 },
reverted: { costUSD: 107, sessions: 4, costPercent: 17, sessionPercent: 15 },
abandoned: { costUSD: 65.4, sessions: 3, costPercent: 11, sessionPercent: 15 },
total: { costUSD: 612.4, sessions: 26 }, productiveToRevertedCostRatio: 4.1,
},
details: [
{ sessionId: 'rev-1', project: 'codeburn', category: 'reverted', commitCount: 2, costUSD: 55 },
{ sessionId: 'rev-2', project: 'agentseal-dash', category: 'reverted', commitCount: 1, costUSD: 52 },
{ sessionId: 'abn-1', project: 'sandbox-spike', category: 'abandoned', commitCount: 0, costUSD: 65.4 },
{ sessionId: 'prod-1', project: 'desktop-app', category: 'productive', commitCount: 5, costUSD: 440 },
],
}
}
function emptyPayload(): MenubarPayload {
const payload = makePayload()
payload.optimize = { findingCount: 0, savingsUSD: 0, topFindings: [] }
return payload
}
function emptyOptimizeReport(): OptimizeJsonReport {
const report = makeOptimizeReport()
report.summary = { ...report.summary, findingCount: 0, potentialSavingsTokens: 0, potentialSavingsCostUSD: 0, potentialSavingsPercent: 0 }
report.findings = []
return report
}
function emptyYield(): YieldJsonReport {
const report = makeYield()
report.summary.reverted = { costUSD: 0, sessions: 0, costPercent: 0, sessionPercent: 0 }
report.summary.abandoned = { costUSD: 0, sessions: 0, costPercent: 0, sessionPercent: 0 }
report.details = []
return report
}
describe('Optimize', () => {
const writeText = vi.fn<(text: string) => Promise<void>>()
beforeEach(() => {
getOverview.mockReset().mockResolvedValue(makePayload())
getOptimizeReport.mockReset().mockResolvedValue(makeOptimizeReport())
getYield.mockReset().mockResolvedValue(makeYield())
writeText.mockReset().mockResolvedValue(undefined)
Object.defineProperty(navigator, 'clipboard', { configurable: true, value: { writeText } })
})
it('renders tabs and actionable Waste findings with impact, savings, explanation, and copy-paste fix', async () => {
render(<Optimize period="30days" provider="all" />)
expect(await screen.findByText('Opus is doing your small talk')).toBeInTheDocument()
expect(screen.getByText('3 findings · $94.40 potential · health 72/100')).toBeInTheDocument()
expect(screen.getByText('High')).toHaveClass('opt-impact-high')
expect(screen.getByText('Medium')).toHaveClass('opt-impact-medium')
expect(screen.getByText('Low')).toHaveClass('opt-impact-low')
expect(screen.getByText('$9.10')).toHaveClass('opt-finding-savings')
expect(screen.getByText('18.2K tokens')).toBeInTheDocument()
expect(screen.getByRole('tab', { name: 'Waste $94.40' })).toBeInTheDocument()
expect(screen.getByRole('tab', { name: 'Reverts $107.00' })).toBeInTheDocument()
expect(screen.getByRole('tab', { name: 'Abandoned $65.40' })).toBeInTheDocument()
expect(screen.getByRole('tab', { name: 'Fixes 3' })).toBeInTheDocument()
const row = screen.getByRole('button', { name: /Opus is doing your small talk/ })
expect(row).toHaveAttribute('aria-expanded', 'false')
fireEvent.click(row)
expect(row).toHaveAttribute('aria-expanded', 'true')
expect(screen.getByText('Small conversational requests are running on an expensive model.')).toBeInTheDocument()
expect(screen.getByText('Use Sonnet for routine questions.')).toBeInTheDocument()
fireEvent.click(screen.getByRole('button', { name: 'Copy' }))
await waitFor(() => expect(writeText).toHaveBeenCalledWith('Use Sonnet for routine questions.'))
expect(screen.getByRole('button', { name: 'Copied' })).toBeInTheDocument()
})
it('keeps only one finding expanded and renders file-content path and content', async () => {
render(<Optimize period="30days" provider="all" />)
const first = await screen.findByRole('button', { name: /Opus is doing your small talk/ })
fireEvent.click(first)
fireEvent.click(screen.getByRole('button', { name: /Batch tiny requests/ }))
expect(first).toHaveAttribute('aria-expanded', 'false')
expect(screen.queryByText('Small conversational requests are running on an expensive model.')).not.toBeInTheDocument()
expect(screen.getByText('~/.codeburn/config.json')).toBeInTheDocument()
expect(screen.getByText('{"batch":true}')).toBeInTheDocument()
})
it('switches to Reverts and Abandoned and shows only the matching yield details', async () => {
render(<Optimize period="30days" provider="all" />)
await screen.findByText('Opus is doing your small talk')
fireEvent.click(screen.getByRole('tab', { name: 'Reverts $107.00' }))
expect(screen.getByText('codeburn')).toBeInTheDocument()
expect(screen.getByText('2 commits · rev-1')).toBeInTheDocument()
expect(screen.queryByText('sandbox-spike')).not.toBeInTheDocument()
fireEvent.click(screen.getByRole('tab', { name: 'Abandoned $65.40' }))
expect(screen.getByText('sandbox-spike')).toBeInTheDocument()
expect(screen.getByText('0 commits · abn-1')).toBeInTheDocument()
expect(screen.getByText('$65.40')).toHaveClass('val')
expect(screen.queryByText('codeburn')).not.toBeInTheDocument()
expect(screen.queryByText('desktop-app')).not.toBeInTheDocument()
})
it('renders honest placeholders for unavailable yield totals and tab bodies', async () => {
getYield.mockReset().mockRejectedValue(new Error('yield failed'))
render(<Optimize period="30days" provider="all" />)
expect(await screen.findByRole('tab', { name: 'Reverts —' })).toBeInTheDocument()
expect(screen.getByRole('tab', { name: 'Abandoned —' })).toBeInTheDocument()
fireEvent.click(screen.getByRole('tab', { name: 'Reverts —' }))
expect(screen.getByText('Yield data is unavailable right now.')).toBeInTheDocument()
})
it('keeps the Fixes tab populated and preserves all four empty tab states', async () => {
const { rerender } = render(<Optimize period="30days" provider="all" />)
await screen.findByText('Opus is doing your small talk')
fireEvent.click(screen.getByRole('tab', { name: 'Fixes 3' }))
expect(screen.getByText('Opus is doing your small talk')).toBeInTheDocument()
getOverview.mockResolvedValue(emptyPayload())
getOptimizeReport.mockResolvedValue(emptyOptimizeReport())
getYield.mockResolvedValue(emptyYield())
rerender(<Optimize period="week" provider="all" />)
expect(await screen.findByText('No fixes in this range yet.')).toBeInTheDocument()
expect(screen.getByRole('tab', { name: 'Fixes 0' })).toBeInTheDocument()
fireEvent.click(screen.getByRole('tab', { name: 'Waste $0.00' }))
expect(screen.getByText('No waste findings in this range yet.')).toBeInTheDocument()
fireEvent.click(screen.getByRole('tab', { name: 'Reverts $0.00' }))
expect(screen.getByText('No reverted sessions in this range yet.')).toBeInTheDocument()
fireEvent.click(screen.getByRole('tab', { name: 'Abandoned $0.00' }))
expect(screen.getByText('No abandoned sessions in this range yet.')).toBeInTheDocument()
})
it('labels the Fixes tab with the rendered list length, not the menubar-wide findingCount', async () => {
const payload = makePayload()
// The menubar counts 25 findings, but the Fixes tab only renders topFindings.
payload.optimize = {
findingCount: 25,
savingsUSD: 94.4,
topFindings: [
{ title: 'A', impact: 'high', savingsUSD: 1 },
{ title: 'B', impact: 'low', savingsUSD: 1 },
],
}
getOverview.mockResolvedValue(payload)
render(<Optimize period="30days" provider="all" />)
expect(await screen.findByRole('tab', { name: 'Fixes 2' })).toBeInTheDocument()
expect(screen.queryByRole('tab', { name: 'Fixes 25' })).not.toBeInTheDocument()
})
it('passes provider and custom range to the optimize report and yield bridges', async () => {
render(<Optimize period="30days" provider="claude" range={{ from: '2026-07-01', to: '2026-07-11' }} />)
await screen.findByText('Opus is doing your small talk')
expect(getOptimizeReport).toHaveBeenCalledWith('30days', 'claude', { from: '2026-07-01', to: '2026-07-11' })
expect(getYield).toHaveBeenCalledWith('30days', 'claude', { from: '2026-07-01', to: '2026-07-11' })
})
it('keeps last-good yield totals and rows visible during revalidation', async () => {
getYield.mockReset().mockResolvedValueOnce(makeYield()).mockImplementation(() => new Promise<YieldJsonReport>(() => {}))
const overview = { data: makePayload(), error: null, loading: false, switching: false, lastSuccessAt: Date.now(), refresh: vi.fn() }
const { rerender } = render(<OptimizeContent period="30days" overview={overview} refreshToken={0} />)
expect(await screen.findByRole('tab', { name: 'Reverts $107.00' })).toBeInTheDocument()
fireEvent.click(screen.getByRole('tab', { name: 'Reverts $107.00' }))
expect(screen.getByText('codeburn')).toBeInTheDocument()
rerender(<OptimizeContent period="30days" overview={overview} refreshToken={1} />)
await waitFor(() => expect(getYield).toHaveBeenCalledTimes(2))
expect(screen.getByRole('tab', { name: 'Reverts $107.00' })).toBeInTheDocument()
expect(screen.getByText('codeburn')).toBeInTheDocument()
})
})