@seidor-cloud-produtos/orbit-backend-lib 2.0.110 → 2.0.112
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/clean-arch/application/cache/cache.spec.d.ts +1 -0
- package/dist/clean-arch/application/cache/cache.spec.js +178 -0
- package/dist/clean-arch/application/consistency-event-dispatcher/consistency-event-dispatcher.d.ts +1 -1
- package/dist/clean-arch/application/logger/logger.spec.d.ts +1 -0
- package/dist/clean-arch/application/logger/logger.spec.js +204 -0
- package/dist/clean-arch/domain/entities/entity.spec.d.ts +1 -0
- package/dist/clean-arch/domain/entities/entity.spec.js +130 -0
- package/dist/clean-arch/domain/events/consistency-event/consistency-event.spec.d.ts +1 -0
- package/dist/clean-arch/domain/events/consistency-event/consistency-event.spec.js +91 -0
- package/dist/clean-arch/domain/events/consistency-event/events-enum.d.ts +16 -0
- package/dist/clean-arch/domain/events/consistency-event/events-enum.js +16 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/authorization/authorization-created.d.ts +9 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/authorization/authorization-created.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/authorization/authorization-entity-event.d.ts +11 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/authorization/authorization-entity-event.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/authorization/authorization-updated.d.ts +9 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/authorization/authorization-updated.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/external-provider/external-provider-created.d.ts +9 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/external-provider/external-provider-created.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/external-provider/external-provider-entity-event.d.ts +14 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/external-provider/external-provider-entity-event.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/role/role-created.d.ts +9 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/role/role-created.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/role/role-entity-event.d.ts +13 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/role/role-entity-event.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/role/role-updated.d.ts +9 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/role/role-updated.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/tenant/tenant-created.d.ts +9 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/tenant/tenant-created.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/tenant/tenant-entity-event.d.ts +14 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/tenant/tenant-entity-event.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/tenant/tenant-updated.d.ts +9 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/tenant/tenant-updated.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/tenant-role/tenant-role-entity-event.d.ts +8 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/tenant-role/tenant-role-entity-event.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/tenant-role/tenant-role-updated.d.ts +9 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/tenant-role/tenant-role-updated.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/tenant-user/tenant-user-entity-event.d.ts +10 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/tenant-user/tenant-user-entity-event.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/tenant-user/tenant-user-updated.d.ts +9 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/tenant-user/tenant-user-updated.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/user/user-forgot-password.d.ts +9 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/user/user-forgot-password.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/user-tenant-role/user-tenant-role-entity-event.d.ts +9 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/user-tenant-role/user-tenant-role-entity-event.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/user-tenant-role/user-tenant-roles-created.d.ts +9 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/user-tenant-role/user-tenant-roles-created.js +2 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/user-tenant-role/user-tenant-roles-updated.d.ts +9 -0
- package/dist/clean-arch/domain/events/consistency-event/types/portal-admin/user-tenant-role/user-tenant-roles-updated.js +2 -0
- package/dist/clean-arch/domain/value-objects/password.spec.d.ts +1 -0
- package/dist/clean-arch/domain/value-objects/password.spec.js +90 -0
- package/dist/clean-arch/infra/adapters/http-adapters.spec.d.ts +1 -0
- package/dist/clean-arch/infra/adapters/http-adapters.spec.js +318 -0
- package/dist/clean-arch/infra/authorizations/authorizer.spec.js +43 -0
- package/dist/clean-arch/infra/cache/cache-clients.spec.d.ts +1 -0
- package/dist/clean-arch/infra/cache/cache-clients.spec.js +161 -0
- package/dist/clean-arch/infra/cache/clients/node-cache.js +3 -2
- package/dist/clean-arch/infra/consistency-event-dispatcher/exchanges-enum.d.ts +16 -0
- package/dist/clean-arch/infra/consistency-event-dispatcher/exchanges-enum.js +18 -0
- package/dist/clean-arch/infra/http/controller.spec.js +170 -51
- package/dist/clean-arch/infra/http/helpers.spec.d.ts +1 -0
- package/dist/clean-arch/infra/http/helpers.spec.js +136 -0
- package/dist/clean-arch/infra/http/net.spec.d.ts +1 -0
- package/dist/clean-arch/infra/http/net.spec.js +46 -0
- package/dist/clean-arch/infra/logger/logger-orbit.d.ts +2 -0
- package/dist/clean-arch/infra/logger/logger-orbit.spec.d.ts +1 -0
- package/dist/clean-arch/infra/logger/logger-orbit.spec.js +122 -0
- package/dist/clean-arch/infra/orbit-http-client/orbit-axios-client/orbit-axios-client.spec.d.ts +1 -0
- package/dist/clean-arch/infra/orbit-http-client/orbit-axios-client/orbit-axios-client.spec.js +143 -0
- package/dist/clean-arch/infra/orbit-notification-client/discord-client.spec.d.ts +1 -0
- package/dist/clean-arch/infra/orbit-notification-client/discord-client.spec.js +58 -0
- package/dist/clean-arch/infra/queue/queue-utils.spec.d.ts +1 -0
- package/dist/clean-arch/infra/queue/queue-utils.spec.js +170 -0
- package/dist/clean-arch/infra/queue/rabbitmq/amqp-lib.js +4 -4
- package/dist/clean-arch/infra/queue/rabbitmq/amqp-lib.spec.js +466 -89
- package/dist/clean-arch/infra/queue/rabbitmq/types.d.ts +1 -1
- package/dist/clean-arch/infra/scaledjob/amqp/runner.d.ts +0 -3
- package/dist/clean-arch/infra/scaledjob/amqp/runner.js +5 -6
- package/dist/clean-arch/infra/scaledjob/amqp/runner.spec.js +74 -84
- package/dist/clean-arch/infra/scaledjob/sqs/runner.spec.d.ts +1 -0
- package/dist/clean-arch/infra/scaledjob/sqs/runner.spec.js +150 -0
- package/dist/clean-arch/infra/tracing/start-tracing.d.ts +10 -0
- package/dist/clean-arch/infra/tracing/start-tracing.js +78 -0
- package/dist/clean-arch/infra/validations/zod/validation-zod.spec.js +23 -0
- package/dist/clean-arch/shared/pagination/get-take-and-skip.spec.d.ts +1 -0
- package/dist/clean-arch/shared/pagination/get-take-and-skip.spec.js +16 -0
- package/dist/coverage/block-navigation.d.ts +1 -0
- package/dist/coverage/block-navigation.js +72 -0
- package/dist/coverage/prettify.d.ts +0 -0
- package/dist/coverage/prettify.js +1009 -0
- package/dist/coverage/sorter.d.ts +1 -0
- package/dist/coverage/sorter.js +178 -0
- package/dist/frameworks/express/api-gateway/mapping-model.spec.js +58 -0
- package/dist/frameworks/express/authorizations/authorization-express.spec.js +9 -0
- package/dist/frameworks/express/middleware-express.spec.d.ts +1 -0
- package/dist/frameworks/express/middleware-express.spec.js +51 -0
- package/dist/frameworks/nest/nest.spec.d.ts +1 -0
- package/dist/frameworks/nest/nest.spec.js +122 -0
- package/dist/infra/http/api-gateway/mapping-model.spec.js +42 -0
- package/package.json +5 -1
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const vitest_1 = require("vitest");
|
|
5
|
+
const httpClient = {
|
|
6
|
+
get: vitest_1.vi.fn(),
|
|
7
|
+
post: vitest_1.vi.fn(),
|
|
8
|
+
};
|
|
9
|
+
vitest_1.vi.mock('axios', () => ({
|
|
10
|
+
default: {
|
|
11
|
+
create: vitest_1.vi.fn(() => httpClient),
|
|
12
|
+
},
|
|
13
|
+
}));
|
|
14
|
+
const axios_1 = tslib_1.__importDefault(require("axios"));
|
|
15
|
+
const http_error_1 = tslib_1.__importDefault(require("../../../domain/errors/http-error"));
|
|
16
|
+
const orbit_axios_client_1 = require("./orbit-axios-client");
|
|
17
|
+
class TestOrbitAxiosClient extends orbit_axios_client_1.OrbitAxiosClient {
|
|
18
|
+
getTarget() {
|
|
19
|
+
return 'target-service';
|
|
20
|
+
}
|
|
21
|
+
getBaseUrl() {
|
|
22
|
+
return 'https://example.com';
|
|
23
|
+
}
|
|
24
|
+
async sendPost() {
|
|
25
|
+
return await this.post({
|
|
26
|
+
endpoint: '/partners',
|
|
27
|
+
body: { id: '1' },
|
|
28
|
+
config: {
|
|
29
|
+
headers: {
|
|
30
|
+
authorization: 'token',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
async sendGet() {
|
|
36
|
+
return await this.get({
|
|
37
|
+
endpoint: '/partners',
|
|
38
|
+
config: {
|
|
39
|
+
headers: {
|
|
40
|
+
authorization: 'token',
|
|
41
|
+
},
|
|
42
|
+
query: {
|
|
43
|
+
page: '1',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
describe('OrbitAxiosClient', () => {
|
|
50
|
+
afterEach(() => {
|
|
51
|
+
vitest_1.vi.clearAllMocks();
|
|
52
|
+
});
|
|
53
|
+
it('should create the axios instance with the target header', () => {
|
|
54
|
+
new TestOrbitAxiosClient();
|
|
55
|
+
expect(axios_1.default.create).toHaveBeenCalledWith({
|
|
56
|
+
baseURL: 'https://example.com',
|
|
57
|
+
headers: {
|
|
58
|
+
target: 'target-service',
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
it('should map successful POST and GET responses', async () => {
|
|
63
|
+
const client = new TestOrbitAxiosClient();
|
|
64
|
+
httpClient.post.mockResolvedValue({
|
|
65
|
+
data: { id: '1' },
|
|
66
|
+
status: 201,
|
|
67
|
+
headers: {
|
|
68
|
+
'content-type': 'application/json',
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
httpClient.get.mockResolvedValue({
|
|
72
|
+
data: [{ id: '1' }],
|
|
73
|
+
status: 200,
|
|
74
|
+
headers: {
|
|
75
|
+
'content-type': 'application/json',
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
await expect(client.sendPost()).resolves.toEqual({
|
|
79
|
+
body: { id: '1' },
|
|
80
|
+
code: 201,
|
|
81
|
+
headers: {
|
|
82
|
+
'content-type': 'application/json',
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
await expect(client.sendGet()).resolves.toEqual({
|
|
86
|
+
body: [{ id: '1' }],
|
|
87
|
+
code: 200,
|
|
88
|
+
headers: {
|
|
89
|
+
'content-type': 'application/json',
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
expect(httpClient.post).toHaveBeenCalledWith('/partners', { id: '1' }, {
|
|
93
|
+
headers: {
|
|
94
|
+
authorization: 'token',
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
expect(httpClient.get).toHaveBeenCalledWith('/partners', {
|
|
98
|
+
headers: {
|
|
99
|
+
authorization: 'token',
|
|
100
|
+
},
|
|
101
|
+
params: {
|
|
102
|
+
page: '1',
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
it('should convert axios errors into HttpError', async () => {
|
|
107
|
+
const client = new TestOrbitAxiosClient();
|
|
108
|
+
httpClient.post.mockRejectedValue({
|
|
109
|
+
response: {
|
|
110
|
+
data: {
|
|
111
|
+
message: 'Integration failed',
|
|
112
|
+
},
|
|
113
|
+
headers: {
|
|
114
|
+
'x-request-id': 'request-id',
|
|
115
|
+
},
|
|
116
|
+
status: 502,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
await expect(client.sendPost()).rejects.toBeInstanceOf(http_error_1.default);
|
|
120
|
+
await expect(client.sendPost()).rejects.toEqual(expect.objectContaining({
|
|
121
|
+
message: 'Integration failed',
|
|
122
|
+
code: 502,
|
|
123
|
+
response: {
|
|
124
|
+
body: {
|
|
125
|
+
message: 'Integration failed',
|
|
126
|
+
},
|
|
127
|
+
headers: {
|
|
128
|
+
'x-request-id': 'request-id',
|
|
129
|
+
},
|
|
130
|
+
code: 502,
|
|
131
|
+
},
|
|
132
|
+
}));
|
|
133
|
+
});
|
|
134
|
+
it('should use the default HttpError message and code when axios error is incomplete', async () => {
|
|
135
|
+
const client = new TestOrbitAxiosClient();
|
|
136
|
+
httpClient.get.mockRejectedValue({});
|
|
137
|
+
await expect(client.sendGet()).rejects.toBeInstanceOf(http_error_1.default);
|
|
138
|
+
await expect(client.sendGet()).rejects.toEqual(expect.objectContaining({
|
|
139
|
+
message: 'Integration error',
|
|
140
|
+
code: 400,
|
|
141
|
+
}));
|
|
142
|
+
});
|
|
143
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const sendMock = vitest_1.vi.fn().mockResolvedValue(undefined);
|
|
5
|
+
const destroyMock = vitest_1.vi.fn();
|
|
6
|
+
const setAuthorMock = vitest_1.vi.fn().mockReturnThis();
|
|
7
|
+
const setColorMock = vitest_1.vi.fn().mockReturnThis();
|
|
8
|
+
const setTitleMock = vitest_1.vi.fn().mockReturnThis();
|
|
9
|
+
const setDescriptionMock = vitest_1.vi.fn().mockReturnThis();
|
|
10
|
+
vitest_1.vi.mock('discord.js', () => ({
|
|
11
|
+
EmbedBuilder: vitest_1.vi.fn().mockImplementation(() => ({
|
|
12
|
+
setAuthor: setAuthorMock,
|
|
13
|
+
setColor: setColorMock,
|
|
14
|
+
setTitle: setTitleMock,
|
|
15
|
+
setDescription: setDescriptionMock,
|
|
16
|
+
})),
|
|
17
|
+
WebhookClient: vitest_1.vi.fn().mockImplementation(() => ({
|
|
18
|
+
send: sendMock,
|
|
19
|
+
destroy: destroyMock,
|
|
20
|
+
})),
|
|
21
|
+
}));
|
|
22
|
+
const discord_js_1 = require("discord.js");
|
|
23
|
+
const discord_client_1 = require("./discord-client");
|
|
24
|
+
class TestDiscordClient extends discord_client_1.OrbitDiscordNotificationClient {
|
|
25
|
+
getId() {
|
|
26
|
+
return 'discord-id';
|
|
27
|
+
}
|
|
28
|
+
getToken() {
|
|
29
|
+
return 'discord-token';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
describe('OrbitDiscordNotificationClient', () => {
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
vitest_1.vi.clearAllMocks();
|
|
35
|
+
});
|
|
36
|
+
it('should send error notifications through the webhook client', async () => {
|
|
37
|
+
const client = new TestDiscordClient();
|
|
38
|
+
await client.sendErrorNotification('API', 'Failure', 'Stacktrace');
|
|
39
|
+
expect(discord_js_1.WebhookClient).toHaveBeenCalledWith({
|
|
40
|
+
id: 'discord-id',
|
|
41
|
+
token: 'discord-token',
|
|
42
|
+
});
|
|
43
|
+
expect(discord_js_1.EmbedBuilder).toHaveBeenCalledTimes(1);
|
|
44
|
+
expect(setAuthorMock).toHaveBeenCalledWith({ name: 'API' });
|
|
45
|
+
expect(setTitleMock).toHaveBeenCalledWith('Failure');
|
|
46
|
+
expect(setDescriptionMock).toHaveBeenCalledWith('```Stacktrace```');
|
|
47
|
+
expect(sendMock).toHaveBeenCalledWith({
|
|
48
|
+
embeds: [expect.any(Object)],
|
|
49
|
+
});
|
|
50
|
+
expect(destroyMock).toHaveBeenCalledTimes(1);
|
|
51
|
+
});
|
|
52
|
+
it('should swallow webhook errors', async () => {
|
|
53
|
+
const client = new TestDiscordClient();
|
|
54
|
+
sendMock.mockRejectedValueOnce(new Error('failed'));
|
|
55
|
+
await expect(client.sendErrorNotification('API', 'Failure', 'Stacktrace')).resolves.toBeUndefined();
|
|
56
|
+
expect(destroyMock).not.toHaveBeenCalled();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const vitest_1 = require("vitest");
|
|
5
|
+
vitest_1.vi.mock('child_process', () => ({
|
|
6
|
+
fork: vitest_1.vi.fn(),
|
|
7
|
+
}));
|
|
8
|
+
const child_process_1 = require("child_process");
|
|
9
|
+
const handler_1 = tslib_1.__importDefault(require("../../application/queue/handler"));
|
|
10
|
+
const create_consumers_1 = tslib_1.__importDefault(require("./create-consumers"));
|
|
11
|
+
const create_queues_1 = tslib_1.__importDefault(require("./create-queues"));
|
|
12
|
+
const in_memory_queue_1 = tslib_1.__importDefault(require("./in-memory/in-memory-queue"));
|
|
13
|
+
const queue_controller_1 = tslib_1.__importDefault(require("./queue-controller"));
|
|
14
|
+
const worker_1 = tslib_1.__importDefault(require("./worker"));
|
|
15
|
+
class TestHandler extends handler_1.default {
|
|
16
|
+
handleMock = vitest_1.vi.fn().mockResolvedValue(undefined);
|
|
17
|
+
constructor(simultaneity = 1, timeoutPerMessageSeconds) {
|
|
18
|
+
super();
|
|
19
|
+
this.simultaneity = simultaneity;
|
|
20
|
+
this.timeoutPerMessageSeconds = timeoutPerMessageSeconds;
|
|
21
|
+
}
|
|
22
|
+
async handle(message) {
|
|
23
|
+
await this.handleMock(message);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
class TestQueueController extends queue_controller_1.default {
|
|
27
|
+
eventHandlers = [
|
|
28
|
+
{
|
|
29
|
+
queueName: 'queue-1',
|
|
30
|
+
callback: Promise.resolve(new TestHandler()),
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
queueName: 'queue-2',
|
|
34
|
+
callback: Promise.resolve(new TestHandler()),
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
}
|
|
38
|
+
class TestCreateConsumers extends create_consumers_1.default {
|
|
39
|
+
consumers = [
|
|
40
|
+
{
|
|
41
|
+
queueName: 'queue-1',
|
|
42
|
+
configs: { durable: true },
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
queueName: 'queue-2',
|
|
46
|
+
configs: { durable: false },
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
}
|
|
50
|
+
class TestCreateQueues extends create_queues_1.default {
|
|
51
|
+
}
|
|
52
|
+
(0, vitest_1.describe)('Queue helpers', () => {
|
|
53
|
+
(0, vitest_1.beforeEach)(() => {
|
|
54
|
+
vitest_1.vi.useFakeTimers();
|
|
55
|
+
});
|
|
56
|
+
(0, vitest_1.afterEach)(() => {
|
|
57
|
+
vitest_1.vi.useRealTimers();
|
|
58
|
+
vitest_1.vi.restoreAllMocks();
|
|
59
|
+
});
|
|
60
|
+
(0, vitest_1.it)('should expose simultaneity and timeout from handlers', () => {
|
|
61
|
+
const handler = new TestHandler(3, 10);
|
|
62
|
+
(0, vitest_1.expect)(handler.getSimultaneity()).toBe(3);
|
|
63
|
+
(0, vitest_1.expect)(handler.getTimeoutPerMessageSeconds()).toBe(10);
|
|
64
|
+
});
|
|
65
|
+
(0, vitest_1.it)('should publish and consume matching in-memory queue messages', async () => {
|
|
66
|
+
const queue = new in_memory_queue_1.default();
|
|
67
|
+
const event = {
|
|
68
|
+
name: 'queue-1',
|
|
69
|
+
eventDate: new Date(),
|
|
70
|
+
};
|
|
71
|
+
const otherEvent = {
|
|
72
|
+
name: 'queue-2',
|
|
73
|
+
eventDate: new Date(),
|
|
74
|
+
};
|
|
75
|
+
const handler = new TestHandler();
|
|
76
|
+
await queue.publish('exchange', event);
|
|
77
|
+
await queue.publish('exchange', otherEvent);
|
|
78
|
+
await queue.on('queue-1', handler);
|
|
79
|
+
(0, vitest_1.expect)(handler.handleMock).toHaveBeenCalledTimes(1);
|
|
80
|
+
(0, vitest_1.expect)(handler.handleMock).toHaveBeenCalledWith({
|
|
81
|
+
exchangeName: 'exchange',
|
|
82
|
+
domainEvent: event,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
(0, vitest_1.it)('should register all queue consumers', async () => {
|
|
86
|
+
const queue = {
|
|
87
|
+
on: vitest_1.vi.fn().mockResolvedValue(undefined),
|
|
88
|
+
};
|
|
89
|
+
const controller = new TestQueueController(queue);
|
|
90
|
+
await controller.runConsumers();
|
|
91
|
+
(0, vitest_1.expect)(queue.on).toHaveBeenCalledTimes(2);
|
|
92
|
+
(0, vitest_1.expect)(queue.on).toHaveBeenNthCalledWith(1, 'queue-1', vitest_1.expect.any(TestHandler));
|
|
93
|
+
(0, vitest_1.expect)(queue.on).toHaveBeenNthCalledWith(2, 'queue-2', vitest_1.expect.any(TestHandler));
|
|
94
|
+
});
|
|
95
|
+
(0, vitest_1.it)('should create consumer topology when supported', async () => {
|
|
96
|
+
const queue = {
|
|
97
|
+
createConsumers: vitest_1.vi.fn().mockResolvedValue(undefined),
|
|
98
|
+
};
|
|
99
|
+
const controller = new TestCreateConsumers(queue);
|
|
100
|
+
await controller.createConsumers();
|
|
101
|
+
(0, vitest_1.expect)(queue.createConsumers).toHaveBeenCalledTimes(2);
|
|
102
|
+
(0, vitest_1.expect)(queue.createConsumers).toHaveBeenNthCalledWith(1, 'queue-1', {
|
|
103
|
+
durable: true,
|
|
104
|
+
});
|
|
105
|
+
(0, vitest_1.expect)(queue.createConsumers).toHaveBeenNthCalledWith(2, 'queue-2', {
|
|
106
|
+
durable: false,
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
(0, vitest_1.it)('should skip consumer topology when not supported', async () => {
|
|
110
|
+
const queue = {};
|
|
111
|
+
const controller = new TestCreateConsumers(queue);
|
|
112
|
+
await (0, vitest_1.expect)(controller.createConsumers()).resolves.toBeUndefined();
|
|
113
|
+
});
|
|
114
|
+
(0, vitest_1.it)('should create queues when supported', async () => {
|
|
115
|
+
const queue = {
|
|
116
|
+
createQueues: vitest_1.vi.fn().mockResolvedValue(undefined),
|
|
117
|
+
};
|
|
118
|
+
const controller = new TestCreateQueues(queue, [
|
|
119
|
+
{ name: 'queue-1', configs: { durable: true } },
|
|
120
|
+
{ name: 'queue-2', configs: { durable: false } },
|
|
121
|
+
]);
|
|
122
|
+
await controller.createQueues();
|
|
123
|
+
(0, vitest_1.expect)(queue.createQueues).toHaveBeenCalledTimes(2);
|
|
124
|
+
(0, vitest_1.expect)(queue.createQueues).toHaveBeenNthCalledWith(1, 'queue-1', {
|
|
125
|
+
durable: true,
|
|
126
|
+
});
|
|
127
|
+
(0, vitest_1.expect)(queue.createQueues).toHaveBeenNthCalledWith(2, 'queue-2', {
|
|
128
|
+
durable: false,
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
(0, vitest_1.it)('should skip queue creation when not supported', async () => {
|
|
132
|
+
const queue = {};
|
|
133
|
+
const controller = new TestCreateQueues(queue, [
|
|
134
|
+
{ name: 'queue-1', configs: { durable: true } },
|
|
135
|
+
]);
|
|
136
|
+
await (0, vitest_1.expect)(controller.createQueues()).resolves.toBeUndefined();
|
|
137
|
+
});
|
|
138
|
+
(0, vitest_1.it)('should restart forked workers until the retry limit', async () => {
|
|
139
|
+
const on = vitest_1.vi.fn();
|
|
140
|
+
const child = {
|
|
141
|
+
on,
|
|
142
|
+
pid: 321,
|
|
143
|
+
};
|
|
144
|
+
const consoleLog = vitest_1.vi
|
|
145
|
+
.spyOn(console, 'log')
|
|
146
|
+
.mockImplementation(() => undefined);
|
|
147
|
+
const consoleError = vitest_1.vi
|
|
148
|
+
.spyOn(console, 'error')
|
|
149
|
+
.mockImplementation(() => undefined);
|
|
150
|
+
vitest_1.vi.mocked(child_process_1.fork).mockReturnValue(child);
|
|
151
|
+
const worker = new worker_1.default('/tmp/worker.js');
|
|
152
|
+
worker.fWorker();
|
|
153
|
+
(0, vitest_1.expect)(child_process_1.fork).toHaveBeenCalledWith('/tmp/worker.js');
|
|
154
|
+
const onError = on.mock.calls.find(([event]) => event === 'error')?.[1];
|
|
155
|
+
const onExit = on.mock.calls.find(([event]) => event === 'exit')?.[1];
|
|
156
|
+
onError?.(new Error('boom'));
|
|
157
|
+
(0, vitest_1.expect)(consoleError).toHaveBeenCalledWith('⛔ Child process 321 error :', vitest_1.expect.any(Error));
|
|
158
|
+
onExit?.(1);
|
|
159
|
+
await vitest_1.vi.runOnlyPendingTimersAsync();
|
|
160
|
+
(0, vitest_1.expect)(child_process_1.fork).toHaveBeenCalledTimes(2);
|
|
161
|
+
for (let attempt = 2; attempt <= 6; attempt++) {
|
|
162
|
+
const currentChild = vitest_1.vi.mocked(child_process_1.fork).mock.results[attempt - 2]?.value || child;
|
|
163
|
+
const exitHandler = currentChild.on.mock.calls.find(([event]) => event === 'exit')?.[1];
|
|
164
|
+
exitHandler?.(1);
|
|
165
|
+
await vitest_1.vi.runOnlyPendingTimersAsync();
|
|
166
|
+
}
|
|
167
|
+
(0, vitest_1.expect)(consoleLog).toHaveBeenCalledWith('🔄 Restarting worker process... Attempt 1 of 5');
|
|
168
|
+
(0, vitest_1.expect)(consoleError).toHaveBeenCalledWith('⛔ Max restart attempts reached. Not restarting worker process 321. Container restart required!');
|
|
169
|
+
});
|
|
170
|
+
});
|
|
@@ -33,8 +33,8 @@ class AmqpQueue {
|
|
|
33
33
|
*/
|
|
34
34
|
setSocketOptions(socketOptions) {
|
|
35
35
|
this.socketOptions = {
|
|
36
|
-
...(socketOptions || {}),
|
|
37
36
|
maxStoredMessagesOnError: 500,
|
|
37
|
+
...(socketOptions || {}),
|
|
38
38
|
};
|
|
39
39
|
return this;
|
|
40
40
|
}
|
|
@@ -76,7 +76,7 @@ class AmqpQueue {
|
|
|
76
76
|
}
|
|
77
77
|
this.logger.info(`Retrying connection in... ${this.socketOptions.retry.intervalMs || 0}ms`);
|
|
78
78
|
await (0, timeout_1.sleep)(this.socketOptions.retry.intervalMs);
|
|
79
|
-
return await this.connect(vHost, retryCount
|
|
79
|
+
return await this.connect(vHost, retryCount + 1);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
/**
|
|
@@ -202,7 +202,7 @@ class AmqpQueue {
|
|
|
202
202
|
error: err,
|
|
203
203
|
});
|
|
204
204
|
if (buildedConfigs.storeMessageOnError === false ||
|
|
205
|
-
(this.socketOptions?.maxStoredMessagesOnError || 0)
|
|
205
|
+
(this.socketOptions?.maxStoredMessagesOnError || 0) <=
|
|
206
206
|
this.messagesInMemory.length) {
|
|
207
207
|
return;
|
|
208
208
|
}
|
|
@@ -280,7 +280,7 @@ class AmqpQueue {
|
|
|
280
280
|
TTLms: sevenDaysInMs,
|
|
281
281
|
};
|
|
282
282
|
}
|
|
283
|
-
return await this.createConsumers(queueName,
|
|
283
|
+
return await this.createConsumers(queueName, buildedConfigs);
|
|
284
284
|
}
|
|
285
285
|
/**
|
|
286
286
|
* Retorna uma instância singleton conectada ao vHost informado.
|