mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
test(web): api/index.jsx
This commit is contained in:
parent
53288d361c
commit
6d133ef724
@ -12,3 +12,11 @@ Object.defineProperty(window, 'matchMedia', {
|
|||||||
dispatchEvent: jest.fn(),
|
dispatchEvent: jest.fn(),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.fetch = () => Promise.resolve();
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.spyOn(window, 'fetch').mockImplementation(async (url, opts = {}) => {
|
||||||
|
throw new Error(`Unexpected fetch to ${url}, ${JSON.stringify(opts)}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
1
web/src/api/__mocks__/baseUrl.js
Normal file
1
web/src/api/__mocks__/baseUrl.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const baseUrl = 'http://base-url.local:5000';
|
116
web/src/api/__tests__/index.test.jsx
Normal file
116
web/src/api/__tests__/index.test.jsx
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import { h } from 'preact';
|
||||||
|
import { ApiProvider, useFetch, useApiHost } from '..';
|
||||||
|
import { render, screen } from '@testing-library/preact';
|
||||||
|
|
||||||
|
jest.mock('../baseUrl');
|
||||||
|
|
||||||
|
describe('useApiHost', () => {
|
||||||
|
test('is set from the baseUrl', async () => {
|
||||||
|
function Test() {
|
||||||
|
const apiHost = useApiHost();
|
||||||
|
return <div>{apiHost}</div>;
|
||||||
|
}
|
||||||
|
render(
|
||||||
|
<ApiProvider>
|
||||||
|
<Test />
|
||||||
|
</ApiProvider>
|
||||||
|
);
|
||||||
|
expect(screen.queryByText('http://base-url.local:5000')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('useFetch', () => {
|
||||||
|
function Test() {
|
||||||
|
const { data, status } = useFetch('/api/tacos');
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<span>{data ? data.returnData : ''}</span>
|
||||||
|
<span>{status}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
test('loads data', async () => {
|
||||||
|
const fetchSpy = jest.spyOn(window, 'fetch').mockImplementation(
|
||||||
|
(url) =>
|
||||||
|
new Promise((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve({ ok: true, json: () => Promise.resolve({ returnData: 'yep' }) });
|
||||||
|
}, 1);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
render(
|
||||||
|
<ApiProvider>
|
||||||
|
<Test />
|
||||||
|
</ApiProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(screen.queryByText('loading')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('yep')).not.toBeInTheDocument();
|
||||||
|
|
||||||
|
jest.runAllTimers();
|
||||||
|
await screen.findByText('loaded');
|
||||||
|
expect(fetchSpy).toHaveBeenCalledWith('http://base-url.local:5000/api/tacos');
|
||||||
|
|
||||||
|
expect(screen.queryByText('loaded')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('yep')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('sets error if response is not okay', async () => {
|
||||||
|
jest.spyOn(window, 'fetch').mockImplementation(
|
||||||
|
(url) =>
|
||||||
|
new Promise((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve({ ok: false });
|
||||||
|
}, 1);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
render(
|
||||||
|
<ApiProvider>
|
||||||
|
<Test />
|
||||||
|
</ApiProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(screen.queryByText('loading')).toBeInTheDocument();
|
||||||
|
jest.runAllTimers();
|
||||||
|
await screen.findByText('error');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('does not re-fetch if the query has already been made', async () => {
|
||||||
|
const fetchSpy = jest.spyOn(window, 'fetch').mockImplementation(
|
||||||
|
(url) =>
|
||||||
|
new Promise((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve({ ok: true, json: () => Promise.resolve({ returnData: 'yep' }) });
|
||||||
|
}, 1);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const { rerender } = render(
|
||||||
|
<ApiProvider>
|
||||||
|
<Test key={0} />
|
||||||
|
</ApiProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(screen.queryByText('loading')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('yep')).not.toBeInTheDocument();
|
||||||
|
|
||||||
|
jest.runAllTimers();
|
||||||
|
await screen.findByText('loaded');
|
||||||
|
expect(fetchSpy).toHaveBeenCalledWith('http://base-url.local:5000/api/tacos');
|
||||||
|
|
||||||
|
rerender(
|
||||||
|
<ApiProvider>
|
||||||
|
<Test key={1} />
|
||||||
|
</ApiProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(screen.queryByText('loaded')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('yep')).toBeInTheDocument();
|
||||||
|
|
||||||
|
jest.runAllTimers();
|
||||||
|
|
||||||
|
expect(fetchSpy).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
1
web/src/api/baseUrl.js
Normal file
1
web/src/api/baseUrl.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const baseUrl = import.meta.env.SNOWPACK_PUBLIC_API_HOST || window.baseUrl || '';
|
@ -1,9 +1,8 @@
|
|||||||
|
import { baseUrl } from './baseUrl';
|
||||||
import { h, createContext } from 'preact';
|
import { h, createContext } from 'preact';
|
||||||
import produce from 'immer';
|
import produce from 'immer';
|
||||||
import { useContext, useEffect, useReducer } from 'preact/hooks';
|
import { useContext, useEffect, useReducer } from 'preact/hooks';
|
||||||
|
|
||||||
export const ApiHost = createContext(import.meta.env.SNOWPACK_PUBLIC_API_HOST || window.baseUrl || '');
|
|
||||||
|
|
||||||
export const FetchStatus = {
|
export const FetchStatus = {
|
||||||
NONE: 'none',
|
NONE: 'none',
|
||||||
LOADING: 'loading',
|
LOADING: 'loading',
|
||||||
@ -12,11 +11,11 @@ export const FetchStatus = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const initialState = Object.freeze({
|
const initialState = Object.freeze({
|
||||||
host: import.meta.env.SNOWPACK_PUBLIC_API_HOST || window.baseUrl || '',
|
host: baseUrl,
|
||||||
queries: {},
|
queries: {},
|
||||||
});
|
});
|
||||||
export const Api = createContext(initialState);
|
|
||||||
export default Api;
|
const Api = createContext(initialState);
|
||||||
|
|
||||||
function reducer(state, { type, payload, meta }) {
|
function reducer(state, { type, payload, meta }) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -65,8 +64,12 @@ export function useFetch(url, fetchId) {
|
|||||||
async function fetchData() {
|
async function fetchData() {
|
||||||
await dispatch({ type: 'REQUEST', payload: { url, fetchId } });
|
await dispatch({ type: 'REQUEST', payload: { url, fetchId } });
|
||||||
const response = await fetch(`${state.host}${url}`);
|
const response = await fetch(`${state.host}${url}`);
|
||||||
|
try {
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
await dispatch({ type: 'RESPONSE', payload: { url, ok: response.ok, data, fetchId } });
|
await dispatch({ type: 'RESPONSE', payload: { url, ok: response.ok, data, fetchId } });
|
||||||
|
} catch (e) {
|
||||||
|
await dispatch({ type: 'RESPONSE', payload: { url, ok: false, data: null, fetchId } });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchData();
|
fetchData();
|
||||||
|
Loading…
Reference in New Issue
Block a user