Files
home-automation/frontend/src/energy/DsmrPanel.test.tsx
T
tliu93 e8521351d7 frontend: add DSMR data panel to Energy page
- New 'DSMR' tab showing the latest parsed telegram (GET /api/energy/dsmr/latest)
  as a key/value table — the source-of-truth view so you can see ingest is
  landing data without reading the DB.
- Auto-refresh toggle (~10s); loading/error/empty states (empty explains the
  likely cause); null phase values shown as a dash.
- useDsmrLatest extended with optional auto-refresh. Tests added.
2026-06-24 11:02:42 +02:00

83 lines
2.6 KiB
TypeScript

/**
* Tests for DsmrPanel — latest parsed DSMR telegram view.
*
* Coverage:
* 1. Loading state.
* 2. Empty state (found=false) with a helpful hint.
* 3. Renders the payload as a key/value table; null values shown as "—".
* 4. Error state.
*/
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { screen, waitFor } from '@testing-library/react'
import { renderWithProviders } from '../test-utils'
const mockGet = vi.fn()
vi.mock('../api/client', () => ({
default: {
GET: (...args: unknown[]) => mockGet(...args),
POST: vi.fn(),
PATCH: vi.fn(),
DELETE: vi.fn(),
},
ApiError: class ApiError extends Error {
status: number
body: unknown
constructor(status: number, body: unknown) {
super(`API error ${status}`)
this.name = 'ApiError'
this.status = status
this.body = body
}
},
registerLoginRedirect: vi.fn(),
}))
import { DsmrPanel } from './DsmrPanel'
describe('DsmrPanel', () => {
beforeEach(() => vi.clearAllMocks())
it('renders loading state initially', () => {
mockGet.mockImplementation(() => new Promise(() => {}))
renderWithProviders(<DsmrPanel />)
expect(screen.getByTestId('dsmr-loading')).toBeInTheDocument()
})
it('shows an empty hint when no DSMR data has been ingested', async () => {
mockGet.mockResolvedValue({ data: { found: false, recorded_at: null, payload: null } })
renderWithProviders(<DsmrPanel />)
await waitFor(() => expect(screen.getByTestId('dsmr-empty')).toBeInTheDocument())
expect(screen.queryByTestId('dsmr-table')).not.toBeInTheDocument()
})
it('renders the latest telegram as a key/value table; null shown as dash', async () => {
mockGet.mockResolvedValue({
data: {
found: true,
recorded_at: '2026-06-23T12:16:00Z',
payload: {
electricity_delivered_1: '20915.154',
phase_voltage_l2: null,
},
},
})
renderWithProviders(<DsmrPanel />)
await waitFor(() => expect(screen.getByTestId('dsmr-table')).toBeInTheDocument())
// Field rows present (keys are sorted).
expect(screen.getByTestId('dsmr-row-electricity_delivered_1')).toHaveTextContent('20915.154')
// Null phase value rendered as an em dash, not omitted.
expect(screen.getByTestId('dsmr-row-phase_voltage_l2')).toHaveTextContent('—')
expect(screen.getByTestId('dsmr-recorded-at')).toBeInTheDocument()
})
it('renders an error state when the request fails', async () => {
mockGet.mockRejectedValue(new Error('network down'))
renderWithProviders(<DsmrPanel />)
await waitFor(() => expect(screen.getByTestId('dsmr-error')).toBeInTheDocument())
})
})