mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
refactor of webapp listing
This commit is contained in:
parent
5dc6cc926b
commit
ef73615d20
@ -23,7 +23,6 @@ export function useCards() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
const contacts = Array.from(card.state.cards.values()).map(item => {
|
const contacts = Array.from(card.state.cards.values()).map(item => {
|
||||||
const profile = item?.data?.cardProfile;
|
const profile = item?.data?.cardProfile;
|
||||||
const detail = item?.data?.cardDetail;
|
const detail = item?.data?.cardDetail;
|
||||||
|
@ -182,11 +182,9 @@ export function useChannels() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const login = store.state['login:timestamp'];
|
const login = store.state['login:timestamp'];
|
||||||
const conversations = new Map();
|
const conversations = new Map();
|
||||||
const { sealKey } = account.state;
|
|
||||||
card.state.cards.forEach((cardValue, cardId) => {
|
card.state.cards.forEach((cardValue, cardId) => {
|
||||||
cardValue.channels.forEach((channelValue, channelId) => {
|
cardValue.channels.forEach((channelValue, channelId) => {
|
||||||
const key = `${channelId}::${cardId}`;
|
const key = `${channelId}::${cardId}`;
|
||||||
const { detailRevision, topicRevision } = channelValue.data;
|
|
||||||
let item = channels.current.get(key);
|
let item = channels.current.get(key);
|
||||||
if (!item) {
|
if (!item) {
|
||||||
item = { cardId, channelId };
|
item = { cardId, channelId };
|
||||||
@ -196,6 +194,7 @@ export function useChannels() {
|
|||||||
syncChannelSummary(item, channelValue);
|
syncChannelSummary(item, channelValue);
|
||||||
|
|
||||||
const revision = store.state[key];
|
const revision = store.state[key];
|
||||||
|
const topicRevision = channelValue.data?.topicRevision;
|
||||||
if (login && item.updated && item.updated > login && topicRevision !== revision) {
|
if (login && item.updated && item.updated > login && topicRevision !== revision) {
|
||||||
item.updatedFlag = true;
|
item.updatedFlag = true;
|
||||||
}
|
}
|
||||||
@ -207,7 +206,6 @@ export function useChannels() {
|
|||||||
});
|
});
|
||||||
channel.state.channels.forEach((channelValue, channelId) => {
|
channel.state.channels.forEach((channelValue, channelId) => {
|
||||||
const key = `${channelId}::${undefined}`;
|
const key = `${channelId}::${undefined}`;
|
||||||
const { detailRevision, topicRevision } = channelValue.data;
|
|
||||||
let item = channels.current.get(key);
|
let item = channels.current.get(key);
|
||||||
if (!item) {
|
if (!item) {
|
||||||
item = { channelId };
|
item = { channelId };
|
||||||
@ -216,6 +214,7 @@ export function useChannels() {
|
|||||||
syncChannelSummary(item, channelValue);
|
syncChannelSummary(item, channelValue);
|
||||||
|
|
||||||
const revision = store.state[key];
|
const revision = store.state[key];
|
||||||
|
const topicRevision = channelValue.data?.topicRevision;
|
||||||
if (login && item.updated && item.updated > login && topicRevision !== revision) {
|
if (login && item.updated && item.updated > login && topicRevision !== revision) {
|
||||||
item.updatedFlag = true;
|
item.updatedFlag = true;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import { ListingItem } from './listingItem/ListingItem';
|
|||||||
|
|
||||||
export function Listing({ closeListing, openContact }) {
|
export function Listing({ closeListing, openContact }) {
|
||||||
|
|
||||||
|
const [ modal, modalContext ] = Modal.useModal();
|
||||||
const { state, actions } = useListing();
|
const { state, actions } = useListing();
|
||||||
|
|
||||||
const getListing = async () => {
|
const getListing = async () => {
|
||||||
@ -14,7 +15,7 @@ export function Listing({ closeListing, openContact }) {
|
|||||||
}
|
}
|
||||||
catch(err) {
|
catch(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
Modal.error({
|
modal.error({
|
||||||
title: 'Communication Error',
|
title: 'Communication Error',
|
||||||
content: 'Please confirm your server name.',
|
content: 'Please confirm your server name.',
|
||||||
});
|
});
|
||||||
@ -23,6 +24,7 @@ export function Listing({ closeListing, openContact }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ListingWrapper>
|
<ListingWrapper>
|
||||||
|
{ modalContext }
|
||||||
<div class="search">
|
<div class="search">
|
||||||
{ !state.showFilter && (
|
{ !state.showFilter && (
|
||||||
<div class="showfilter" onClick={actions.showFilter}>
|
<div class="showfilter" onClick={actions.showFilter}>
|
||||||
@ -64,7 +66,7 @@ export function Listing({ closeListing, openContact }) {
|
|||||||
{ state.contacts.length > 0 && (
|
{ state.contacts.length > 0 && (
|
||||||
<List local={{ emptyText: '' }} itemLayout="horizontal" dataSource={state.contacts} gutter="0"
|
<List local={{ emptyText: '' }} itemLayout="horizontal" dataSource={state.contacts} gutter="0"
|
||||||
renderItem={item => (
|
renderItem={item => (
|
||||||
<ListingItem item={item} node={state.node} open={openContact} />
|
<ListingItem item={item} open={() => openContact(item.guid, item)} />
|
||||||
)} />
|
)} />
|
||||||
)}
|
)}
|
||||||
{ state.contacts.length === 0 && (
|
{ state.contacts.length === 0 && (
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
import { ListingItemWrapper } from './ListingItem.styled';
|
import { ListingItemWrapper } from './ListingItem.styled';
|
||||||
import { useListingItem } from './useListingItem.hook';
|
|
||||||
import { Logo } from 'logo/Logo';
|
import { Logo } from 'logo/Logo';
|
||||||
|
|
||||||
export function ListingItem({ item, node, open }) {
|
export function ListingItem({ item, open }) {
|
||||||
|
|
||||||
const { state } = useListingItem(node, item);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ListingItemWrapper onClick={() => open(item.guid, item)}>
|
<ListingItemWrapper onClick={open}>
|
||||||
<Logo url={state.logo} width={32} height={32} radius={8} />
|
<Logo url={item.logo} width={32} height={32} radius={4} />
|
||||||
<div class="details">
|
<div class="details">
|
||||||
<div class="name">{ state.name }</div>
|
<div class="name">{ item.name }</div>
|
||||||
<div class="handle">{ state.handle }</div>
|
<div class="handle">{ item.handle }</div>
|
||||||
</div>
|
</div>
|
||||||
</ListingItemWrapper>
|
</ListingItemWrapper>
|
||||||
);
|
);
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
import { useState, useEffect } from 'react';
|
|
||||||
import { getListingImageUrl } from 'api/getListingImageUrl';
|
|
||||||
|
|
||||||
export function useListingItem(server, item) {
|
|
||||||
|
|
||||||
const [state, setState] = useState({
|
|
||||||
});
|
|
||||||
|
|
||||||
const updateState = (value) => {
|
|
||||||
setState((s) => ({ ...s, ...value }));
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
updateState({
|
|
||||||
logo: item.imageSet ? getListingImageUrl(server, item.guid) : null,
|
|
||||||
name: item.name,
|
|
||||||
handle: item.handle,
|
|
||||||
});
|
|
||||||
}, [server, item]);
|
|
||||||
|
|
||||||
const actions = {
|
|
||||||
};
|
|
||||||
|
|
||||||
return { state, actions };
|
|
||||||
}
|
|
||||||
|
|
@ -2,17 +2,18 @@ import { useContext, useState, useEffect } from 'react';
|
|||||||
import { ProfileContext } from 'context/ProfileContext';
|
import { ProfileContext } from 'context/ProfileContext';
|
||||||
import { ViewportContext } from 'context/ViewportContext';
|
import { ViewportContext } from 'context/ViewportContext';
|
||||||
import { getListing } from 'api/getListing';
|
import { getListing } from 'api/getListing';
|
||||||
|
import { getListingImageUrl } from 'api/getListingImageUrl';
|
||||||
|
|
||||||
export function useListing() {
|
export function useListing() {
|
||||||
|
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
contacts: [],
|
contacts: [],
|
||||||
|
username: null,
|
||||||
node: null,
|
node: null,
|
||||||
busy: false,
|
busy: false,
|
||||||
disabled: true,
|
disabled: true,
|
||||||
display: null,
|
|
||||||
showFilter: false,
|
showFilter: false,
|
||||||
username: null,
|
display: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const profile = useContext(ProfileContext);
|
const profile = useContext(ProfileContext);
|
||||||
@ -42,9 +43,19 @@ export function useListing() {
|
|||||||
getListing: async () => {
|
getListing: async () => {
|
||||||
updateState({ busy: true });
|
updateState({ busy: true });
|
||||||
try {
|
try {
|
||||||
let contacts = await getListing(state.node, state.username);
|
const listing = await getListing(state.node, state.username);
|
||||||
let filtered = contacts.filter(contact => (contact.guid !== profile.state.identity.guid));
|
const filtered = listing.filter(item => {
|
||||||
let sorted = filtered.sort((a, b) => {
|
return item.guid !== profile.state.identity.guid;
|
||||||
|
});
|
||||||
|
const contacts = filtered.map(item => {
|
||||||
|
return {
|
||||||
|
guid: item.guid,
|
||||||
|
logo: item.imageSet ? getListingImageUrl(state.node, item.guid) : null,
|
||||||
|
name: item.name,
|
||||||
|
handle: item.handle,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const sorted = contacts.sort((a, b) => {
|
||||||
if (a?.name < b?.name) {
|
if (a?.name < b?.name) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -61,13 +72,13 @@ export function useListing() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let node = profile?.state?.identity?.node;
|
const node = profile?.state?.identity?.node;
|
||||||
updateState({ disabled: node == null || node === '', node });
|
updateState({ disabled: node == null || node === '', node });
|
||||||
}, [profile]);
|
}, [profile.state]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateState({ display: viewport.state.display });
|
updateState({ display: viewport.state.display });
|
||||||
}, [viewport]);
|
}, [viewport.state]);
|
||||||
|
|
||||||
return { state, actions };
|
return { state, actions };
|
||||||
}
|
}
|
||||||
|
172
net/web/test/Contacts.test.js
Normal file
172
net/web/test/Contacts.test.js
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
import React, { useState, useEffect, useContext } from 'react';
|
||||||
|
import {render, act, screen, waitFor, fireEvent} from '@testing-library/react'
|
||||||
|
import { AppContextProvider } from 'context/AppContext';
|
||||||
|
import { AccountContextProvider } from 'context/AccountContext';
|
||||||
|
import { ProfileContextProvider } from 'context/ProfileContext';
|
||||||
|
import { CardContext, CardContextProvider } from 'context/CardContext';
|
||||||
|
import { ChannelContextProvider } from 'context/ChannelContext';
|
||||||
|
import { StoreContextProvider } from 'context/StoreContext';
|
||||||
|
import { UploadContextProvider } from 'context/UploadContext';
|
||||||
|
import { ViewportContextProvider } from 'context/ViewportContext';
|
||||||
|
import { useCards } from 'session/cards/useCards.hook';
|
||||||
|
import * as fetchUtil from 'api/fetchUtil';
|
||||||
|
|
||||||
|
let cardContext;
|
||||||
|
function ContactsView() {
|
||||||
|
const { state, actions } = useCards();
|
||||||
|
|
||||||
|
const [renderCount, setRenderCount] = useState(0);
|
||||||
|
const [cards, setCards] = useState([]);
|
||||||
|
const card = useContext(CardContext);
|
||||||
|
cardContext = card;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const rendered = [];
|
||||||
|
state.cards.forEach(c => {
|
||||||
|
rendered.push(
|
||||||
|
<div key={c.cardId} data-testid="card">
|
||||||
|
<span key={c.cardId} data-testid={'cardid-' + c.cardId}>{ c.name }</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
setCards(rendered);
|
||||||
|
setRenderCount(renderCount + 1);
|
||||||
|
}, [state]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div data-testid="cards" count={renderCount}>
|
||||||
|
{ cards }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ContactsTestApp() {
|
||||||
|
return (
|
||||||
|
<UploadContextProvider>
|
||||||
|
<ChannelContextProvider>
|
||||||
|
<CardContextProvider>
|
||||||
|
<ProfileContextProvider>
|
||||||
|
<StoreContextProvider>
|
||||||
|
<AccountContextProvider>
|
||||||
|
<ViewportContextProvider>
|
||||||
|
<ContactsView />
|
||||||
|
</ViewportContextProvider>
|
||||||
|
</AccountContextProvider>
|
||||||
|
</StoreContextProvider>
|
||||||
|
</ProfileContextProvider>
|
||||||
|
</CardContextProvider>
|
||||||
|
</ChannelContextProvider>
|
||||||
|
</UploadContextProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let fetchCards;
|
||||||
|
let fetchProfile;
|
||||||
|
const realFetchWithTimeout = fetchUtil.fetchWithTimeout;
|
||||||
|
const realFetchWithCustomTimeout = fetchUtil.fetchWithCustomTimeout;
|
||||||
|
beforeEach(() => {
|
||||||
|
|
||||||
|
fetchCards = [];
|
||||||
|
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 {
|
||||||
|
return Promise.resolve({
|
||||||
|
json: () => Promise.resolve([])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fetchUtil.fetchWithTimeout = mockFetch;
|
||||||
|
fetchUtil.fetchWithCustomTimeout = mockFetch;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fetchUtil.fetchWithTimeout = realFetchWithTimeout;
|
||||||
|
fetchUtil.fetchWithCustomTimeout = realFetchWithCustomTimeout;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('add, update and remove contact', async () => {
|
||||||
|
render(<ContactsTestApp />);
|
||||||
|
|
||||||
|
await waitFor(async () => {
|
||||||
|
expect(cardContext).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('cards').children).toHaveLength(1);
|
||||||
|
expect(screen.getByTestId('cardid-000a').textContent).toBe('tester');
|
||||||
|
});
|
||||||
|
|
||||||
|
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('cardid-000a').textContent).toBe('tested');
|
||||||
|
});
|
||||||
|
|
||||||
|
fetchCards = [{
|
||||||
|
id: '000a',
|
||||||
|
revision: 3,
|
||||||
|
}];
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
cardContext.actions.setRevision(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(async () => {
|
||||||
|
expect(screen.getByTestId('cards').children).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
98
net/web/test/Listing.test.js
Normal file
98
net/web/test/Listing.test.js
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
import React, { useState, useEffect, useContext } from 'react';
|
||||||
|
import {render, act, screen, waitFor, fireEvent} from '@testing-library/react'
|
||||||
|
import { ProfileContextProvider } from 'context/ProfileContext';
|
||||||
|
import { ViewportContextProvider } from 'context/ViewportContext';
|
||||||
|
import { useListing } from 'session/listing/useListing.hook';
|
||||||
|
import * as fetchUtil from 'api/fetchUtil';
|
||||||
|
|
||||||
|
let listing = null;
|
||||||
|
function ListingView() {
|
||||||
|
const { state, actions } = useListing();
|
||||||
|
const [renderCount, setRenderCount] = useState(0);
|
||||||
|
const [contacts, setContacts] = useState([]);
|
||||||
|
|
||||||
|
listing = actions;
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
const rendered = [];
|
||||||
|
state.contacts.forEach(item => {
|
||||||
|
rendered.push(
|
||||||
|
<div key={item.guid} data-testid="contact">
|
||||||
|
<span key={item.guid} data-testid={'contact-' + item.guid}>{ item.name }</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
setContacts(rendered);
|
||||||
|
setRenderCount(renderCount + 1);
|
||||||
|
}, [state]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div data-testid="contacts" count={renderCount}>
|
||||||
|
{ contacts }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ListingTestApp() {
|
||||||
|
return (
|
||||||
|
<ProfileContextProvider>
|
||||||
|
<ViewportContextProvider>
|
||||||
|
<ListingView />
|
||||||
|
</ViewportContextProvider>
|
||||||
|
</ProfileContextProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let fetchListing;
|
||||||
|
const realFetchWithTimeout = fetchUtil.fetchWithTimeout;
|
||||||
|
const realFetchWithCustomTimeout = fetchUtil.fetchWithCustomTimeout;
|
||||||
|
beforeEach(() => {
|
||||||
|
fetchListing = [];
|
||||||
|
|
||||||
|
const mockFetch = jest.fn().mockImplementation((url, options) => {
|
||||||
|
|
||||||
|
return Promise.resolve({
|
||||||
|
json: () => Promise.resolve(fetchListing)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
fetchUtil.fetchWithTimeout = mockFetch;
|
||||||
|
fetchUtil.fetchWithCustomTimeout = mockFetch;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fetchUtil.fetchWithTimeout = realFetchWithTimeout;
|
||||||
|
fetchUtil.fetchWithCustomTimeout = realFetchWithCustomTimeout;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('retrieve listing', async () => {
|
||||||
|
render(<ListingTestApp />);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(listing).not.toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
fetchListing = [
|
||||||
|
{
|
||||||
|
guid: 'abc123',
|
||||||
|
handle: 'tester',
|
||||||
|
name: 'mr. tester',
|
||||||
|
description: 'a tester',
|
||||||
|
location: 'here',
|
||||||
|
imageSet: false,
|
||||||
|
version: '0.0.1',
|
||||||
|
node: 'test.org',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
await listing.getListing();
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(async () => {
|
||||||
|
expect(screen.getByTestId('contact-abc123').textContent).toBe('mr. tester');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
import React, { useState, useEffect, useContext } from 'react';
|
import React, { useState, useEffect, useContext } from 'react';
|
||||||
import {render, act, screen, waitFor, fireEvent} from '@testing-library/react'
|
import {render, act, screen, waitFor, fireEvent} from '@testing-library/react'
|
||||||
import { AppContext, AppContextProvider } from 'context/AppContext';
|
import { AppContextProvider } from 'context/AppContext';
|
||||||
import { AccountContextProvider } from 'context/AccountContext';
|
import { AccountContextProvider } from 'context/AccountContext';
|
||||||
import { ProfileContextProvider } from 'context/ProfileContext';
|
import { ProfileContextProvider } from 'context/ProfileContext';
|
||||||
import { CardContext, CardContextProvider } from 'context/CardContext';
|
import { CardContext, CardContextProvider } from 'context/CardContext';
|
||||||
@ -43,7 +43,7 @@ function TopicsView() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function AccessTestApp() {
|
function TopicsTestApp() {
|
||||||
return (
|
return (
|
||||||
<UploadContextProvider>
|
<UploadContextProvider>
|
||||||
<ChannelContextProvider>
|
<ChannelContextProvider>
|
||||||
@ -107,7 +107,7 @@ afterEach(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('view merged channels', async () => {
|
test('view merged channels', async () => {
|
||||||
render(<AccessTestApp />);
|
render(<TopicsTestApp />);
|
||||||
|
|
||||||
await waitFor(async () => {
|
await waitFor(async () => {
|
||||||
expect(cardContext).not.toBe(null);
|
expect(cardContext).not.toBe(null);
|
||||||
|
Loading…
Reference in New Issue
Block a user