Skip to content

Commit 5a4d94b

Browse files
committed
tests: added tests for sendMessageToClient util
1 parent d2fe54f commit 5a4d94b

File tree

1 file changed

+105
-1
lines changed

1 file changed

+105
-1
lines changed

packages/wallet-service/tests/ws.utils.test.ts

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,47 @@
11
import { mockedAddAlert } from '@tests/utils/alerting.utils.mock';
2-
import { connectionInfoFromEvent } from '@src/ws/utils';
2+
import { connectionInfoFromEvent, sendMessageToClient } from '@src/ws/utils';
33
import { Severity } from '@src/types';
4+
import { Logger } from 'winston';
5+
6+
import { logger } from '@tests/winston.mock';
7+
import { RedisClient } from 'redis';
8+
import {
9+
GoneException,
10+
} from '@aws-sdk/client-apigatewaymanagementapi';
11+
import { RedisConfig } from '@src/types';
12+
13+
const mockedSend = jest.fn();
14+
15+
jest.mock('@src/redis', () => {
16+
const originalModule = jest.requireActual('@src/redis');
17+
return {
18+
...originalModule,
19+
endWsConnection: jest.fn(),
20+
};
21+
});
22+
23+
jest.mock('@aws-sdk/client-apigatewaymanagementapi', () => {
24+
const originalModule = jest.requireActual('@aws-sdk/client-apigatewaymanagementapi');
25+
return {
26+
...originalModule,
27+
ApiGatewayManagementApiClient: jest.fn().mockImplementation(() => ({
28+
send: mockedSend,
29+
})),
30+
};
31+
});
32+
33+
jest.mock('redis', () => ({
34+
RedisClient: jest.fn().mockImplementation(() => ({
35+
endWsConnection: jest.fn(),
36+
on: jest.fn(),
37+
set: jest.fn(),
38+
get: jest.fn(),
39+
del: jest.fn(),
40+
quit: jest.fn(),
41+
})),
42+
}));
43+
44+
import { endWsConnection } from '@src/redis';
445

546
test('connectionInfoFromEvent', async () => {
647
expect.hasAssertions();
@@ -42,3 +83,66 @@ test('missing WS_DOMAIN should throw', () => {
4283
Severity.MINOR,
4384
);
4485
});
86+
87+
describe('sendMessageToClient', () => {
88+
let client: any;
89+
const redisConfig: RedisConfig = {
90+
url: 'http://doesntmatter.com',
91+
password: 'password',
92+
};
93+
const connInfo = { url: 'http://example.com', id: '1234' };
94+
const message = 'hello';
95+
96+
beforeEach(() => {
97+
jest.clearAllMocks();
98+
client = new RedisClient(redisConfig);
99+
});
100+
101+
it('should send a message successfully', async () => {
102+
mockedSend.mockResolvedValue({
103+
$metadata: { httpStatusCode: 200 },
104+
});
105+
106+
await sendMessageToClient(client, connInfo, message);
107+
108+
expect(mockedSend).toHaveBeenCalledWith(expect.objectContaining({
109+
input: expect.objectContaining({
110+
ConnectionId: connInfo.id,
111+
Data: JSON.stringify(message),
112+
})
113+
}));
114+
115+
expect(logger.error).not.toHaveBeenCalled();
116+
});
117+
118+
it('should log and throw an error if API Gateway returns non-200 status', async () => {
119+
mockedSend.mockResolvedValue({
120+
$metadata: { httpStatusCode: 400 },
121+
});
122+
123+
await sendMessageToClient(client, connInfo, message);
124+
125+
expect(mockedAddAlert).toHaveBeenCalledWith(
126+
'Unhandled error while sending websocket message to client',
127+
'The wallet-service was unable to handle an error while attempting to send a message to a websocket client. Please check the logs.',
128+
Severity.MINOR,
129+
{
130+
ConnectionId: connInfo.id,
131+
Message: JSON.stringify(message),
132+
},
133+
expect.any(Logger),
134+
);
135+
});
136+
137+
it('should handle GoneException by closing the connection', async () => {
138+
mockedSend.mockRejectedValue(new GoneException({
139+
message: 'Connection is gone.',
140+
$metadata: {
141+
httpStatusCode: 410,
142+
}
143+
}));
144+
145+
await sendMessageToClient(client, connInfo, message);
146+
expect(endWsConnection).toHaveBeenCalledWith(client, connInfo.id);
147+
});
148+
});

0 commit comments

Comments
 (0)