added contact component test for webapp

This commit is contained in:
Roland Osborne 2023-01-24 11:45:01 -08:00
parent 9a85e1116a
commit 7f41ce6566
6 changed files with 268 additions and 53 deletions

View File

@ -89,39 +89,42 @@ export function useCardContext() {
if (cur == null) {
cur = { id: card.id, data: { articles: new Map() }, offsync: false, channels: new Map() }
}
if (cur.data.detailRevision !== card.data.detailRevision) {
if (card.data.cardDetail != null) {
cur.data.cardDetail = card.data.cardDetail;
if (cur.revision !== card.revision) {
if (cur.data.detailRevision !== card.data.detailRevision) {
if (card.data.cardDetail != null) {
cur.data.cardDetail = card.data.cardDetail;
}
else {
cur.data.cardDetail = await getCardDetail(access.current, card.id);
}
cur.data.detailRevision = card.data.detailRevision;
}
else {
cur.data.cardDetail = await getCardDetail(access.current, card.id);
if (cur.data.profileRevision !== card.data.profileRevision) {
if (card.data.cardProfile != null) {
cur.data.cardProfile = card.data.cardProfile;
}
else {
cur.data.cardProfile = await getCardProfile(access.current, card.id);
}
cur.data.profileRevision = card.data.profileRevision;
}
cur.data.detailRevision = card.data.detailRevision;
}
if (cur.data.profileRevision !== card.data.profileRevision) {
if (card.data.cardProfile != null) {
cur.data.cardProfile = card.data.cardProfile;
}
else {
cur.data.cardProfile = await getCardProfile(access.current, card.id);
}
cur.data.profileRevision = card.data.profileRevision;
}
if (cur.data.cardDetail.status === 'connected' && !cur.offsync) {
cur.data.curNotifiedView = card.data.notifiedView;
cur.data.curNotifiedProfile = card.data.notifiedProfile;
cur.data.curNotifiedArticle = card.data.notifiedArticle;
cur.data.curNotifiedChannel = card.data.notifiedChannel;
try {
await syncCard(token, cur);
}
catch (err) {
console.log(err);
cur.offsync = true;
if (cur.data.cardDetail.status === 'connected' && !cur.offsync) {
cur.data.curNotifiedView = card.data.notifiedView;
cur.data.curNotifiedProfile = card.data.notifiedProfile;
cur.data.curNotifiedArticle = card.data.notifiedArticle;
cur.data.curNotifiedChannel = card.data.notifiedChannel;
try {
await syncCard(token, cur);
}
catch (err) {
console.log(err);
cur.offsync = true;
}
}
cur.revision = card.revision;
cards.current.set(card.id, cur);
}
cards.current.set(card.id, cur);
}
else {
cards.current.delete(card.id);

View File

@ -57,28 +57,30 @@ export function useChannelContext() {
if (cur == null) {
cur = { id: channel.id, data: { } }
}
if (cur.data.detailRevision !== channel.data.detailRevision) {
if (channel.data.channelDetail != null) {
cur.data.channelDetail = channel.data.channelDetail;
if (cur.revision !== channel.revision) {
if (cur.data.detailRevision !== channel.data.detailRevision) {
if (channel.data.channelDetail != null) {
cur.data.channelDetail = channel.data.channelDetail;
}
else {
let detail = await getChannelDetail(token, channel.id);
cur.data.channelDetail = detail;
}
cur.data.detailRevision = channel.data.detailRevision;
}
else {
let detail = await getChannelDetail(token, channel.id);
cur.data.channelDetail = detail;
if (cur.data.topicRevision !== channel.data.topicRevision) {
if (channel.data.channelSummary != null) {
cur.data.channelSummary = channel.data.channelSummary;
}
else {
let summary = await getChannelSummary(token, channel.id);
cur.data.channelSummary = summary;
}
cur.data.topicRevision = channel.data.topicRevision;
}
cur.data.detailRevision = channel.data.detailRevision;
cur.revision = channel.revision;
channels.current.set(channel.id, cur);
}
if (cur.data.topicRevision !== channel.data.topicRevision) {
if (channel.data.channelSummary != null) {
cur.data.channelSummary = channel.data.channelSummary;
}
else {
let summary = await getChannelSummary(token, channel.id);
cur.data.channelSummary = summary;
}
cur.data.topicRevision = channel.data.topicRevision;
}
cur.revision = channel.revision;
channels.current.set(channel.id, cur);
}
else {
channels.current.delete(channel.id);

View File

@ -15,7 +15,6 @@ export function useContact(guid, listing, close) {
description: null,
handle: null,
node: null,
removed: false,
status: null,
busy: false,
buttonStatus: 'button idle',
@ -58,7 +57,8 @@ export function useContact(guid, listing, close) {
updateState({ logo, name, location, description, handle, node, status: 'unsaved', cardId: null });
}
else {
updateState({ removed: true });
updateState({ logo: null, name: null, cardId: null, location: null, description: null, handle: null,
node: null, status: null });
}
// eslint-disable-next-line
}, [card.state, guid, listing]);

View File

@ -181,7 +181,7 @@ test('resync contact', async () => {
fetchCards = [{
id: '000a',
revision: 1,
revision: 2,
data: {
detailRevision: 2,
profileRevision: 3,

View File

@ -299,7 +299,7 @@ test('add, update, and remove topic', async() => {
});
fetchChannels = [
{ id: '123', revision: 2, data: {
{ id: '123', revision: 3, data: {
detailRevision: 3,
topicRevision: 7,
}
@ -307,7 +307,7 @@ test('add, update, and remove topic', async() => {
];
fetchTopics = [
{ id: '888', revision: 5, data: {
{ id: '888', revision: 6, data: {
detailRevision: 4,
tagRevision: 0,
}
@ -453,7 +453,7 @@ test('load more', async() => {
fetchCards = [{
id: '000a',
revision: 1,
revision: 2,
data: {
detailRevision: 2,
profileRevision: 3,

210
net/web/test/Person.test.js Normal file
View File

@ -0,0 +1,210 @@
import React, { useState, useEffect, useContext } from 'react';
import {render, act, screen, waitFor, fireEvent} from '@testing-library/react'
import { CardContext, CardContextProvider } from 'context/CardContext';
import { ViewportContextProvider } from 'context/ViewportContext';
import { useContact } from 'session/contact/useContact.hook';
import * as fetchUtil from 'api/fetchUtil';
let contactHook;
let cardContext;
function ContactView() {
const [name, setName] = useState();
const [status, setStatus] = useState();
const { state, actions } = useContact('01ab23');
const [renderCount, setRenderCount] = useState(0);
const card = useContext(CardContext);
cardContext = card;
contactHook = actions;
useEffect(() => {
const rendered = [];
setName(state.name);
setStatus(state.status);
setRenderCount(renderCount + 1);
}, [state]);
return (
<div count={renderCount}>
<div data-testid="name">{ name }</div>
<div data-testid="status">{ status }</div>
</div>
);
}
function ContactTestApp() {
return (
<CardContextProvider>
<ViewportContextProvider>
<ContactView />
</ViewportContextProvider>
</CardContextProvider>
);
}
let fetchCards;
let fetchProfile;
let fetchDetail;
const realFetchWithTimeout = fetchUtil.fetchWithTimeout;
const realFetchWithCustomTimeout = fetchUtil.fetchWithCustomTimeout;
beforeEach(() => {
fetchCards = [];
fetchDetail = {};
fetchProfile = {};
const mockFetch = jest.fn().mockImplementation((url, options) => {
if (url.startsWith('/contact/cards?agent')) {
return Promise.resolve({
json: () => Promise.resolve(fetchCards)
});
}
else if (url.startsWith('/contact/cards/000a/profile?agent')) {
return Promise.resolve({
json: () => Promise.resolve(fetchProfile)
});
}
else if (url.startsWith('/contact/cards/000a/detail?agent')) {
return Promise.resolve({
json: () => Promise.resolve(fetchDetail)
});
}
else {
return Promise.resolve({
json: () => Promise.resolve([])
});
}
});
fetchUtil.fetchWithTimeout = mockFetch;
fetchUtil.fetchWithCustomTimeout = mockFetch;
});
afterEach(() => {
fetchUtil.fetchWithTimeout = realFetchWithTimeout;
fetchUtil.fetchWithCustomTimeout = realFetchWithCustomTimeout;
});
test('update contact name', async () => {
render(<ContactTestApp />);
await waitFor(async () => {
expect(cardContext).not.toBe(null);
expect(contactHook).not.toBe(null);
});
fetchCards = [{
id: '000a',
revision: 1,
data: {
detailRevision: 2,
profileRevision: 3,
notifiedProfile: 3,
notifiedArticle: 5,
notifiedChannel: 6,
notifiedView: 7,
cardDetail: { status: 'connected', statusUpdate: 136, token: '01ab', },
cardProfile: { guid: '01ab23', handle: 'test1', name: 'tester', imageSet: false,
seal: 'abc', version: '1.1.1', node: 'test.org' },
},
}];
await act(async () => {
cardContext.actions.setToken('abc123');
cardContext.actions.setRevision(1);
});
await waitFor(async () => {
expect(screen.getByTestId('name').textContent).toBe('tester');
expect(screen.getByTestId('status').textContent).toBe('connected');
});
fetchCards = [{
id: '000a',
revision: 2,
data: {
detailRevision: 2,
profileRevision: 4,
notifiedProfile: 3,
notifiedArticle: 5,
notifiedChannel: 6,
notifiedView: 7,
},
}];
fetchProfile = { guid: '01ab23', handle: 'test1', name: 'tested', imageSet: false,
seal: 'abc', version: '1.1.1', node: 'test.org' },
await act(async () => {
cardContext.actions.setRevision(2);
});
await waitFor(async () => {
expect(screen.getByTestId('name').textContent).toBe('tested');
expect(screen.getByTestId('status').textContent).toBe('connected');
});
fetchCards = [{
id: '000a',
revision: 2,
data: {
detailRevision: 3,
profileRevision: 4,
notifiedProfile: 3,
notifiedArticle: 5,
notifiedChannel: 6,
notifiedView: 7,
},
}];
fetchDetail = { status: 'confirmed', statusUpdate: 137 },
await act(async () => {
cardContext.actions.setRevision(3);
});
await waitFor(async () => {
expect(screen.getByTestId('name').textContent).toBe('tested');
expect(screen.getByTestId('status').textContent).toBe('connected');
});
fetchCards = [{
id: '000a',
revision: 3,
data: {
detailRevision: 3,
profileRevision: 4,
notifiedProfile: 3,
notifiedArticle: 5,
notifiedChannel: 6,
notifiedView: 7,
},
}];
fetchDetail = { status: 'confirmed', statusUpdate: 137 },
await act(async () => {
cardContext.actions.setRevision(4);
});
await waitFor(async () => {
expect(screen.getByTestId('name').textContent).toBe('tested');
expect(screen.getByTestId('status').textContent).toBe('saved');
});
fetchCards = [{
id: '000a',
revision: 4,
}];
await act(async () => {
cardContext.actions.setRevision(5);
});
await waitFor(async () => {
expect(screen.getByTestId('name').textContent).toBe('');
expect(screen.getByTestId('status').textContent).toBe('');
});
});