@ecdt/server-common 1.7.0 → 2.0.0

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.
@@ -1,310 +0,0 @@
1
- const { test, describe, beforeEach, afterEach } = require('node:test');
2
- const assert = require('node:assert/strict');
3
-
4
- const {
5
- publicarEvento,
6
- publicarEventoDaRequisicao,
7
- } = require('../src/services/motorEventosService.js');
8
-
9
- const URL = 'http://coletor.interno/eventos';
10
-
11
- const esperarMicrotasks = () => new Promise((resolve) => setImmediate(resolve));
12
-
13
- describe('publicarEvento', () => {
14
- let fetchOriginal;
15
- let warnOriginal;
16
- let urlOriginal;
17
- let chamadas;
18
- let falhas;
19
- let avisos;
20
-
21
- const aoFalhar = (mensagem) => falhas.push(mensagem);
22
-
23
- beforeEach(() => {
24
- fetchOriginal = global.fetch;
25
- warnOriginal = console.warn;
26
- urlOriginal = process.env.MOTOR_EVENTOS_URL;
27
- chamadas = [];
28
- falhas = [];
29
- avisos = [];
30
- console.warn = (mensagem) => avisos.push(mensagem);
31
- global.fetch = (url, opcoes) => {
32
- chamadas.push({ url, opcoes });
33
- return Promise.resolve({ ok: true, status: 201 });
34
- };
35
- });
36
-
37
- afterEach(() => {
38
- global.fetch = fetchOriginal;
39
- console.warn = warnOriginal;
40
- if (urlOriginal === undefined) {
41
- delete process.env.MOTOR_EVENTOS_URL;
42
- } else {
43
- process.env.MOTOR_EVENTOS_URL = urlOriginal;
44
- }
45
- });
46
-
47
- test('envia POST na url configurada com o token de quem chamou', async () => {
48
- publicarEvento({
49
- tipo: 'meu_evento',
50
- autorizacao: 'Bearer jwt',
51
- payload: { campo: 'valor' },
52
- url: URL,
53
- aoFalhar,
54
- });
55
-
56
- await esperarMicrotasks();
57
-
58
- assert.equal(chamadas.length, 1);
59
- assert.equal(chamadas[0].url, URL);
60
- assert.equal(chamadas[0].opcoes.method, 'POST');
61
- assert.equal(chamadas[0].opcoes.headers.Authorization, 'Bearer jwt');
62
-
63
- const corpo = JSON.parse(chamadas[0].opcoes.body);
64
- assert.equal(corpo.tipo, 'meu_evento');
65
- assert.deepEqual(corpo.payload, { campo: 'valor' });
66
- assert.ok(!Number.isNaN(Date.parse(corpo.dt_evento)));
67
- assert.deepEqual(falhas, []);
68
- assert.deepEqual(avisos, []);
69
- });
70
-
71
- test('nao acrescenta caminho nenhum a url configurada', async () => {
72
- publicarEvento({ tipo: 'meu_evento', autorizacao: 'Bearer jwt', url: 'http://coletor.interno/v2/x', aoFalhar });
73
- await esperarMicrotasks();
74
-
75
- assert.equal(chamadas[0].url, 'http://coletor.interno/v2/x');
76
- });
77
-
78
- test('cai na MOTOR_EVENTOS_URL quando a url nao e passada', async () => {
79
- process.env.MOTOR_EVENTOS_URL = URL;
80
-
81
- publicarEvento({ tipo: 'meu_evento', autorizacao: 'Bearer jwt', aoFalhar });
82
- await esperarMicrotasks();
83
-
84
- assert.equal(chamadas[0].url, URL);
85
- });
86
-
87
- test('avisa e nao publica quando a url esta ausente', async () => {
88
- delete process.env.MOTOR_EVENTOS_URL;
89
-
90
- publicarEvento({ tipo: 'meu_evento', autorizacao: 'Bearer jwt', aoFalhar });
91
- await esperarMicrotasks();
92
-
93
- assert.equal(chamadas.length, 0);
94
- assert.equal(avisos.length, 1);
95
- assert.match(avisos[0], /url do coletor ausente/);
96
- });
97
-
98
- test('avisa quando a url nao e string ou e so espaco', async () => {
99
- publicarEvento({ tipo: 'meu_evento', autorizacao: 'Bearer jwt', url: 123, aoFalhar });
100
- publicarEvento({ tipo: 'meu_evento', autorizacao: 'Bearer jwt', url: ' ', aoFalhar });
101
- await esperarMicrotasks();
102
-
103
- assert.equal(chamadas.length, 0);
104
- assert.equal(avisos.length, 2);
105
- });
106
-
107
- test('nao publica sem tipo, nem sem identidade nenhuma', async () => {
108
- publicarEvento({ autorizacao: 'Bearer jwt', url: URL, aoFalhar });
109
- publicarEvento({ tipo: 'meu_evento', url: URL, aoFalhar });
110
- publicarEvento({ tipo: 'meu_evento', url: URL, idVisitante: ' ', aoFalhar });
111
- await esperarMicrotasks();
112
-
113
- assert.equal(chamadas.length, 0);
114
- assert.deepEqual(falhas, []);
115
- assert.deepEqual(avisos, []);
116
- });
117
-
118
- test('publica so com idVisitante, sem header de autorizacao', async () => {
119
- publicarEvento({ tipo: 'meu_evento', idVisitante: 'visitante-1', url: URL, aoFalhar });
120
- await esperarMicrotasks();
121
-
122
- assert.equal(chamadas.length, 1);
123
- assert.equal(chamadas[0].opcoes.headers.Authorization, undefined);
124
- assert.equal(JSON.parse(chamadas[0].opcoes.body).id_visitante, 'visitante-1');
125
- });
126
-
127
- test('manda os dois quando tem token e visitante', async () => {
128
- publicarEvento({
129
- tipo: 'meu_evento',
130
- autorizacao: 'Bearer jwt',
131
- idVisitante: 'visitante-1',
132
- url: URL,
133
- aoFalhar,
134
- });
135
- await esperarMicrotasks();
136
-
137
- assert.equal(chamadas[0].opcoes.headers.Authorization, 'Bearer jwt');
138
- assert.equal(JSON.parse(chamadas[0].opcoes.body).id_visitante, 'visitante-1');
139
- });
140
-
141
- test('omite id_visitante do corpo quando nao ha visitante', async () => {
142
- publicarEvento({ tipo: 'meu_evento', autorizacao: 'Bearer jwt', url: URL, aoFalhar });
143
- await esperarMicrotasks();
144
-
145
- assert.ok(!('id_visitante' in JSON.parse(chamadas[0].opcoes.body)));
146
- });
147
-
148
- test('nao quebra quando chamado sem argumento nenhum', () => {
149
- delete process.env.MOTOR_EVENTOS_URL;
150
-
151
- assert.doesNotThrow(() => publicarEvento());
152
- assert.equal(chamadas.length, 0);
153
- });
154
-
155
- test('nao propaga rejeicao do fetch e reporta a falha', async () => {
156
- global.fetch = () => Promise.reject(new Error('connect ECONNREFUSED'));
157
-
158
- assert.doesNotThrow(() =>
159
- publicarEvento({ tipo: 'meu_evento', autorizacao: 'Bearer jwt', url: URL, aoFalhar })
160
- );
161
-
162
- await esperarMicrotasks();
163
-
164
- assert.equal(falhas.length, 1);
165
- assert.match(falhas[0], /meu_evento/);
166
- });
167
-
168
- test('reporta resposta de erro sem lancar', async () => {
169
- global.fetch = () => Promise.resolve({ ok: false, status: 400 });
170
-
171
- publicarEvento({ tipo: 'meu_evento', autorizacao: 'Bearer jwt', url: URL, aoFalhar });
172
- await esperarMicrotasks();
173
-
174
- assert.equal(falhas.length, 1);
175
- assert.match(falhas[0], /400/);
176
- });
177
-
178
- test('nao propaga erro sincrono do fetch', () => {
179
- global.fetch = () => {
180
- throw new TypeError('opcoes invalidas');
181
- };
182
-
183
- assert.doesNotThrow(() =>
184
- publicarEvento({ tipo: 'meu_evento', autorizacao: 'Bearer jwt', url: URL, aoFalhar })
185
- );
186
- assert.equal(falhas.length, 1);
187
- });
188
-
189
- test('nao devolve promise, para ninguem conseguir esperar por ela', () => {
190
- const retorno = publicarEvento({
191
- tipo: 'meu_evento',
192
- autorizacao: 'Bearer jwt',
193
- url: URL,
194
- aoFalhar,
195
- });
196
-
197
- assert.equal(retorno, undefined);
198
- });
199
- });
200
-
201
- describe('publicarEventoDaRequisicao', () => {
202
- let fetchOriginal;
203
- let warnOriginal;
204
- let errorOriginal;
205
- let urlOriginal;
206
- let cookieOriginal;
207
- let chamadas;
208
-
209
- beforeEach(() => {
210
- fetchOriginal = global.fetch;
211
- warnOriginal = console.warn;
212
- errorOriginal = console.error;
213
- urlOriginal = process.env.MOTOR_EVENTOS_URL;
214
- cookieOriginal = process.env.MOTOR_EVENTOS_COOKIE_VISITANTE;
215
- chamadas = [];
216
- console.warn = () => {};
217
- console.error = () => {};
218
- process.env.MOTOR_EVENTOS_URL = URL;
219
- global.fetch = (url, opcoes) => {
220
- chamadas.push({ url, opcoes });
221
- return Promise.resolve({ ok: true, status: 201 });
222
- };
223
- });
224
-
225
- afterEach(() => {
226
- global.fetch = fetchOriginal;
227
- console.warn = warnOriginal;
228
- console.error = errorOriginal;
229
- for (const [chave, valor] of [
230
- ['MOTOR_EVENTOS_URL', urlOriginal],
231
- ['MOTOR_EVENTOS_COOKIE_VISITANTE', cookieOriginal],
232
- ]) {
233
- if (valor === undefined) delete process.env[chave];
234
- else process.env[chave] = valor;
235
- }
236
- });
237
-
238
- const corpoEnviado = () => JSON.parse(chamadas[0].opcoes.body);
239
-
240
- test('tira o token do header da requisicao', async () => {
241
- publicarEventoDaRequisicao(
242
- { headers: { authorization: 'Bearer jwt' }, body: {} },
243
- { tipo: 'meu_evento', payload: { campo: 'valor' } }
244
- );
245
- await esperarMicrotasks();
246
-
247
- assert.equal(chamadas[0].opcoes.headers.Authorization, 'Bearer jwt');
248
- assert.deepEqual(corpoEnviado().payload, { campo: 'valor' });
249
- });
250
-
251
- test('tira o visitante do cookie quando nao ha token', async () => {
252
- publicarEventoDaRequisicao(
253
- { headers: { cookie: 'trk=%7B%22id%22%3A%22visitante-1%22%7D' }, body: {} },
254
- { tipo: 'meu_evento', cookieVisitante: 'trk' }
255
- );
256
- await esperarMicrotasks();
257
-
258
- assert.equal(corpoEnviado().id_visitante, 'visitante-1');
259
- assert.equal(chamadas[0].opcoes.headers.Authorization, undefined);
260
- });
261
-
262
- test('o corpo tem precedencia sobre o cookie', async () => {
263
- publicarEventoDaRequisicao(
264
- {
265
- headers: { cookie: 'trk=%7B%22id%22%3A%22do-cookie%22%7D' },
266
- body: { id_visitante: 'do-corpo' },
267
- },
268
- { tipo: 'meu_evento', cookieVisitante: 'trk' }
269
- );
270
- await esperarMicrotasks();
271
-
272
- assert.equal(corpoEnviado().id_visitante, 'do-corpo');
273
- });
274
-
275
- test('cai na MOTOR_EVENTOS_COOKIE_VISITANTE quando o nome nao e passado', async () => {
276
- process.env.MOTOR_EVENTOS_COOKIE_VISITANTE = 'trk';
277
-
278
- publicarEventoDaRequisicao(
279
- { headers: { cookie: 'trk=visitante-2' }, body: {} },
280
- { tipo: 'meu_evento' }
281
- );
282
- await esperarMicrotasks();
283
-
284
- assert.equal(corpoEnviado().id_visitante, 'visitante-2');
285
- });
286
-
287
- test('nao publica quando a requisicao nao traz identidade nenhuma', async () => {
288
- delete process.env.MOTOR_EVENTOS_COOKIE_VISITANTE;
289
-
290
- publicarEventoDaRequisicao({ headers: {}, body: {} }, { tipo: 'meu_evento' });
291
- await esperarMicrotasks();
292
-
293
- assert.equal(chamadas.length, 0);
294
- });
295
-
296
- test('nao quebra com requisicao sem headers, sem corpo, ou sem argumento nenhum', () => {
297
- assert.doesNotThrow(() => publicarEventoDaRequisicao({}, { tipo: 'meu_evento' }));
298
- assert.doesNotThrow(() => publicarEventoDaRequisicao());
299
- });
300
-
301
- test('repassa as demais opcoes para o publicarEvento', async () => {
302
- publicarEventoDaRequisicao(
303
- { headers: { authorization: 'Bearer jwt' }, body: {} },
304
- { tipo: 'meu_evento', url: 'http://outro.interno/eventos' }
305
- );
306
- await esperarMicrotasks();
307
-
308
- assert.equal(chamadas[0].url, 'http://outro.interno/eventos');
309
- });
310
- });