M5: Energy view — per-metric decimal formatting and chart auto-refresh toggle

This commit is contained in:
2026-06-22 19:18:29 +02:00
parent 4767a7af60
commit 935e68846c
7 changed files with 386 additions and 26 deletions
+74
View File
@@ -274,6 +274,80 @@ describe('useMetrics', () => {
})
})
describe('useLatestReading — auto-refresh option', () => {
beforeEach(() => vi.clearAllMocks())
it('passes refetchInterval to TanStack Query when refetchIntervalMs is provided', async () => {
mockGet.mockResolvedValue({
data: { found: true, recorded_at: '2026-06-22T10:00:00Z', payload: { voltage: 230.2 } },
})
const { Wrapper } = makeWrapper()
const { useLatestReading } = await import('./hooks')
const { result } = renderHook(
() => useLatestReading('test-uuid-1', { refetchIntervalMs: 5_000 }),
{ wrapper: Wrapper },
)
await waitFor(() => expect(result.current.isSuccess).toBe(true))
// Query succeeds — refetchIntervalMs is wired through without error.
expect(result.current.data?.found).toBe(true)
})
it('works without options (no auto-refresh)', async () => {
mockGet.mockResolvedValue({
data: { found: false, recorded_at: null, payload: null },
})
const { Wrapper } = makeWrapper()
const { useLatestReading } = await import('./hooks')
const { result } = renderHook(
() => useLatestReading('test-uuid-2'),
{ wrapper: Wrapper },
)
await waitFor(() => expect(result.current.isSuccess).toBe(true))
expect(result.current.data?.found).toBe(false)
})
})
describe('useReadings — auto-refresh option', () => {
beforeEach(() => vi.clearAllMocks())
it('passes refetchInterval to TanStack Query when refetchIntervalMs is provided', async () => {
mockGet.mockResolvedValue({
data: { items: [{ recorded_at: '2026-06-22T10:00:00Z', payload: { voltage: 230.2 } }] },
})
const { Wrapper } = makeWrapper()
const { useReadings } = await import('./hooks')
const { result } = renderHook(
() => useReadings('test-uuid-1', {}, { refetchIntervalMs: 5_000 }),
{ wrapper: Wrapper },
)
await waitFor(() => expect(result.current.isSuccess).toBe(true))
// Query succeeds — refetchIntervalMs is wired through without error.
expect(result.current.data?.items).toHaveLength(1)
})
it('enforces minimum refetchInterval of 2000ms', async () => {
mockGet.mockResolvedValue({ data: { items: [] } })
const { Wrapper } = makeWrapper()
const { useReadings } = await import('./hooks')
// Pass a very small value — should be clamped to 2000ms internally.
const { result } = renderHook(
() => useReadings('test-uuid-1', {}, { refetchIntervalMs: 100 }),
{ wrapper: Wrapper },
)
await waitFor(() => expect(result.current.isSuccess).toBe(true))
// No crash; the hook accepted the option and clamped it internally.
expect(result.current.isSuccess).toBe(true)
})
})
describe('useReadings', () => {
beforeEach(() => vi.clearAllMocks())