/** * Tests for TibberPrices component. * * Coverage: * 1. Loading state. * 2. Empty state (no active contract / no kind). * 3. Renders tibber chart when tibber kind data is available. * 4. Shows tariff table for manual kind. */ import { describe, it, expect, vi, beforeEach } from 'vitest' import { screen, waitFor } from '@testing-library/react' import { renderWithProviders } from '../test-utils' // --------------------------------------------------------------------------- // Mock apiClient // --------------------------------------------------------------------------- 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 component // --------------------------------------------------------------------------- import { TibberPrices } from './TibberPrices' // --------------------------------------------------------------------------- // Tests // --------------------------------------------------------------------------- describe('TibberPrices', () => { beforeEach(() => vi.clearAllMocks()) it('renders loading state initially', () => { mockGet.mockImplementation(() => new Promise(() => {})) renderWithProviders() expect(screen.getByTestId('prices-loading')).toBeInTheDocument() }) it('renders "no active contract" when kind is missing/null', async () => { mockGet.mockResolvedValue({ data: { kind: null, currency: 'EUR', points: [], tariff: null, }, }) renderWithProviders() await waitFor(() => { expect(screen.getByTestId('prices-no-contract')).toBeInTheDocument() }) }) it('renders error state when fetch fails', async () => { mockGet.mockRejectedValue(new Error('Network error')) renderWithProviders() await waitFor(() => { expect(screen.getByTestId('prices-error')).toBeInTheDocument() }) }) it('renders tibber chart when tibber data is available', async () => { mockGet.mockResolvedValue({ data: { kind: 'tibber', currency: 'EUR', points: [ { starts_at: '2026-06-22T10:00:00Z', buy: 0.133, sell: 0.09, level: 'NORMAL' }, { starts_at: '2026-06-22T10:15:00Z', buy: 0.140, sell: 0.092, level: 'NORMAL' }, ], tariff: null, }, }) renderWithProviders() await waitFor(() => { expect(screen.getByTestId('tibber-chart')).toBeInTheDocument() }) // Check badge shows kind expect(screen.getByText('tibber')).toBeInTheDocument() }) it('shows tariff table for manual kind', async () => { mockGet.mockResolvedValue({ data: { kind: 'manual', currency: 'EUR', points: [], tariff: { buy_dal: 0.127, buy_normal: 0.133, sell_dal: 0.09, sell_normal: 0.09, }, }, }) renderWithProviders() await waitFor(() => { expect(screen.getByTestId('manual-tariff-table')).toBeInTheDocument() }) expect(screen.getByTestId('tariff-buy-normal')).toHaveTextContent('0.1330') expect(screen.getByTestId('tariff-buy-dal')).toHaveTextContent('0.1270') expect(screen.getByTestId('tariff-sell-normal')).toHaveTextContent('0.0900') expect(screen.getByTestId('tariff-sell-dal')).toHaveTextContent('0.0900') }) })