Skip to content

Commit f8961c9

Browse files
committed
test: (wip) websocket server duplex connectio tests
Signed-off-by: Kevin Viglucci <[email protected]>
1 parent 93dbba2 commit f8961c9

File tree

2 files changed

+341
-0
lines changed

2 files changed

+341
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import type { Config } from "@jest/types";
2+
import { pathsToModuleNameMapper } from "ts-jest/utils";
3+
import { compilerOptions } from "../../tsconfig.json";
4+
5+
const config: Config.InitialOptions = {
6+
preset: "ts-jest",
7+
testRegex: "(\\/__tests__\\/.*|\\.(test|spec))\\.(ts)$",
8+
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
9+
// This has to match the baseUrl defined in tsconfig.json.
10+
prefix: "<rootDir>/../../",
11+
}),
12+
modulePathIgnorePatterns: [
13+
"<rootDir>/__tests__/test-utils",
14+
"<rootDir>/__tests__/*.d.ts",
15+
],
16+
collectCoverage: true,
17+
collectCoverageFrom: ["<rootDir>/src/**/*.ts", "!**/node_modules/**"],
18+
};
19+
20+
export default config;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
import { mock } from "jest-mock-extended";
2+
import {
3+
Demultiplexer,
4+
Deserializer,
5+
Flags,
6+
Frame,
7+
FrameHandler,
8+
FrameTypes,
9+
Multiplexer,
10+
serializeFrame,
11+
SetupFrame,
12+
} from "rsocket-core";
13+
import { WebsocketDuplexConnection } from "../WebsocketDuplexConnection";
14+
// import { MockSocket } from "../__mocks__/ws";
15+
import { Duplex } from "stream";
16+
17+
// const deserializer = mock<Deserializer>();
18+
19+
describe("WebsocketDuplexConnection", function () {
20+
describe("when closed", () => {
21+
it("removes listeners from the underlying socket event emitter", () => {
22+
// arrange
23+
const socketStub = mock<Duplex>();
24+
const multiplexerDemultiplexer = mock<
25+
Multiplexer & Demultiplexer & FrameHandler
26+
>();
27+
const frame = mock<Frame>();
28+
const connection = new WebsocketDuplexConnection(
29+
socketStub,
30+
frame,
31+
() => multiplexerDemultiplexer
32+
);
33+
34+
// act
35+
connection.close();
36+
37+
// assert
38+
expect(socketStub.removeAllListeners).toBeCalledWith();
39+
});
40+
41+
it("cleans up the socket resource when closed without an error", () => {
42+
// arrange
43+
const socketStub = mock<Duplex>();
44+
const multiplexerDemultiplexer = mock<
45+
Multiplexer & Demultiplexer & FrameHandler
46+
>();
47+
const frame = mock<Frame>();
48+
const connection = new WebsocketDuplexConnection(
49+
socketStub,
50+
frame,
51+
() => multiplexerDemultiplexer
52+
);
53+
54+
// act
55+
connection.close();
56+
57+
// assert
58+
expect(socketStub.end).toBeCalledWith();
59+
});
60+
61+
it("cleans up the socket resource when closed with an error", () => {
62+
// arrange
63+
const socketStub = mock<Duplex>();
64+
const multiplexerDemultiplexer = mock<
65+
Multiplexer & Demultiplexer & FrameHandler
66+
>();
67+
const frame = mock<Frame>();
68+
const connection = new WebsocketDuplexConnection(
69+
socketStub,
70+
frame,
71+
() => multiplexerDemultiplexer
72+
);
73+
74+
// act
75+
const error = new Error();
76+
connection.close(error);
77+
78+
// assert
79+
expect(socketStub.end).toBeCalledWith();
80+
});
81+
82+
it("calls the onClose callback when one is registered", () => {
83+
// arrange
84+
const socketStub = mock<Duplex>();
85+
const multiplexerDemultiplexer = mock<
86+
Multiplexer & Demultiplexer & FrameHandler
87+
>();
88+
const frame = mock<Frame>();
89+
const connection = new WebsocketDuplexConnection(
90+
socketStub,
91+
frame,
92+
() => multiplexerDemultiplexer
93+
);
94+
const onCloseCallback = jest.fn();
95+
96+
// act
97+
connection.onClose(onCloseCallback);
98+
connection.close();
99+
100+
// assert
101+
expect(onCloseCallback).toBeCalledTimes(1);
102+
expect(onCloseCallback).toBeCalledWith();
103+
});
104+
105+
it("when closed with an error it calls the onClose callback when one is registered", () => {
106+
// arrange
107+
const socketStub = mock<Duplex>();
108+
const multiplexerDemultiplexer = mock<
109+
Multiplexer & Demultiplexer & FrameHandler
110+
>();
111+
const frame = mock<Frame>();
112+
const connection = new WebsocketDuplexConnection(
113+
socketStub,
114+
frame,
115+
() => multiplexerDemultiplexer
116+
);
117+
const onCloseCallback = jest.fn();
118+
const error = new Error();
119+
120+
// act
121+
connection.onClose(onCloseCallback);
122+
connection.close(error);
123+
124+
// assert
125+
expect(onCloseCallback).toBeCalledTimes(1);
126+
expect(onCloseCallback).toBeCalledWith(error);
127+
});
128+
//
129+
// it("subsequent calls to close result in only a single invocation of onClose", () => {
130+
// const socketStub = mock<WebSocket>();
131+
// const multiplexerDemultiplexer = mock<
132+
// Multiplexer & Demultiplexer & FrameHandler
133+
// >();
134+
// const connection = new WebsocketDuplexConnection(
135+
// socketStub,
136+
// deserializer,
137+
// () => multiplexerDemultiplexer
138+
// );
139+
// const onCloseCallback = jest.fn();
140+
// const error = new Error();
141+
// connection.onClose(onCloseCallback);
142+
// connection.close(error);
143+
// connection.close(error);
144+
//
145+
// expect(onCloseCallback).toBeCalledTimes(1);
146+
// expect(onCloseCallback).toBeCalledWith(error);
147+
// });
148+
//
149+
// it("the onClose callback is called with an error when the socket is closed unexpectedly", () => {
150+
// const socket = new MockSocket() as unknown as WebSocket;
151+
// const multiplexerDemultiplexer = mock<
152+
// Multiplexer & Demultiplexer & FrameHandler
153+
// >();
154+
// const connection = new WebsocketDuplexConnection(
155+
// socket,
156+
// deserializer,
157+
// () => multiplexerDemultiplexer
158+
// );
159+
// const onCloseCallback = jest.fn();
160+
//
161+
// connection.onClose(onCloseCallback);
162+
// (socket as unknown as MockSocket).mock.close({});
163+
//
164+
// expect(onCloseCallback).toBeCalledTimes(1);
165+
// expect(onCloseCallback).toHaveBeenCalledWith(
166+
// new Error("WebsocketDuplexConnection: Socket closed unexpectedly.")
167+
// );
168+
// });
169+
//
170+
// it("the onClose callback is called with an error when the socket is closed with an error", () => {
171+
// const socket = new MockSocket() as unknown as WebSocket;
172+
// const multiplexerDemultiplexer = mock<
173+
// Multiplexer & Demultiplexer & FrameHandler
174+
// >();
175+
// const connection = new WebsocketDuplexConnection(
176+
// socket,
177+
// deserializer,
178+
// () => multiplexerDemultiplexer
179+
// );
180+
// const onCloseCallback = jest.fn();
181+
// const expectedError = new Error(
182+
// "WebsocketDuplexConnection: Test error 1"
183+
// );
184+
//
185+
// connection.onClose(onCloseCallback);
186+
// (socket as unknown as MockSocket).mock.error({ error: expectedError });
187+
//
188+
// expect(onCloseCallback).toBeCalledTimes(1);
189+
// expect(onCloseCallback).toHaveBeenCalledWith(expectedError);
190+
// });
191+
});
192+
193+
// describe("send()", () => {
194+
// const setupFrame = {
195+
// type: FrameTypes.SETUP,
196+
// dataMimeType: "application/octet-stream",
197+
// metadataMimeType: "application/octet-stream",
198+
// keepAlive: 60000,
199+
// lifetime: 300000,
200+
// metadata: Buffer.from("hello world"),
201+
// data: Buffer.from("hello world"),
202+
// resumeToken: null,
203+
// streamId: 0,
204+
// majorVersion: 1,
205+
// minorVersion: 0,
206+
// flags: Flags.METADATA,
207+
// } as SetupFrame;
208+
//
209+
// it("serializes and writes the given frame to the underlying socket", () => {
210+
// // arrange
211+
// const socketStub = mock<WebSocket>();
212+
// const multiplexerDemultiplexer = mock<
213+
// Multiplexer & Demultiplexer & FrameHandler
214+
// >();
215+
// const connection = new WebsocketDuplexConnection(
216+
// socketStub,
217+
// deserializer,
218+
// () => multiplexerDemultiplexer
219+
// );
220+
//
221+
// // act
222+
// connection.send(setupFrame);
223+
//
224+
// // assert
225+
// expect(socketStub.send).toBeCalledWith(expect.any(Buffer));
226+
// });
227+
//
228+
// it("does not write the given frame to the underlying socket when close was previously called", () => {
229+
// // arrange
230+
// const socketStub = mock<WebSocket>();
231+
// const multiplexerDemultiplexer = mock<
232+
// Multiplexer & Demultiplexer & FrameHandler
233+
// >();
234+
// const connection = new WebsocketDuplexConnection(
235+
// socketStub,
236+
// deserializer,
237+
// () => multiplexerDemultiplexer
238+
// );
239+
//
240+
// // act
241+
// connection.close();
242+
// connection.send(setupFrame);
243+
//
244+
// // assert
245+
// expect(socketStub.send).toBeCalledTimes(0);
246+
// });
247+
// });
248+
//
249+
// describe("when receiving data", () => {
250+
// const setupFrame: SetupFrame = {
251+
// type: FrameTypes.SETUP,
252+
// dataMimeType: "application/octet-stream",
253+
// metadataMimeType: "application/octet-stream",
254+
// keepAlive: 60000,
255+
// lifetime: 300000,
256+
// metadata: Buffer.from("hello world"),
257+
// data: Buffer.from("hello world"),
258+
// resumeToken: null,
259+
// streamId: 0,
260+
// majorVersion: 1,
261+
// minorVersion: 0,
262+
// flags: Flags.METADATA,
263+
// };
264+
//
265+
// describe("when buffer contains a single frame", () => {
266+
// it("deserializes received frames and calls the configured handler", () => {
267+
// // arrange
268+
// const multiplexerDemultiplexer = mock<
269+
// Multiplexer & Demultiplexer & FrameHandler
270+
// >();
271+
// const socketStub = new MockSocket() as unknown as WebSocket;
272+
// const connection = new WebsocketDuplexConnection(
273+
// socketStub,
274+
// new Deserializer(),
275+
// () => multiplexerDemultiplexer
276+
// );
277+
//
278+
// // act
279+
// (socketStub as unknown as MockSocket).mock.message({
280+
// data: serializeFrame(setupFrame),
281+
// });
282+
//
283+
// // assert
284+
// expect(multiplexerDemultiplexer.handle).toBeCalledTimes(1);
285+
//
286+
// const [call0] = multiplexerDemultiplexer.handle.mock.calls;
287+
// const [arg0] = call0;
288+
// expect(arg0).toMatchSnapshot();
289+
// });
290+
// });
291+
//
292+
// describe("causes an error", () => {
293+
// it("the connection is closed", () => {
294+
// // arrange
295+
// const multiplexerDemultiplexer = mock<
296+
// Multiplexer & Demultiplexer & FrameHandler
297+
// >();
298+
// const socketStub = new MockSocket() as unknown as WebSocket;
299+
// const deserializerStub = mock<Deserializer>();
300+
// const connection = new WebsocketDuplexConnection(
301+
// socketStub as unknown as WebSocket,
302+
// deserializerStub,
303+
// () => multiplexerDemultiplexer
304+
// );
305+
// deserializerStub.deserializeFrame.mockImplementation(() => {
306+
// throw new Error("Mock error");
307+
// });
308+
// const onCloseCallback = jest.fn();
309+
// const data = Buffer.allocUnsafe(0).toString();
310+
//
311+
// // act
312+
// connection.onClose(onCloseCallback);
313+
// (socketStub as unknown as MockSocket).mock.message({ data });
314+
//
315+
// // assert
316+
// expect(onCloseCallback).toBeCalledTimes(1);
317+
// expect(onCloseCallback).toBeCalledWith(expect.any(Error));
318+
// });
319+
// });
320+
// });
321+
});

0 commit comments

Comments
 (0)