import { h } from 'preact'; import { Mqtt, MqttProvider, useMqtt } from '../mqtt'; import { useCallback, useContext } from 'preact/hooks'; import { fireEvent, render, screen } from '@testing-library/preact'; function Test() { const { state } = useContext(Mqtt); return state.__connected ? (
{Object.keys(state).map((key) => (
{JSON.stringify(state[key])}
))}
) : null; } const TEST_URL = 'ws://test-foo:1234/ws'; describe('MqttProvider', () => { let createWebsocket, wsClient; beforeEach(() => { wsClient = { close: jest.fn(), send: jest.fn(), }; createWebsocket = jest.fn((url) => { wsClient.args = [url]; return new Proxy( {}, { get(target, prop, receiver) { return wsClient[prop]; }, set(target, prop, value) { wsClient[prop] = typeof value === 'function' ? jest.fn(value) : value; if (prop === 'onopen') { wsClient[prop](); } return true; }, } ); }); }); test('connects to the mqtt server', async () => { render( ); await screen.findByTestId('data'); expect(wsClient.args).toEqual([TEST_URL]); expect(screen.getByTestId('__connected')).toHaveTextContent('true'); }); test('receives data through useMqtt', async () => { function Test() { const { value: { payload, retain }, connected, } = useMqtt('tacos'); return connected ? (
{JSON.stringify(payload)}
{JSON.stringify(retain)}
) : null; } const { rerender } = render( ); await screen.findByTestId('payload'); wsClient.onmessage({ data: JSON.stringify({ topic: 'tacos', payload: JSON.stringify({ yes: true }), retain: false }), }); rerender( ); expect(screen.getByTestId('payload')).toHaveTextContent('{"yes":true}'); expect(screen.getByTestId('retain')).toHaveTextContent('false'); }); test('can send values through useMqtt', async () => { function Test() { const { send, connected } = useMqtt('tacos'); const handleClick = useCallback(() => { send({ yes: true }); }, [send]); return connected ? : null; } render( ); await screen.findByRole('button'); fireEvent.click(screen.getByRole('button')); await expect(wsClient.send).toHaveBeenCalledWith( JSON.stringify({ topic: 'tacos', payload: JSON.stringify({ yes: true }) }) ); }); test('prefills the recordings/detect/snapshots state from config', async () => { jest.spyOn(Date, 'now').mockReturnValue(123456); const config = { cameras: { front: { name: 'front', detect: { enabled: true }, record: { enabled: false }, snapshots: { enabled: true } }, side: { name: 'side', detect: { enabled: false }, record: { enabled: false }, snapshots: { enabled: false } }, }, }; render( ); await screen.findByTestId('data'); expect(screen.getByTestId('front/detect/state')).toHaveTextContent('{"lastUpdate":123456,"payload":"ON","retain":true}'); expect(screen.getByTestId('front/recordings/state')).toHaveTextContent('{"lastUpdate":123456,"payload":"OFF","retain":true}'); expect(screen.getByTestId('front/snapshots/state')).toHaveTextContent('{"lastUpdate":123456,"payload":"ON","retain":true}'); expect(screen.getByTestId('side/detect/state')).toHaveTextContent('{"lastUpdate":123456,"payload":"OFF","retain":true}'); expect(screen.getByTestId('side/recordings/state')).toHaveTextContent('{"lastUpdate":123456,"payload":"OFF","retain":true}'); expect(screen.getByTestId('side/snapshots/state')).toHaveTextContent('{"lastUpdate":123456,"payload":"OFF","retain":true}'); }); }); const mockConfig = { cameras: {}, };