databag/net/web/test/Channel.test.tsx

301 lines
7.9 KiB
TypeScript
Raw Normal View History

2023-01-04 23:27:29 +00:00
import React, { useState, useEffect, useContext } from 'react';
2024-04-25 20:29:25 +00:00
import { prettyDOM } from '@testing-library/dom';
import { render, act, screen, waitFor, fireEvent } from '@testing-library/react';
2023-01-04 23:27:29 +00:00
import { ChannelContextProvider, ChannelContext } from 'context/ChannelContext';
import * as fetchUtil from 'api/fetchUtil';
let channelContext = null;
function ChannelView() {
const [renderCount, setRenderCount] = useState(0);
2023-01-05 00:59:38 +00:00
const [channels, setChannels] = useState([]);
2023-01-04 23:27:29 +00:00
const channel = useContext(ChannelContext);
channelContext = channel;
useEffect(() => {
2024-04-25 20:29:25 +00:00
const rendered = [];
2023-01-05 00:59:38 +00:00
const entries = Array.from(channel.state.channels.values());
2024-04-25 20:29:25 +00:00
entries.forEach((entry) => {
2023-01-05 00:59:38 +00:00
rendered.push(
2024-04-25 20:29:25 +00:00
<div
key={entry.id}
data-testid="channel"
>
<span data-testid="detail">{entry.data.channelDetail.data}</span>
<span data-testid="summary">{entry.data.channelSummary.data}</span>
</div>,
);
2023-01-05 00:59:38 +00:00
});
setChannels(rendered);
2023-01-04 23:27:29 +00:00
setRenderCount(renderCount + 1);
2024-04-25 20:29:25 +00:00
}, [channel.state]);
2023-01-04 23:27:29 +00:00
return (
//@ts-ignore
2024-04-25 20:29:25 +00:00
<div
data-testid="channels"
count={renderCount}
offsync={channel.state.offsync.toString()}
>
{channels}
2023-01-04 23:27:29 +00:00
</div>
);
}
function ChannelTestApp() {
return (
<ChannelContextProvider>
<ChannelView />
</ChannelContextProvider>
2024-04-25 20:29:25 +00:00
);
2023-01-04 23:27:29 +00:00
}
const realFetchWithTimeout = fetchUtil.fetchWithTimeout;
const realFetchWithCustomTimeout = fetchUtil.fetchWithCustomTimeout;
2023-01-05 20:30:35 +00:00
let statusDetail;
let statusSummary;
let statusChannels;
let fetchDetail;
let fetchSummary;
let fetchChannels;
2023-01-05 22:33:06 +00:00
let addedChannel;
let removedChannel;
let updatedChannel;
let addedCard;
let removedCard;
2023-01-04 23:27:29 +00:00
beforeEach(() => {
2023-01-05 20:30:35 +00:00
statusDetail = 200;
statusSummary = 200;
statusChannels = 200;
fetchDetail = {};
fetchSummary = {};
2024-04-25 20:29:25 +00:00
fetchChannels = [];
2023-01-05 22:33:06 +00:00
addedChannel = [];
updatedChannel = [];
removedChannel = [];
addedCard = [];
removedCard = [];
2023-01-05 05:00:36 +00:00
const mockFetch = jest.fn().mockImplementation((url, options) => {
2023-01-05 22:33:06 +00:00
if (options.method === 'POST') {
addedChannel.push(options.body);
2023-01-05 00:59:38 +00:00
return Promise.resolve({
2023-01-05 22:33:06 +00:00
status: 200,
json: () => Promise.resolve({ id: 'id1' }),
});
2024-04-25 20:29:25 +00:00
} else if (options.method === 'PUT') {
2023-01-05 22:33:06 +00:00
const params = url.split('/');
if (params[4] === 'cards') {
addedCard.push(params[5].split('?')[0]);
2024-04-25 20:29:25 +00:00
} else {
2023-01-05 22:33:06 +00:00
updatedChannel.push({ id: params[3], body: options.body });
}
return Promise.resolve({
status: 200,
json: () => Promise.resolve({}),
});
2024-04-25 20:29:25 +00:00
} else if (options.method === 'DELETE') {
2023-01-05 22:33:06 +00:00
const params = url.split('/');
if (params[4] === 'cards') {
removedCard.push(params[5].split('?')[0]);
2024-04-25 20:29:25 +00:00
} else {
2023-01-05 22:33:06 +00:00
removedChannel.push(params[3].split('?')[0]);
}
return Promise.resolve({
status: 200,
json: () => Promise.resolve(),
});
2024-04-25 20:29:25 +00:00
} else if (url.includes('detail')) {
2023-01-05 22:33:06 +00:00
return Promise.resolve({
url: 'getDetail',
2023-01-05 20:30:35 +00:00
status: statusDetail,
2023-01-05 05:00:36 +00:00
json: () => Promise.resolve(fetchDetail),
2023-01-05 00:59:38 +00:00
});
2024-04-25 20:29:25 +00:00
} else if (url.includes('summary')) {
2023-01-05 00:59:38 +00:00
return Promise.resolve({
2023-01-05 22:33:06 +00:00
url: 'getSummary',
2023-01-05 20:30:35 +00:00
status: statusSummary,
2023-01-05 05:00:36 +00:00
json: () => Promise.resolve(fetchSummary),
2023-01-05 00:59:38 +00:00
});
2024-04-25 20:29:25 +00:00
} else {
2023-01-05 00:59:38 +00:00
return Promise.resolve({
2023-01-05 22:33:06 +00:00
url: 'getChannels',
status: statusChannels,
2023-01-05 05:00:36 +00:00
json: () => Promise.resolve(fetchChannels),
2023-01-05 00:59:38 +00:00
});
}
2023-01-05 05:00:36 +00:00
});
//@ts-ignore
2023-01-05 05:00:36 +00:00
fetchUtil.fetchWithTimeout = mockFetch;
//@ts-ignore
2023-01-05 05:00:36 +00:00
fetchUtil.fetchWithCustomTimeout = mockFetch;
});
afterEach(() => {
//@ts-ignore
2023-01-05 05:00:36 +00:00
fetchUtil.fetchWithTimeout = realFetchWithTimeout;
//@ts-ignore
2023-01-05 05:00:36 +00:00
fetchUtil.fetchWithCustomTimeout = realFetchWithCustomTimeout;
});
2023-01-05 22:33:06 +00:00
test('api invocation', async () => {
2023-01-04 23:27:29 +00:00
render(<ChannelTestApp />);
await waitFor(async () => {
expect(channelContext).not.toBe(null);
});
2024-04-25 20:29:25 +00:00
await act(async () => {
2023-01-05 22:33:06 +00:00
channelContext.actions.setToken('abc123');
});
await act(async () => {
await channelContext.actions.addChannel('testtype', 'testsubject', ['testcard']);
await channelContext.actions.setChannelSubject('123', 'testtype', 'testsubject');
await channelContext.actions.setChannelCard('123', 'newcard');
await channelContext.actions.clearChannelCard('123', 'newcard');
await channelContext.actions.removeChannel('123');
});
await waitFor(async () => {
expect(addedChannel.length).toBe(1);
const added = JSON.parse(addedChannel[0]);
expect(added.dataType).toBe('testtype');
expect(updatedChannel.length).toBe(1);
expect(updatedChannel[0].id).toBe('123');
expect(removedChannel.length).toBe(1);
expect(removedChannel[0]).toBe('123');
expect(addedCard.length).toBe(1);
expect(addedCard[0]).toBe('newcard');
expect(addedCard[0]).toBe('newcard');
});
2024-04-25 20:29:25 +00:00
await act(async () => {
2023-01-05 22:33:06 +00:00
channelContext.actions.clearToken();
});
});
test('add, update and remove channel', async () => {
render(<ChannelTestApp />);
fetchDetail = { dataType: 'superbasic', data: 'testdata' };
fetchSummary = { guid: '11', dataType: 'superbasictopic', data: 'testdata' };
2023-01-05 05:00:36 +00:00
fetchChannels = [
2024-04-25 20:29:25 +00:00
{
id: '123',
revision: 2,
data: {
2023-01-05 05:00:36 +00:00
detailRevision: 3,
topicRevision: 5,
channelSummary: { guid: '11', dataType: 'superbasictopic', data: 'testdata' },
channelDetail: { dataType: 'superbasic', data: 'testdata' },
2024-04-25 20:29:25 +00:00
},
2023-01-05 05:00:36 +00:00
},
];
2023-01-05 22:33:06 +00:00
await waitFor(async () => {
expect(channelContext).not.toBe(null);
});
2024-04-25 20:29:25 +00:00
await act(async () => {
2023-01-04 23:27:29 +00:00
channelContext.actions.setToken('abc123');
2023-01-05 22:33:06 +00:00
});
2024-04-25 20:29:25 +00:00
await act(async () => {
2023-01-04 23:27:29 +00:00
await channelContext.actions.setRevision(1);
});
2023-01-05 00:59:38 +00:00
//screen.getByTestId('count').attributes.count.value
//console.log(prettyDOM(screen.getByTestId('channels')));
await waitFor(async () => {
expect(screen.getByTestId('channels').children).toHaveLength(1);
expect(screen.getByTestId('detail').textContent).toBe('testdata');
expect(screen.getByTestId('summary').textContent).toBe('testdata');
});
//@ts-ignore
2023-01-05 22:33:06 +00:00
const count = parseInt(screen.getByTestId('channels').attributes.count.value) + 1;
2023-01-05 20:30:35 +00:00
fetchChannels = [
2024-04-25 20:29:25 +00:00
{
id: '123',
revision: 3,
data: {
2023-01-05 20:30:35 +00:00
detailRevision: 4,
topicRevision: 5,
channelDetail: { dataType: 'superbasic', data: 'testdata2' },
2024-04-25 20:29:25 +00:00
},
2023-01-05 20:30:35 +00:00
},
];
2023-01-05 05:00:36 +00:00
2024-04-25 20:29:25 +00:00
await act(async () => {
2023-01-05 20:30:35 +00:00
await channelContext.actions.setRevision(2);
2023-01-05 05:00:36 +00:00
});
await waitFor(async () => {
expect(screen.getByTestId('channels').children).toHaveLength(1);
2023-01-05 20:30:35 +00:00
expect(screen.getByTestId('detail').textContent).toBe('testdata2');
//@ts-ignore
2023-01-05 22:33:06 +00:00
expect(screen.getByTestId('channels').attributes.count.value).toBe(count.toString());
});
2024-04-25 20:29:25 +00:00
fetchChannels = [{ id: '123', revision: 3 }];
2023-01-05 20:30:35 +00:00
2024-04-25 20:29:25 +00:00
await act(async () => {
2023-01-05 05:00:36 +00:00
await channelContext.actions.setRevision(2);
});
2023-01-05 20:30:35 +00:00
await waitFor(async () => {
expect(screen.getByTestId('channels').children).toHaveLength(1);
});
2024-04-25 20:29:25 +00:00
await act(async () => {
2023-01-05 20:30:35 +00:00
await channelContext.actions.setRevision(3);
});
2023-01-05 05:00:36 +00:00
await waitFor(async () => {
expect(screen.getByTestId('channels').children).toHaveLength(0);
});
2023-01-05 20:30:35 +00:00
await waitFor(async () => {
//@ts-ignore
2024-04-25 20:29:25 +00:00
expect(screen.getByTestId('channels').attributes.offsync.value).toBe('false');
2023-01-05 20:30:35 +00:00
});
2023-01-05 22:33:06 +00:00
2024-04-25 20:29:25 +00:00
await act(async () => {
2023-01-05 22:33:06 +00:00
channelContext.actions.clearToken();
});
2023-01-04 23:27:29 +00:00
});
2023-01-05 22:33:06 +00:00
test('resync', async () => {
render(<ChannelTestApp />);
await waitFor(async () => {
expect(channelContext).not.toBe(null);
});
2024-04-25 20:29:25 +00:00
await act(async () => {
2023-01-05 22:33:06 +00:00
channelContext.actions.setToken('abc123');
});
2024-04-25 20:29:25 +00:00
await act(async () => {
2023-01-05 22:33:06 +00:00
statusChannels = 500;
await channelContext.actions.setRevision(1);
});
await waitFor(async () => {
//@ts-ignore
2024-04-25 20:29:25 +00:00
expect(screen.getByTestId('channels').attributes.offsync.value).toBe('true');
2023-01-05 22:33:06 +00:00
});
2024-04-25 20:29:25 +00:00
await act(async () => {
2023-01-05 22:33:06 +00:00
statusChannels = 200;
await channelContext.actions.resync();
});
await waitFor(async () => {
//@ts-ignore
2024-04-25 20:29:25 +00:00
expect(screen.getByTestId('channels').attributes.offsync.value).toBe('false');
2023-01-05 22:33:06 +00:00
});
});