@zdavison/matador 4.0.3 → 4.2.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.
Files changed (71) hide show
  1. package/dist/core/matador.d.ts.map +1 -1
  2. package/dist/core/matador.js +4 -1
  3. package/dist/index.cjs +156 -16
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/pipeline/pipeline.d.ts +30 -2
  7. package/dist/pipeline/pipeline.d.ts.map +1 -1
  8. package/dist/pipeline/pipeline.js +65 -9
  9. package/dist/retry/index.d.ts +1 -1
  10. package/dist/retry/index.d.ts.map +1 -1
  11. package/dist/retry/policy.d.ts +27 -0
  12. package/dist/retry/policy.d.ts.map +1 -1
  13. package/dist/retry/standard-policy.d.ts +33 -2
  14. package/dist/retry/standard-policy.d.ts.map +1 -1
  15. package/dist/retry/standard-policy.js +73 -9
  16. package/dist/topology/types.d.ts +14 -0
  17. package/dist/topology/types.d.ts.map +1 -1
  18. package/dist/transport/rabbitmq/rabbitmq-transport.d.ts.map +1 -1
  19. package/dist/transport/rabbitmq/rabbitmq-transport.js +3 -0
  20. package/package.json +1 -1
  21. package/dist/checkpoint/context.test.d.ts +0 -2
  22. package/dist/checkpoint/context.test.d.ts.map +0 -1
  23. package/dist/checkpoint/context.test.js +0 -428
  24. package/dist/checkpoint/stores/stores.test.d.ts +0 -2
  25. package/dist/checkpoint/stores/stores.test.d.ts.map +0 -1
  26. package/dist/checkpoint/stores/stores.test.js +0 -146
  27. package/dist/codec/rabbitmq-codec.test.d.ts +0 -2
  28. package/dist/codec/rabbitmq-codec.test.d.ts.map +0 -1
  29. package/dist/codec/rabbitmq-codec.test.js +0 -428
  30. package/dist/core/fanout.test.d.ts +0 -2
  31. package/dist/core/fanout.test.d.ts.map +0 -1
  32. package/dist/core/fanout.test.js +0 -1970
  33. package/dist/core/matador.test.d.ts +0 -2
  34. package/dist/core/matador.test.d.ts.map +0 -1
  35. package/dist/core/matador.test.js +0 -813
  36. package/dist/core/shutdown.test.d.ts +0 -2
  37. package/dist/core/shutdown.test.d.ts.map +0 -1
  38. package/dist/core/shutdown.test.js +0 -599
  39. package/dist/errors/retry-errors.test.d.ts +0 -2
  40. package/dist/errors/retry-errors.test.d.ts.map +0 -1
  41. package/dist/errors/retry-errors.test.js +0 -136
  42. package/dist/pipeline/pipeline.test.d.ts +0 -2
  43. package/dist/pipeline/pipeline.test.d.ts.map +0 -1
  44. package/dist/pipeline/pipeline.test.js +0 -1124
  45. package/dist/retry/standard-policy.test.d.ts +0 -2
  46. package/dist/retry/standard-policy.test.d.ts.map +0 -1
  47. package/dist/retry/standard-policy.test.js +0 -196
  48. package/dist/schema/registry.test.d.ts +0 -2
  49. package/dist/schema/registry.test.d.ts.map +0 -1
  50. package/dist/schema/registry.test.js +0 -278
  51. package/dist/schema/types.test.d.ts +0 -2
  52. package/dist/schema/types.test.d.ts.map +0 -1
  53. package/dist/schema/types.test.js +0 -246
  54. package/dist/topology/builder.test.d.ts +0 -2
  55. package/dist/topology/builder.test.d.ts.map +0 -1
  56. package/dist/topology/builder.test.js +0 -547
  57. package/dist/transport/local/local-transport.test.d.ts +0 -2
  58. package/dist/transport/local/local-transport.test.d.ts.map +0 -1
  59. package/dist/transport/local/local-transport.test.js +0 -232
  60. package/dist/transport/multi/multi-transport.test.d.ts +0 -2
  61. package/dist/transport/multi/multi-transport.test.d.ts.map +0 -1
  62. package/dist/transport/multi/multi-transport.test.js +0 -322
  63. package/dist/transport/rabbitmq/rabbitmq-transport-reconnection.test.d.ts +0 -2
  64. package/dist/transport/rabbitmq/rabbitmq-transport-reconnection.test.d.ts.map +0 -1
  65. package/dist/transport/rabbitmq/rabbitmq-transport-reconnection.test.js +0 -149
  66. package/dist/transport/rabbitmq/rabbitmq-transport.test.d.ts +0 -2
  67. package/dist/transport/rabbitmq/rabbitmq-transport.test.d.ts.map +0 -1
  68. package/dist/transport/rabbitmq/rabbitmq-transport.test.js +0 -230
  69. package/dist/types/event.test.d.ts +0 -2
  70. package/dist/types/event.test.d.ts.map +0 -1
  71. package/dist/types/event.test.js +0 -130
@@ -1,232 +0,0 @@
1
- import { beforeEach, describe, expect, it } from 'bun:test';
2
- import { LocalTransportNoActiveSubscriberError } from '../../errors/index.js';
3
- import { createEnvelope } from '../../types/index.js';
4
- import { LocalTransport } from './local-transport.js';
5
- describe('LocalTransport', () => {
6
- let transport;
7
- beforeEach(() => {
8
- transport = new LocalTransport();
9
- });
10
- describe('connection', () => {
11
- it('should start disconnected', () => {
12
- expect(transport.isConnected()).toBe(false);
13
- });
14
- it('should connect successfully', async () => {
15
- await transport.connect();
16
- expect(transport.isConnected()).toBe(true);
17
- });
18
- it('should disconnect successfully', async () => {
19
- await transport.connect();
20
- await transport.disconnect();
21
- expect(transport.isConnected()).toBe(false);
22
- });
23
- });
24
- describe('capabilities', () => {
25
- it('should report correct capabilities', () => {
26
- expect(transport.name).toBe('local');
27
- expect(transport.capabilities.deliveryModes).toContain('at-least-once');
28
- expect(transport.capabilities.delayedMessages).toBe(true);
29
- expect(transport.capabilities.deadLetterRouting).toBe('manual');
30
- });
31
- });
32
- describe('send and receive', () => {
33
- beforeEach(async () => {
34
- await transport.connect();
35
- // A no-op subscriber makes 'test-queue' deliverable; LocalTransport now
36
- // rejects sends to queues with no active subscriber in this process.
37
- await transport.subscribe('test-queue', async () => { });
38
- });
39
- it('should throw when sending while disconnected', async () => {
40
- await transport.disconnect();
41
- const envelope = createTestEnvelope();
42
- await expect(transport.send('test-queue', envelope)).rejects.toThrow('is not connected');
43
- });
44
- it('should throw when sending to a queue with no active subscriber', async () => {
45
- const envelope = createTestEnvelope();
46
- await expect(transport.send('unsubscribed-queue', envelope)).rejects.toThrow(LocalTransportNoActiveSubscriberError);
47
- });
48
- it('should send and receive a message', async () => {
49
- const envelope = createTestEnvelope();
50
- await transport.send('test-queue', envelope);
51
- const received = await transport.receiveOne('test-queue');
52
- expect(received).not.toBeNull();
53
- expect(received?.envelope.id).toBe(envelope.id);
54
- expect(received?.envelope.data).toEqual({ test: 'data' });
55
- });
56
- it('should track queue size correctly', async () => {
57
- expect(transport.getQueueSize('test-queue')).toBe(0);
58
- await transport.send('test-queue', createTestEnvelope());
59
- expect(transport.getQueueSize('test-queue')).toBe(1);
60
- await transport.send('test-queue', createTestEnvelope());
61
- expect(transport.getQueueSize('test-queue')).toBe(2);
62
- });
63
- it('should complete messages and remove from queue', async () => {
64
- const envelope = createTestEnvelope();
65
- await transport.send('test-queue', envelope);
66
- const received = await transport.receiveOne('test-queue');
67
- if (!received)
68
- throw new Error('expected received message');
69
- await transport.complete(received.receipt);
70
- expect(transport.getQueueSize('test-queue')).toBe(0);
71
- expect(transport.getCompleted()).toHaveLength(1);
72
- });
73
- it('should return null when queue is empty', async () => {
74
- const received = await transport.receiveOne('empty-queue');
75
- expect(received).toBeNull();
76
- });
77
- it('should preserve FIFO order of pending messages', async () => {
78
- const envelopes = [0, 1, 2].map((seq) => createEnvelope({
79
- eventKey: 'test.event',
80
- targetSubscriber: 'test-subscriber',
81
- data: { seq },
82
- importance: 'should-investigate',
83
- }));
84
- for (const envelope of envelopes) {
85
- await transport.send('test-queue', envelope);
86
- }
87
- expect(transport.getPendingMessages('test-queue').map((e) => e.data)).toEqual([{ seq: 0 }, { seq: 1 }, { seq: 2 }]);
88
- for (const envelope of envelopes) {
89
- const received = await transport.receiveOne('test-queue');
90
- expect(received?.envelope.id).toBe(envelope.id);
91
- if (received)
92
- await transport.complete(received.receipt);
93
- }
94
- });
95
- });
96
- describe('subscriptions', () => {
97
- beforeEach(async () => {
98
- await transport.connect();
99
- });
100
- it('should throw when subscribing while disconnected', async () => {
101
- await transport.disconnect();
102
- await expect(transport.subscribe('test-queue', async () => { })).rejects.toThrow('is not connected');
103
- });
104
- it('should deliver messages to subscribers', async () => {
105
- const receivedMessages = [];
106
- await transport.subscribe('test-queue', async (envelope) => {
107
- receivedMessages.push(envelope);
108
- });
109
- const envelope = createTestEnvelope();
110
- await transport.send('test-queue', envelope);
111
- expect(receivedMessages).toHaveLength(1);
112
- expect(receivedMessages[0].id).toBe(envelope.id);
113
- });
114
- it('should redeliver pending (uncompleted) messages to a newly attached subscriber', async () => {
115
- const firstSubscriberMessages = [];
116
- const firstSubscription = await transport.subscribe('test-queue', async (envelope) => {
117
- firstSubscriberMessages.push(envelope);
118
- });
119
- const envelope = createTestEnvelope();
120
- await transport.send('test-queue', envelope);
121
- expect(firstSubscriberMessages).toHaveLength(1);
122
- // First subscriber never completed the message before going away.
123
- await firstSubscription.unsubscribe();
124
- const secondSubscriberMessages = [];
125
- await transport.subscribe('test-queue', async (env) => {
126
- secondSubscriberMessages.push(env);
127
- });
128
- expect(secondSubscriberMessages).toHaveLength(1);
129
- });
130
- it('should stop delivering after unsubscribe', async () => {
131
- const receivedMessages = [];
132
- const subscription = await transport.subscribe('test-queue', async (envelope) => {
133
- receivedMessages.push(envelope);
134
- });
135
- await transport.send('test-queue', createTestEnvelope());
136
- expect(receivedMessages).toHaveLength(1);
137
- await subscription.unsubscribe();
138
- expect(subscription.isActive).toBe(false);
139
- });
140
- });
141
- describe('dead letter queue', () => {
142
- beforeEach(async () => {
143
- await transport.connect();
144
- await transport.subscribe('test-queue', async () => { });
145
- });
146
- it('should send messages to dead letter queue', async () => {
147
- const envelope = createTestEnvelope();
148
- await transport.send('test-queue', envelope);
149
- const received = await transport.receiveOne('test-queue');
150
- if (!received)
151
- throw new Error('expected received message');
152
- await transport.sendToDeadLetter(received.receipt, 'dlq', envelope, 'test error');
153
- expect(transport.getQueueSize('test-queue')).toBe(0);
154
- expect(transport.getQueueSize('test-queue.dlq')).toBe(1);
155
- });
156
- });
157
- describe('topology', () => {
158
- it('should apply topology and create queues', async () => {
159
- const topology = {
160
- namespace: 'test',
161
- queues: [{ name: 'events' }, { name: 'notifications' }],
162
- deadLetter: {
163
- unhandled: { enabled: true },
164
- undeliverable: { enabled: true },
165
- },
166
- retry: {
167
- enabled: true,
168
- defaultDelayMs: 1000,
169
- maxDelayMs: 30000,
170
- },
171
- };
172
- await transport.connect();
173
- await transport.applyTopology(topology);
174
- // Queues should be created
175
- expect(transport.getQueueSize('test.events')).toBe(0);
176
- expect(transport.getQueueSize('test.notifications')).toBe(0);
177
- });
178
- });
179
- describe('clear', () => {
180
- it('should reset all state', async () => {
181
- await transport.connect();
182
- await transport.subscribe('test-queue', async () => { });
183
- await transport.send('test-queue', createTestEnvelope());
184
- const received = await transport.receiveOne('test-queue');
185
- if (!received)
186
- throw new Error('expected received message');
187
- await transport.complete(received.receipt);
188
- transport.clear();
189
- expect(transport.getQueueSize('test-queue')).toBe(0);
190
- expect(transport.getCompleted()).toHaveLength(0);
191
- });
192
- });
193
- describe('delayed messages', () => {
194
- beforeEach(async () => {
195
- await transport.connect();
196
- await transport.subscribe('test-queue', async () => { });
197
- });
198
- it('should return immediately and delay message delivery', async () => {
199
- const envelope = createTestEnvelope();
200
- // Send returns immediately (non-blocking)
201
- await transport.send('test-queue', envelope, {
202
- delay: 100,
203
- });
204
- // Message should not be in queue immediately
205
- expect(transport.getQueueSize('test-queue')).toBe(0);
206
- // Wait for the delay to pass
207
- await new Promise((resolve) => setTimeout(resolve, 150));
208
- // Message should now be in queue
209
- expect(transport.getQueueSize('test-queue')).toBe(1);
210
- });
211
- it('should cancel delayed messages on disconnect', async () => {
212
- const envelope = createTestEnvelope();
213
- await transport.send('test-queue', envelope, {
214
- delay: 100,
215
- });
216
- // Disconnect before delay expires
217
- await transport.disconnect();
218
- // Wait past the original delay
219
- await new Promise((resolve) => setTimeout(resolve, 150));
220
- // Message should never have been delivered
221
- expect(transport.getQueueSize('test-queue')).toBe(0);
222
- });
223
- });
224
- });
225
- function createTestEnvelope() {
226
- return createEnvelope({
227
- eventKey: 'test.event',
228
- targetSubscriber: 'test-subscriber',
229
- data: { test: 'data' },
230
- importance: 'should-investigate',
231
- });
232
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=multi-transport.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"multi-transport.test.d.ts","sourceRoot":"","sources":["../../../src/transport/multi/multi-transport.test.ts"],"names":[],"mappings":""}
@@ -1,322 +0,0 @@
1
- import { beforeEach, describe, expect, it, mock } from 'bun:test';
2
- import { createEnvelope } from '../../types/index.js';
3
- import { LocalTransport } from '../local/local-transport.js';
4
- import { MultiTransport } from './multi-transport.js';
5
- describe('MultiTransport', () => {
6
- let primary;
7
- let secondary;
8
- let transport;
9
- beforeEach(() => {
10
- primary = new LocalTransport();
11
- secondary = new LocalTransport();
12
- transport = new MultiTransport({
13
- transports: [primary, secondary],
14
- });
15
- });
16
- describe('constructor', () => {
17
- it('should throw if no transports provided', () => {
18
- expect(() => new MultiTransport({ transports: [] })).toThrow('At least one transport is required');
19
- });
20
- it('should set name based on transport names', () => {
21
- expect(transport.name).toBe('multi(local,local)');
22
- });
23
- it('should use primary transport capabilities', () => {
24
- expect(transport.capabilities).toBe(primary.capabilities);
25
- });
26
- it('should expose primary transport', () => {
27
- expect(transport.primary).toBe(primary);
28
- });
29
- it('should expose all transports', () => {
30
- expect(transport.transports).toEqual([primary, secondary]);
31
- });
32
- it('should default fallbackEnabled to true', () => {
33
- expect(transport.fallbackEnabled).toBe(true);
34
- });
35
- it('should allow disabling fallback', () => {
36
- const noFallback = new MultiTransport({
37
- transports: [primary, secondary],
38
- fallbackEnabled: false,
39
- });
40
- expect(noFallback.fallbackEnabled).toBe(false);
41
- });
42
- });
43
- describe('connection', () => {
44
- it('should start disconnected', () => {
45
- expect(transport.isConnected()).toBe(false);
46
- });
47
- it('should connect all transports', async () => {
48
- await transport.connect();
49
- expect(transport.isConnected()).toBe(true);
50
- expect(primary.isConnected()).toBe(true);
51
- expect(secondary.isConnected()).toBe(true);
52
- });
53
- it('should disconnect all transports', async () => {
54
- await transport.connect();
55
- await transport.disconnect();
56
- expect(transport.isConnected()).toBe(false);
57
- expect(primary.isConnected()).toBe(false);
58
- expect(secondary.isConnected()).toBe(false);
59
- });
60
- });
61
- describe('topology', () => {
62
- it('should apply topology to all transports', async () => {
63
- const topology = {
64
- namespace: 'test',
65
- queues: [{ name: 'events' }],
66
- deadLetter: {
67
- unhandled: { enabled: true },
68
- undeliverable: { enabled: true },
69
- },
70
- retry: {
71
- enabled: true,
72
- defaultDelayMs: 1000,
73
- maxDelayMs: 30000,
74
- },
75
- };
76
- await transport.connect();
77
- await transport.applyTopology(topology);
78
- // Both transports should have the queue
79
- expect(primary.getQueueSize('test.events')).toBe(0);
80
- expect(secondary.getQueueSize('test.events')).toBe(0);
81
- });
82
- });
83
- describe('send - primary success', () => {
84
- beforeEach(async () => {
85
- await transport.connect();
86
- await transport.subscribe('test-queue', async () => { });
87
- });
88
- it('should send to primary transport when it succeeds', async () => {
89
- const envelope = createTestEnvelope();
90
- await transport.send('test-queue', envelope);
91
- expect(primary.getQueueSize('test-queue')).toBe(1);
92
- expect(secondary.getQueueSize('test-queue')).toBe(0);
93
- });
94
- it('should not call onEnqueueFallback when primary succeeds', async () => {
95
- const onEnqueueFallback = mock(() => { });
96
- const transportWithCallback = new MultiTransport({ transports: [primary, secondary] }, { onEnqueueFallback });
97
- await transportWithCallback.connect();
98
- const envelope = createTestEnvelope();
99
- await transportWithCallback.send('test-queue', envelope);
100
- expect(onEnqueueFallback).not.toHaveBeenCalled();
101
- });
102
- });
103
- describe('send - fallback', () => {
104
- beforeEach(async () => {
105
- await transport.connect();
106
- await transport.subscribe('test-queue', async () => { });
107
- });
108
- it('should fallback when primary fails', async () => {
109
- // Make primary fail
110
- await primary.disconnect();
111
- const envelope = createTestEnvelope();
112
- await transport.send('test-queue', envelope);
113
- expect(secondary.getQueueSize('test-queue')).toBe(1);
114
- });
115
- it('should call onEnqueueFallback when fallback is used', async () => {
116
- const fallbackContexts = [];
117
- const transportWithCallback = new MultiTransport({ transports: [primary, secondary] }, { onEnqueueFallback: (ctx) => fallbackContexts.push(ctx) });
118
- await transportWithCallback.connect();
119
- // Make primary fail
120
- await primary.disconnect();
121
- const envelope = createTestEnvelope();
122
- await transportWithCallback.send('test-queue', envelope);
123
- expect(fallbackContexts).toHaveLength(1);
124
- const ctx = fallbackContexts[0];
125
- if (!ctx)
126
- throw new Error('expected fallback context');
127
- expect(ctx.failedTransport).toBe('local');
128
- expect(ctx.nextTransport).toBe('local');
129
- expect(ctx.queue).toBe('test-queue');
130
- expect(ctx.envelope).toBe(envelope);
131
- expect(ctx.error.message).toContain('is not connected');
132
- });
133
- it('should throw when all transports fail', async () => {
134
- await primary.disconnect();
135
- await secondary.disconnect();
136
- const envelope = createTestEnvelope();
137
- await expect(transport.send('test-queue', envelope)).rejects.toThrow('All transports failed');
138
- });
139
- it('should try transports in order', async () => {
140
- const third = new LocalTransport();
141
- const multiTransport = new MultiTransport({
142
- transports: [primary, secondary, third],
143
- });
144
- await multiTransport.connect();
145
- await third.subscribe('test-queue', async () => { });
146
- // Make primary and secondary fail
147
- await primary.disconnect();
148
- await secondary.disconnect();
149
- const envelope = createTestEnvelope();
150
- await multiTransport.send('test-queue', envelope);
151
- expect(third.getQueueSize('test-queue')).toBe(1);
152
- });
153
- it('should not fallback when fallbackEnabled is false', async () => {
154
- const noFallback = new MultiTransport({
155
- transports: [primary, secondary],
156
- fallbackEnabled: false,
157
- });
158
- await noFallback.connect();
159
- // Make primary fail
160
- await primary.disconnect();
161
- const envelope = createTestEnvelope();
162
- await expect(noFallback.send('test-queue', envelope)).rejects.toThrow('is not connected');
163
- // Secondary should not have received the message
164
- expect(secondary.getQueueSize('test-queue')).toBe(0);
165
- });
166
- it('should send to primary when fallbackEnabled is false and primary succeeds', async () => {
167
- const noFallback = new MultiTransport({
168
- transports: [primary, secondary],
169
- fallbackEnabled: false,
170
- });
171
- await noFallback.connect();
172
- const envelope = createTestEnvelope();
173
- await noFallback.send('test-queue', envelope);
174
- expect(primary.getQueueSize('test-queue')).toBe(1);
175
- expect(secondary.getQueueSize('test-queue')).toBe(0);
176
- });
177
- });
178
- describe('subscribe', () => {
179
- beforeEach(async () => {
180
- await transport.connect();
181
- });
182
- it('should receive messages from primary transport', async () => {
183
- const receivedMessages = [];
184
- await transport.subscribe('test-queue', async (envelope) => {
185
- receivedMessages.push(envelope);
186
- });
187
- // Send directly to primary (simulating normal operation)
188
- await primary.send('test-queue', createTestEnvelope());
189
- expect(receivedMessages).toHaveLength(1);
190
- });
191
- it('should receive messages that fell back to secondary transport', async () => {
192
- const receivedMessages = [];
193
- // Subscribe through MultiTransport
194
- await transport.subscribe('test-queue', async (envelope) => {
195
- receivedMessages.push(envelope);
196
- });
197
- // Make primary fail for sends
198
- await primary.disconnect();
199
- // Send through MultiTransport - should fall back to secondary
200
- const envelope = createTestEnvelope();
201
- await transport.send('test-queue', envelope);
202
- // Message went to secondary transport, subscriber should still receive it
203
- expect(receivedMessages).toHaveLength(1);
204
- expect(receivedMessages[0].id).toBe(envelope.id);
205
- });
206
- it('should leave sub-transports subscribed when pauseForShutdown is a no-op', async () => {
207
- const receivedMessages = [];
208
- const subscription = await transport.subscribe('test-queue', async (envelope) => {
209
- receivedMessages.push(envelope);
210
- });
211
- // Both primary and secondary here are LocalTransport, whose
212
- // pauseForShutdown is a no-op — pausing the aggregate must leave both
213
- // underlying subscriptions untouched.
214
- await subscription.pauseForShutdown?.();
215
- await primary.send('test-queue', createTestEnvelope());
216
- expect(receivedMessages).toHaveLength(1);
217
- });
218
- it('should call pauseForShutdown on sub-transports that implement it', async () => {
219
- const externalPauseForShutdown = mock(async () => { });
220
- const externalMock = {
221
- name: 'rabbitmq',
222
- capabilities: {
223
- deliveryModes: ['at-least-once'],
224
- delayedMessages: false,
225
- deadLetterRouting: 'native',
226
- attemptTracking: true,
227
- concurrencyModel: 'prefetch',
228
- ordering: 'none',
229
- priorities: false,
230
- },
231
- isConnected: () => true,
232
- connect: mock(async () => { }),
233
- disconnect: mock(async () => { }),
234
- send: mock(async () => 'rabbitmq'),
235
- subscribe: mock(async () => ({
236
- unsubscribe: mock(async () => { }),
237
- pauseForShutdown: externalPauseForShutdown,
238
- isActive: true,
239
- })),
240
- applyTopology: mock(async () => { }),
241
- complete: mock(async () => { }),
242
- };
243
- const multiWithExternal = new MultiTransport({
244
- transports: [externalMock, primary],
245
- });
246
- await multiWithExternal.connect();
247
- const subscription = await multiWithExternal.subscribe('test-queue', async () => { });
248
- await subscription.pauseForShutdown?.();
249
- expect(externalPauseForShutdown).toHaveBeenCalledTimes(1);
250
- });
251
- it('should fall back to unsubscribe for sub-transports without pauseForShutdown', async () => {
252
- const externalUnsubscribe = mock(async () => { });
253
- const externalMock = {
254
- name: 'rabbitmq',
255
- capabilities: {
256
- deliveryModes: ['at-least-once'],
257
- delayedMessages: false,
258
- deadLetterRouting: 'native',
259
- attemptTracking: true,
260
- concurrencyModel: 'prefetch',
261
- ordering: 'none',
262
- priorities: false,
263
- },
264
- isConnected: () => true,
265
- connect: mock(async () => { }),
266
- disconnect: mock(async () => { }),
267
- send: mock(async () => 'rabbitmq'),
268
- subscribe: mock(async () => ({
269
- unsubscribe: externalUnsubscribe,
270
- isActive: true,
271
- })),
272
- applyTopology: mock(async () => { }),
273
- complete: mock(async () => { }),
274
- };
275
- const multiWithExternal = new MultiTransport({
276
- transports: [externalMock, primary],
277
- });
278
- await multiWithExternal.connect();
279
- const subscription = await multiWithExternal.subscribe('test-queue', async () => { });
280
- await subscription.pauseForShutdown?.();
281
- expect(externalUnsubscribe).toHaveBeenCalledTimes(1);
282
- });
283
- });
284
- describe('complete', () => {
285
- beforeEach(async () => {
286
- await transport.connect();
287
- await primary.subscribe('test-queue', async () => { });
288
- });
289
- it('should complete using primary transport', async () => {
290
- await primary.send('test-queue', createTestEnvelope());
291
- const received = await primary.receiveOne('test-queue');
292
- if (!received)
293
- throw new Error('expected received message');
294
- await transport.complete(received.receipt);
295
- expect(primary.getCompleted()).toHaveLength(1);
296
- });
297
- });
298
- describe('sendToDeadLetter', () => {
299
- beforeEach(async () => {
300
- await transport.connect();
301
- await primary.subscribe('test-queue', async () => { });
302
- });
303
- it('should send to dead letter using primary transport', async () => {
304
- const envelope = createTestEnvelope();
305
- await primary.send('test-queue', envelope);
306
- const received = await primary.receiveOne('test-queue');
307
- if (!received)
308
- throw new Error('expected received message');
309
- await transport.sendToDeadLetter(received.receipt, 'dlq', envelope, 'test error');
310
- expect(primary.getQueueSize('test-queue')).toBe(0);
311
- expect(primary.getQueueSize('test-queue.dlq')).toBe(1);
312
- });
313
- });
314
- });
315
- function createTestEnvelope() {
316
- return createEnvelope({
317
- eventKey: 'test.event',
318
- targetSubscriber: 'test-subscriber',
319
- data: { test: 'data' },
320
- importance: 'should-investigate',
321
- });
322
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=rabbitmq-transport-reconnection.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rabbitmq-transport-reconnection.test.d.ts","sourceRoot":"","sources":["../../../src/transport/rabbitmq/rabbitmq-transport-reconnection.test.ts"],"names":[],"mappings":""}