forked from romgain/jest-websocket-mock
/
saga.test.ts
117 lines (97 loc) · 3.42 KB
/
saga.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/**
* @copyright Romain Bertrand 2018
* @copyright AKiomi Kamakura 2023
*/
import type { Store } from 'redux';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { WS } from 'vitest-websocket-mock';
import makeStore from '../store';
import { actions } from '../store/reducer';
let ws: WS;
let store: Store;
beforeEach(async () => {
ws = new WS('ws://localhost:8080');
store = makeStore();
await ws.connected;
ws.send('Hello there');
});
afterEach(() => {
WS.clean();
});
describe('The saga', () => {
it('connects to the websocket server', () => {
expect(store.getState().messages).toEqual([{ side: 'received', text: 'Hello there' }]);
});
it('stores new messages', () => {
ws.send('how you doin?');
expect(store.getState().messages).toEqual([
{ side: 'received', text: 'Hello there' },
{ side: 'received', text: 'how you doin?' },
]);
});
it('stores new messages received shortly one after the other', () => {
ws.send('hey');
ws.send('hey?');
ws.send('hey??');
ws.send('hey???');
expect(store.getState().messages).toEqual([
{ side: 'received', text: 'Hello there' },
{ side: 'received', text: 'hey' },
{ side: 'received', text: 'hey?' },
{ side: 'received', text: 'hey??' },
{ side: 'received', text: 'hey???' },
]);
});
it('sends messages', async () => {
store.dispatch(actions.send('oh hi Mark'));
await expect(ws).toReceiveMessage('oh hi Mark');
expect(ws).toHaveReceivedMessages(['oh hi Mark']);
expect(store.getState().messages).toEqual([
{ side: 'received', text: 'Hello there' },
{ side: 'sent', text: 'oh hi Mark' },
]);
});
it('sends messages in a quick succession', async () => {
store.dispatch(actions.send('hey'));
store.dispatch(actions.send('hey?'));
store.dispatch(actions.send('hey??'));
store.dispatch(actions.send('hey???'));
await expect(ws).toReceiveMessage('hey');
await expect(ws).toReceiveMessage('hey?');
await expect(ws).toReceiveMessage('hey??');
await expect(ws).toReceiveMessage('hey???');
expect(ws).toHaveReceivedMessages(['hey', 'hey?', 'hey??', 'hey???']);
expect(store.getState().messages).toEqual([
{ side: 'received', text: 'Hello there' },
{ side: 'sent', text: 'hey' },
{ side: 'sent', text: 'hey?' },
{ side: 'sent', text: 'hey??' },
{ side: 'sent', text: 'hey???' },
]);
});
it('marks the connection as active when it successfully connects to the ws server', () => {
expect(store.getState().connected).toBe(true);
});
it('marks the connection as inactive after a disconnect', async () => {
ws.close();
await ws.closed;
expect(store.getState().connected).toBe(false);
});
it('marks the connection as inactive after a connection error', async () => {
ws.error();
await ws.closed;
expect(store.getState().connected).toBe(false);
});
it('reconnects after losing the ws connection', async () => {
// We cannot use vi.useFakeTimers because mock-socket has to work around timing issues
const spy = vi.spyOn(window, 'setTimeout');
ws.error();
await ws.closed;
expect(store.getState().connected).toBe(false);
// Trigger our delayed reconnection
spy.mock.calls.forEach(([cb, , ...args]) => cb(...args));
await ws.connected; // reconnected!
expect(store.getState().connected).toBe(true);
spy.mockRestore();
});
});