mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
testing web app context
This commit is contained in:
parent
28940671d9
commit
a371bbbc1d
@ -15,7 +15,7 @@ import { createWebsocket } from 'api/fetchUtil';
|
|||||||
|
|
||||||
export function useAppContext(websocket) {
|
export function useAppContext(websocket) {
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
disconnected: true,
|
status: 'disconnected',
|
||||||
});
|
});
|
||||||
const [appRevision, setAppRevision] = useState();
|
const [appRevision, setAppRevision] = useState();
|
||||||
|
|
||||||
@ -23,8 +23,8 @@ export function useAppContext(websocket) {
|
|||||||
const appVersion = "1.0.0";
|
const appVersion = "1.0.0";
|
||||||
const userAgent = window.navigator.userAgent;
|
const userAgent = window.navigator.userAgent;
|
||||||
|
|
||||||
|
const access = useRef(null);
|
||||||
const ws = useRef(null);
|
const ws = useRef(null);
|
||||||
const revision = useRef(null);
|
|
||||||
|
|
||||||
const updateState = (value) => {
|
const updateState = (value) => {
|
||||||
setState((s) => ({ ...s, ...value }))
|
setState((s) => ({ ...s, ...value }))
|
||||||
@ -37,21 +37,28 @@ export function useAppContext(websocket) {
|
|||||||
const channelContext = useContext(ChannelContext);
|
const channelContext = useContext(ChannelContext);
|
||||||
const cardContext = useContext(CardContext);
|
const cardContext = useContext(CardContext);
|
||||||
|
|
||||||
const resetData = () => {
|
const setSession = (token) => {
|
||||||
revision.current = null;
|
accountContext.actions.setToken(token);
|
||||||
|
profileContext.actions.setToken(token);
|
||||||
|
cardContext.actions.setToken(token);
|
||||||
|
channelContext.actions.setToken(token);
|
||||||
|
setWebsocket(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearSession = () => {
|
||||||
|
uploadContext.actions.clear();
|
||||||
|
storeContext.actions.clear();
|
||||||
|
|
||||||
accountContext.actions.clearToken();
|
accountContext.actions.clearToken();
|
||||||
profileContext.actions.clearToken();
|
profileContext.actions.clearToken();
|
||||||
cardContext.actions.clearToken();
|
cardContext.actions.clearToken();
|
||||||
channelContext.actions.clearToken();
|
channelContext.actions.clearToken();
|
||||||
setState({});
|
clearWebsocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
logout: () => {
|
logout: async () => {
|
||||||
appLogout();
|
await appLogout();
|
||||||
storeContext.actions.clear();
|
|
||||||
uploadContext.actions.clear();
|
|
||||||
resetData();
|
|
||||||
},
|
},
|
||||||
access: async (token) => {
|
access: async (token) => {
|
||||||
await appAccess(token)
|
await appAccess(token)
|
||||||
@ -62,21 +69,14 @@ export function useAppContext(websocket) {
|
|||||||
create: async (username, password, token) => {
|
create: async (username, password, token) => {
|
||||||
await appCreate(username, password, token)
|
await appCreate(username, password, token)
|
||||||
},
|
},
|
||||||
username: getUsername,
|
|
||||||
available: getAvailable,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const appCreate = async (username, password, token) => {
|
const appCreate = async (username, password, token) => {
|
||||||
await addAccount(username, password, token);
|
await addAccount(username, password, token);
|
||||||
let access = await setLogin(username, password, appName, appVersion, userAgent)
|
const access = await setLogin(username, password, appName, appVersion, userAgent);
|
||||||
updateState({ access: access.appToken });
|
|
||||||
storeContext.actions.setValue('login:timestamp', access.created);
|
storeContext.actions.setValue('login:timestamp', access.created);
|
||||||
accountContext.actions.setToken(access.appToken);
|
setSession(access.appToken);
|
||||||
profileContext.actions.setToken(access.appToken);
|
|
||||||
cardContext.actions.setToken(access.appToken);
|
|
||||||
channelContext.actions.setToken(access.appToken);
|
|
||||||
|
|
||||||
setWebsocket(access.appToken)
|
|
||||||
localStorage.setItem("session", JSON.stringify({
|
localStorage.setItem("session", JSON.stringify({
|
||||||
access: access.appToken,
|
access: access.appToken,
|
||||||
timestamp: access.created,
|
timestamp: access.created,
|
||||||
@ -85,15 +85,10 @@ export function useAppContext(websocket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const appLogin = async (username, password) => {
|
const appLogin = async (username, password) => {
|
||||||
let access = await setLogin(username, password, appName, appVersion, userAgent)
|
const access = await setLogin(username, password, appName, appVersion, userAgent);
|
||||||
updateState({ access: access.appToken });
|
|
||||||
storeContext.actions.setValue('login:timestamp', access.created);
|
storeContext.actions.setValue('login:timestamp', access.created);
|
||||||
accountContext.actions.setToken(access.appToken);
|
setSession(access.appToken);
|
||||||
profileContext.actions.setToken(access.appToken);
|
|
||||||
cardContext.actions.setToken(access.appToken);
|
|
||||||
channelContext.actions.setToken(access.appToken);
|
|
||||||
|
|
||||||
setWebsocket(access.appToken)
|
|
||||||
localStorage.setItem("session", JSON.stringify({
|
localStorage.setItem("session", JSON.stringify({
|
||||||
access: access.appToken,
|
access: access.appToken,
|
||||||
timestamp: access.created,
|
timestamp: access.created,
|
||||||
@ -102,15 +97,10 @@ export function useAppContext(websocket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const appAccess = async (token) => {
|
const appAccess = async (token) => {
|
||||||
let access = await setAccountAccess(token, appName, appVersion, userAgent)
|
const access = await setAccountAccess(token, appName, appVersion, userAgent);
|
||||||
updateState({ access: access.appToken });
|
|
||||||
storeContext.actions.setValue('login:timestamp', access.created);
|
storeContext.actions.setValue('login:timestamp', access.created);
|
||||||
accountContext.actions.setToken(access.appToken);
|
setSession(access.appToken);
|
||||||
profileContext.actions.setToken(access.appToken);
|
|
||||||
cardContext.actions.setToken(access.appToken);
|
|
||||||
channelContext.actions.setToken(access.appToken);
|
|
||||||
|
|
||||||
setWebsocket(access.appToken)
|
|
||||||
localStorage.setItem("session", JSON.stringify({
|
localStorage.setItem("session", JSON.stringify({
|
||||||
access: access.appToken,
|
access: access.appToken,
|
||||||
timestamp: access.created,
|
timestamp: access.created,
|
||||||
@ -119,21 +109,15 @@ export function useAppContext(websocket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const appLogout = async () => {
|
const appLogout = async () => {
|
||||||
|
clearSession();
|
||||||
try {
|
try {
|
||||||
await clearLogin(state.access);
|
await clearLogin(access.current);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
updateState({ access: null });
|
|
||||||
accountContext.actions.clearToken();
|
|
||||||
profileContext.actions.clearToken();
|
|
||||||
cardContext.actions.clearToken();
|
|
||||||
channelContext.actions.clearToken();
|
|
||||||
|
|
||||||
clearWebsocket()
|
|
||||||
localStorage.removeItem("session");
|
localStorage.removeItem("session");
|
||||||
}
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (appRevision) {
|
if (appRevision) {
|
||||||
@ -154,20 +138,22 @@ export function useAppContext(websocket) {
|
|||||||
protocol = 'wss://';
|
protocol = 'wss://';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateState({ status: 'connecting' });
|
||||||
ws.current = createWebsocket(protocol + window.location.host + "/status");
|
ws.current = createWebsocket(protocol + window.location.host + "/status");
|
||||||
ws.current.onmessage = (ev) => {
|
ws.current.onmessage = (ev) => {
|
||||||
try {
|
try {
|
||||||
let rev = JSON.parse(ev.data);
|
let rev = JSON.parse(ev.data);
|
||||||
|
updateState({ status: 'connected' });
|
||||||
setAppRevision(rev);
|
setAppRevision(rev);
|
||||||
updateState({ disconnected: false });
|
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
ws.current.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ws.current.onclose = (e) => {
|
ws.current.onclose = (e) => {
|
||||||
updateState({ disconnected: true });
|
|
||||||
console.log(e)
|
console.log(e)
|
||||||
|
updateState({ status: 'disconnected' });
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (ws.current != null) {
|
if (ws.current != null) {
|
||||||
ws.current.onmessage = () => {}
|
ws.current.onmessage = () => {}
|
||||||
@ -176,14 +162,15 @@ export function useAppContext(websocket) {
|
|||||||
ws.current.onerror = () => {}
|
ws.current.onerror = () => {}
|
||||||
setWebsocket(token);
|
setWebsocket(token);
|
||||||
}
|
}
|
||||||
}, 1000)
|
}, 1000);
|
||||||
}
|
}
|
||||||
ws.current.onopen = () => {
|
ws.current.onopen = () => {
|
||||||
ws.current.send(JSON.stringify({ AppToken: token }))
|
ws.current.send(JSON.stringify({ AppToken: token }))
|
||||||
}
|
}
|
||||||
ws.current.error = (e) => {
|
ws.current.error = (e) => {
|
||||||
updateState({ disconnected: true });
|
|
||||||
console.log(e)
|
console.log(e)
|
||||||
|
ws.current.close();
|
||||||
|
updateState({ status: 'disconnected' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,6 +178,7 @@ export function useAppContext(websocket) {
|
|||||||
ws.current.onclose = () => {}
|
ws.current.onclose = () => {}
|
||||||
ws.current.close()
|
ws.current.close()
|
||||||
ws.current = null
|
ws.current = null
|
||||||
|
updateState({ status: 'disconnected' });
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -199,25 +187,16 @@ export function useAppContext(websocket) {
|
|||||||
try {
|
try {
|
||||||
const session = JSON.parse(storage)
|
const session = JSON.parse(storage)
|
||||||
if (session?.access) {
|
if (session?.access) {
|
||||||
setState({ access: session.access })
|
setSession(session.access);
|
||||||
setWebsocket(session.access);
|
|
||||||
} else {
|
|
||||||
setState({})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(err) {
|
catch(err) {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
setState({})
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
setState({})
|
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (state == null) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return { state, actions }
|
return { state, actions }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,10 +12,9 @@ import { UploadContextProvider } from 'context/UploadContext';
|
|||||||
import { ViewportContextProvider } from 'context/ViewportContext';
|
import { ViewportContextProvider } from 'context/ViewportContext';
|
||||||
import { ConversationContextProvider } from 'context/ConversationContext';
|
import { ConversationContextProvider } from 'context/ConversationContext';
|
||||||
|
|
||||||
|
let mockWebsocket;
|
||||||
function MockWebsocket(url) {
|
function MockWebsocket(url) {
|
||||||
setTimeout(() => {
|
this.url = url;
|
||||||
this.onmessage({ data: JSON.stringify({ account: 1, profile: 1, card: 1, channel: 1 }) });
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let appContext = null;
|
let appContext = null;
|
||||||
@ -31,7 +30,7 @@ function AppView() {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<span data-testid="count">{ renderCount }</span>
|
<span data-testid="count">{ renderCount }</span>
|
||||||
<span data-testid="disconnected">{ app.state.disconnected ? 'true' : 'false' }</span>
|
<span data-testid="status">{ app.state.status }</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -64,7 +63,8 @@ const realFetchWithCustomTimeout = fetchUtil.fetchWithCustomTimeout;
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
||||||
const mockCreateWebsocket = jest.fn().mockImplementation((url) => {
|
const mockCreateWebsocket = jest.fn().mockImplementation((url) => {
|
||||||
return new MockWebsocket(url);
|
mockWebsocket = new MockWebsocket(url);
|
||||||
|
return mockWebsocket;
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockFetch = jest.fn().mockImplementation((url, options) => {
|
const mockFetch = jest.fn().mockImplementation((url, options) => {
|
||||||
@ -102,10 +102,29 @@ test('testing app sync', async () => {
|
|||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
appContext.actions.login('testlogin', 'testpassword');
|
appContext.actions.login('testlogin', 'testpassword');
|
||||||
|
expect(mockWebsocket?.onmessage).not.toBe(null);
|
||||||
|
expect(mockWebsocket?.onclose).not.toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
await waitFor(async () => {
|
await waitFor(async () => {
|
||||||
expect(screen.getByTestId('disconnected').textContent).toBe('false');
|
expect(screen.getByTestId('status').textContent).toBe('connecting');
|
||||||
|
});
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
mockWebsocket.onmessage({ data: JSON.stringify({ account: 1, profile: 1, card: 1, channel: 1 }) });
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(async () => {
|
||||||
|
expect(screen.getByTestId('status').textContent).toBe('connected');
|
||||||
|
});
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
mockWebsocket.onclose();
|
||||||
|
await new Promise(r => setTimeout(r, 1000));
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(async () => {
|
||||||
|
expect(screen.getByTestId('status').textContent).toBe('connecting');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user