Skip to content

Commit dca6dfd

Browse files
committed
tests: added tests for sendMessageToClient util
1 parent 9d84734 commit dca6dfd

File tree

1 file changed

+104
-1
lines changed

1 file changed

+104
-1
lines changed

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

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,48 @@
11
import { Logger } from 'winston';
22
import { mockedAddAlert } from '@tests/utils/alerting.utils.mock';
3-
import { connectionInfoFromEvent } from '@src/ws/utils';
3+
import { connectionInfoFromEvent, sendMessageToClient } from '@src/ws/utils';
44
import { Severity } from '@wallet-service/common/src/types';
55

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

0 commit comments

Comments
 (0)