mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
testing conversation context for mobile app
This commit is contained in:
parent
eca43835be
commit
50fa8bf9af
@ -109,6 +109,7 @@ export function useCardContext() {
|
||||
const { notifiedView, notifiedProfile, notifiedArticle, notifiedChannel } = card.data || {};
|
||||
const cardRevision = { view: notifiedView, profile: notifiedProfile, artcile: notifiedArticle, channel: notifiedChannel };
|
||||
await syncCard(server, token, guid, entry, cardRevision);
|
||||
await store.action.clearCardItemOffsync(guid, cardId);
|
||||
entry.card.offsync = false;
|
||||
}
|
||||
|
||||
@ -164,6 +165,7 @@ export function useCardContext() {
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
entry.offsync = true;
|
||||
await store.action.setCardItemOffsync(guid, card.id);
|
||||
}
|
||||
}
|
||||
cards.current.set(card.id, entry);
|
||||
|
@ -24,7 +24,6 @@ export function useConversationContext() {
|
||||
const force = useRef(false);
|
||||
const syncing = useRef(false);
|
||||
const update = useRef(false);
|
||||
|
||||
const loaded = useRef(false);
|
||||
const conversationId = useRef(null);
|
||||
const topics = useRef(new Map());
|
||||
@ -44,7 +43,7 @@ export function useConversationContext() {
|
||||
syncing.current = true;
|
||||
update.current = false;
|
||||
force.current = false;
|
||||
loadMore.current = false;
|
||||
more.current = false;
|
||||
|
||||
if (reset.current) {
|
||||
reset.current = false;
|
||||
@ -55,8 +54,6 @@ export function useConversationContext() {
|
||||
|
||||
if (conversation) {
|
||||
const { cardId, channelId } = conversation;
|
||||
|
||||
if (loaded.current) {
|
||||
const cardValue = cardId ? card.state.cards.get(cardId) : null;
|
||||
const channelValue = cardId ? cardValue?.get(channelId) : channel.state.channels.get(channelId);
|
||||
if (channelValue) {
|
||||
@ -65,35 +62,21 @@ export function useConversationContext() {
|
||||
setRevision = syncRevision;
|
||||
marker = topicMarker;
|
||||
updateState({ card: cardValue, channel: channelValue });
|
||||
}
|
||||
else {
|
||||
console.log("failed to load conversation");
|
||||
sysncing.current = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!loaded.current) {
|
||||
const cardValue = cardId ? card.state.cards.get(cardId) : null;
|
||||
const channelValue = cardId ? cardValue?.get(channelId) : channel.state.channels.get(channelId);
|
||||
if (channelValue) {
|
||||
const { topicRevision, syncRevision, topicMarker } = channelValue;
|
||||
curRevision = topicRevision;
|
||||
setRevision = syncRevision;
|
||||
marker = topicMarker;
|
||||
const topicItems = await getTopicItems(cardId, channelId);
|
||||
for (let topic: topicItems) {
|
||||
for (let topic of topicItems) {
|
||||
topics.current.set(topic.topicId, topic);
|
||||
}
|
||||
updateState({ card: cardValue, channel: channelValue, topics: topics.current });
|
||||
updateState({ offsync: false, topics: topics.current });
|
||||
loaded.current = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log("failed to load conversation");
|
||||
syncing.current = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (!marker) {
|
||||
@ -125,7 +108,7 @@ export function useConversationContext() {
|
||||
}
|
||||
}
|
||||
|
||||
const setTopicDelta(cardId, channelId, entries) => {
|
||||
const setTopicDelta = async (cardId, channelId, entries) => {
|
||||
for (let entry of entries) {
|
||||
if (entry.data) {
|
||||
if (entry.data.detail) {
|
||||
@ -139,6 +122,7 @@ export function useConversationContext() {
|
||||
}
|
||||
}
|
||||
else {
|
||||
topics.current.delete(entry.id);
|
||||
clearTopicItem(entry.id);
|
||||
}
|
||||
}
|
||||
@ -157,7 +141,7 @@ export function useConversationContext() {
|
||||
reset.current = true;
|
||||
await sync();
|
||||
},
|
||||
clearConversation: async ()
|
||||
clearConversation: async () => {
|
||||
conversationId.current = null;
|
||||
reset.current = true;
|
||||
await sync();
|
||||
@ -216,6 +200,15 @@ export function useConversationContext() {
|
||||
await channel.actions.clearChannelCard(channelId, id);
|
||||
}
|
||||
},
|
||||
setChannelReadRevision: async (revision) => {
|
||||
const { cardId, channelId } = conversationId.current || {};
|
||||
if (cardId) {
|
||||
await card.actions.setChannelReadRevision(cardId, channelId, revision);
|
||||
}
|
||||
else if (channelId) {
|
||||
await channel.actions.setReadRevision(channelId, revision);
|
||||
}
|
||||
},
|
||||
addChannelAlert: async () => {
|
||||
const { cardId, channelId } = conversationId.current || {};
|
||||
if (cardId) {
|
||||
@ -224,7 +217,6 @@ export function useConversationContext() {
|
||||
else if (channelId) {
|
||||
return await channel.actions.addChannelAlert(channelId);
|
||||
}
|
||||
}
|
||||
},
|
||||
setChannelFlag: async () => {
|
||||
const { cardId, channelId } = conversationId.current || {};
|
||||
@ -271,7 +263,7 @@ export function useConversationContext() {
|
||||
if (cardId) {
|
||||
await card.actions.setUnsealedTopicSubject(cardId, channelId, topicId, revision, unsealed);
|
||||
}
|
||||
else {channelId) {
|
||||
else if (channelId) {
|
||||
await channel.actions.setUnsealedTopicSubject(channelId, topicId, revision, unsealed);
|
||||
}
|
||||
setTopicField(topicId, 'unsaledDetail', unsealed);
|
||||
@ -390,8 +382,8 @@ export function useConversationContext() {
|
||||
return {
|
||||
topicId: entry.id,
|
||||
revision: entry.revision,
|
||||
detailRevision = entry.data?.detailRevision,
|
||||
detail = entry.data?.topicDetail,
|
||||
detailRevision: entry.data?.detailRevision,
|
||||
detail: entry.data?.topicDetail,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -103,7 +103,7 @@ export function useStoreContext() {
|
||||
},
|
||||
setCardItem: async (guid, card) => {
|
||||
const { id, revision, data } = card;
|
||||
await db.current.executeSql(`INSERT OR REPLACE INTO card_${guid} (card_id, revision, detail_revision, profile_revision, detail, profile, notified_view, notified_profile, notified_article, notified_channel) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`, [id, revision, data.detailRevision, data.profileRevision, encodeObject(data.cardDetail), encodeObject(data.cardProfile), null, null, null, null]);
|
||||
await db.current.executeSql(`INSERT OR REPLACE INTO card_${guid} (card_id, revision, detail_revision, profile_revision, detail, profile, notified_view, notified_profile, notified_article, notified_channel) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`, [card.cardId, card.revision, card.detailRevision, card.profileRevision, encodeObject(card.detail), encodeObject(card.profile), null, null, null, null]);
|
||||
},
|
||||
clearCardItem: async (guid, cardId) => {
|
||||
await db.current.executeSql(`DELETE FROM card_${guid} WHERE card_id=?`, [cardId]);
|
||||
@ -141,24 +141,6 @@ export function useStoreContext() {
|
||||
setCardItemProfile: async (guid, cardId, revision, profile) => {
|
||||
await db.current.executeSql(`UPDATE card_${guid} set profile_revision=?, profile=? where card_id=?`, [revision, encodeObject(profile), cardId]);
|
||||
},
|
||||
getCardItemStatus: async (guid, cardId) => {
|
||||
const values = await getAppValues(db.current, `SELECT detail, profile, profile_revision, detail_revision, notified_view, notified_article, notified_profile, notified_channel, offsync FROM card_${guid} WHERE card_id=?`, [cardId]);
|
||||
if (!values.length) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
detail: decodeObject(values[0].detail),
|
||||
profile: decodeObject(values[0].profile),
|
||||
profileRevision: values[0].profile_revision,
|
||||
detailRevision: values[0].detail_revision,
|
||||
notifiedView: values[0].notified_view,
|
||||
notifiedArticle: values[0].notified_article,
|
||||
notifiedProfile: values[0].notified_profile,
|
||||
notifiedChannel: values[0].notified_channel,
|
||||
offsync: values[0].offsync,
|
||||
blocked: values[0].blocked,
|
||||
};
|
||||
},
|
||||
getCardItems: async (guid) => {
|
||||
const values = await getAppValues(db.current, `SELECT card_id, revision, detail_revision, profile_revision, detail, profile, offsync, blocked, notified_view, notified_profile, notified_article, notified_channel FROM card_${guid}`, []);
|
||||
return values.map(card => ({
|
||||
|
85
app/mobile/test/Conversation.test.js
Normal file
85
app/mobile/test/Conversation.test.js
Normal file
@ -0,0 +1,85 @@
|
||||
import React, { useState, useEffect, useContext } from 'react';
|
||||
import { View, Text } from 'react-native';
|
||||
import { useTestStoreContext } from './useTestStoreContext.hook';
|
||||
import { prettyDOM } from '@testing-library/dom';
|
||||
import {render, act, screen, waitFor, fireEvent} from '@testing-library/react-native';
|
||||
import { StoreContext } from 'context/StoreContext';
|
||||
import { ConversationContextProvider, ConversationContext } from 'context/ConversationContext';
|
||||
import { CardContextProvider, CardContext } from 'context/CardContext';
|
||||
import { ChannelContextProvider, ChannelContext } from 'context/ChannelContext';
|
||||
import * as fetchUtil from 'api/fetchUtil';
|
||||
|
||||
function ConversationView() {
|
||||
const [renderCount, setRenderCount] = useState(0);
|
||||
const conversation = useContext(ConversationContext);
|
||||
const channel = useContext(ChannelContext);
|
||||
const card = useContext(CardContext);
|
||||
const [topics, setTopics] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
setRenderCount(renderCount + 1);
|
||||
const rendered = [];
|
||||
}, [conversation.state]);
|
||||
|
||||
return (
|
||||
<View key="conversation" testID="conversation" renderCount={renderCount}
|
||||
card={card} channel={channel} conversation={conversation}>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
function ConversationTestApp() {
|
||||
return (
|
||||
<ChannelContextProvider>
|
||||
<CardContextProvider>
|
||||
<ConversationContextProvider>
|
||||
<ConversationView />
|
||||
</ConversationContextProvider>
|
||||
</CardContextProvider>
|
||||
</ChannelContextProvider>
|
||||
)
|
||||
}
|
||||
|
||||
const realUseContext = React.useContext;
|
||||
const realFetchWithTimeout = fetchUtil.fetchWithTimeout;
|
||||
const realFetchWithCustomTimeout = fetchUtil.fetchWithCustomTimeout;
|
||||
beforeEach(() => {
|
||||
const mockUseContext = jest.fn().mockImplementation((ctx) => {
|
||||
if (ctx === StoreContext) {
|
||||
return useTestStoreContext();
|
||||
}
|
||||
return realUseContext(ctx);
|
||||
});
|
||||
React.useContext = mockUseContext;
|
||||
|
||||
const mockFetch = jest.fn().mockImplementation((url, options) => {
|
||||
return Promise.resolve({
|
||||
json: () => Promise.resolve([])
|
||||
});
|
||||
});
|
||||
fetchUtil.fetchWithTimeout = mockFetch;
|
||||
fetchUtil.fetchWithCustomTimeout = mockFetch;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
React.useContext = realUseContext;
|
||||
fetchUtil.fetchWithTimeout = realFetchWithTimeout;
|
||||
fetchUtil.fetchWithCustomTimeout = realFetchWithCustomTimeout;
|
||||
});
|
||||
|
||||
test('test conversation', async () => {
|
||||
|
||||
render(<ConversationTestApp />)
|
||||
|
||||
await act(async () => {
|
||||
const channel = screen.getByTestId('conversation').props.channel;
|
||||
await channel.actions.setSession({ guid: 'abc', server: 'test.org', token: '123' });
|
||||
await channel.actions.setRevision(1);
|
||||
|
||||
const card = screen.getByTestId('conversation').props.card;
|
||||
await card.actions.setSession({ guid: 'abc', server: 'test.org', token: '123' });
|
||||
await card.actions.setRevision(1);
|
||||
//const conversation = screen.getByTestId('conversation').props.conversation;
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user