queen-mq 0.2.23 → 0.3.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 (35) hide show
  1. package/README.md +162 -136
  2. package/client-js/client-v2/LOGGING.md +240 -0
  3. package/client-js/client-v2/Queen.js +389 -0
  4. package/client-js/client-v2/README.md +1883 -0
  5. package/client-js/client-v2/buffer/BufferManager.js +215 -0
  6. package/client-js/client-v2/buffer/MessageBuffer.js +132 -0
  7. package/client-js/client-v2/builders/QueueBuilder.js +724 -0
  8. package/client-js/client-v2/builders/TransactionBuilder.js +110 -0
  9. package/client-js/client-v2/consumer/ConsumerManager.js +390 -0
  10. package/client-js/client-v2/http/HttpClient.js +215 -0
  11. package/client-js/client-v2/http/LoadBalancer.js +50 -0
  12. package/client-js/client-v2/index.js +7 -0
  13. package/client-js/client-v2/utils/defaults.js +54 -0
  14. package/client-js/client-v2/utils/logger.js +54 -0
  15. package/client-js/client-v2/utils/validation.js +31 -0
  16. package/client-js/test-v2/AI_TEST_SUMMARY.md +226 -0
  17. package/client-js/test-v2/GETTING_STARTED.md +154 -0
  18. package/client-js/test-v2/ai_buffering.js +194 -0
  19. package/client-js/test-v2/ai_error_handling.js +223 -0
  20. package/client-js/test-v2/ai_lease_renewal.js +206 -0
  21. package/client-js/test-v2/ai_mixed_scenarios.js +278 -0
  22. package/client-js/test-v2/ai_priority.js +169 -0
  23. package/client-js/test-v2/ai_resources.js +217 -0
  24. package/client-js/test-v2/ai_ttl_retention.js +170 -0
  25. package/client-js/test-v2/complete.js +59 -0
  26. package/client-js/test-v2/consume.js +655 -0
  27. package/client-js/test-v2/dlq.js +82 -0
  28. package/client-js/test-v2/load.js +177 -0
  29. package/client-js/test-v2/pop.js +114 -0
  30. package/client-js/test-v2/push.js +333 -0
  31. package/client-js/test-v2/queue.js +39 -0
  32. package/client-js/test-v2/run.js +187 -0
  33. package/client-js/test-v2/subscription.js +354 -0
  34. package/client-js/test-v2/transaction.js +443 -0
  35. package/package.json +1 -1
@@ -0,0 +1,82 @@
1
+ export async function testDLQ(client) {
2
+ const queueName = 'test-queue-v2-dlq'
3
+
4
+ // 1. Create queue with low retry limit
5
+ const queue = await client
6
+ .queue(queueName)
7
+ .config({
8
+ retryLimit: 1, // Only 1 retry before DLQ
9
+ dlqAfterMaxRetries: true // Enable DLQ after max retries
10
+ })
11
+ .create()
12
+
13
+ if (!queue.configured) {
14
+ return { success: false, message: 'Queue not created' }
15
+ }
16
+
17
+ // 2. Push a test message
18
+ const testMessage = { message: 'Test DLQ message', timestamp: Date.now() }
19
+ await client
20
+ .queue(queueName)
21
+ .push([{ data: testMessage }])
22
+
23
+ // 3. Consume and fail the message (will trigger retry then DLQ)
24
+ await client
25
+ .queue(queueName)
26
+ .batch(1)
27
+ .wait(false)
28
+ .limit(1) // Process up to 2 messages (original + retry)
29
+ .each()
30
+ .consume(async msg => {
31
+ // Always fail to trigger DLQ
32
+ throw new Error('Test error - triggering DLQ')
33
+ })
34
+ .onError(async (msg, error) => {
35
+ // Ack as failed to trigger DLQ logic
36
+ await client.ack(msg, false, { error: error.message })
37
+ })
38
+
39
+ // 4. Wait a moment for DLQ processing
40
+ await new Promise(resolve => setTimeout(resolve, 500))
41
+ // 5. Check DLQ for the message
42
+ const dlqResult = await client
43
+ .queue(queueName)
44
+ .dlq()
45
+ .limit(10)
46
+ .get()
47
+
48
+ console.log('DLQ result: ', JSON.stringify(dlqResult, null, 2))
49
+
50
+ if (!dlqResult || !dlqResult.messages) {
51
+ return { success: false, message: 'Failed to query DLQ' }
52
+ }
53
+
54
+ if (dlqResult.messages.length === 0) {
55
+ return {
56
+ success: false,
57
+ message: `No messages in DLQ. Expected at least 1 message. Total: ${dlqResult.total}`
58
+ }
59
+ }
60
+
61
+ // 6. Verify the message content
62
+ const dlqMessage = dlqResult.messages[0]
63
+
64
+ if (!dlqMessage.data || dlqMessage.data.message !== testMessage.message) {
65
+ return {
66
+ success: false,
67
+ message: 'DLQ message data does not match expected content'
68
+ }
69
+ }
70
+
71
+ if (!dlqMessage.errorMessage || !dlqMessage.errorMessage.includes('Test error')) {
72
+ return {
73
+ success: false,
74
+ message: 'DLQ message missing or incorrect error message'
75
+ }
76
+ }
77
+
78
+ return {
79
+ success: true,
80
+ message: `DLQ test completed successfully. Found ${dlqResult.total} message(s) in DLQ`
81
+ }
82
+ }
@@ -0,0 +1,177 @@
1
+ export async function testLoad(client) {
2
+ const queue = await client
3
+ .queue('test-queue-v2-load')
4
+ .create()
5
+ if (!queue.configured) {
6
+ return { success: false, message: 'Queue not created' }
7
+ }
8
+
9
+ const messagesToPush = 100000;
10
+
11
+ let messages = [];
12
+ for (let i = 0; i < messagesToPush; i++) {
13
+ messages.push({ data: { id: i } })
14
+ if (messages.length >= 10000) {
15
+ await client.queue('test-queue-v2-load').push(messages)
16
+ messages = [];
17
+ }
18
+ }
19
+ await client.queue('test-queue-v2-load').push(messages)
20
+
21
+ let uniqueIds = new Set();
22
+ let lastId = null;
23
+
24
+ await client
25
+ .queue('test-queue-v2-load')
26
+ .concurrency(10)
27
+ .batch(10000)
28
+ .wait(false)
29
+ .limit(1)
30
+ .consume(async msgs => {
31
+ console.log(`Messages: ${msgs.length}`)
32
+ for (const msg of msgs) {
33
+ if (lastId === null) {
34
+ lastId = msg.data.id
35
+ } else {
36
+ if (msg.data.id !== lastId + 1) {
37
+ throw new Error('Message ordering violation')
38
+ }
39
+ lastId = msg.data.id
40
+ }
41
+ uniqueIds.add(msg.data.id)
42
+ }
43
+ })
44
+
45
+ const uniqueIdsCount = uniqueIds.size;
46
+ console.log(`Unique IDs count: ${uniqueIdsCount}`)
47
+
48
+ return { success: uniqueIdsCount === messagesToPush, message: 'Load test completed successfully' }
49
+ }
50
+
51
+ export async function testLoadPartition(client) {
52
+ const queue = await client
53
+ .queue('test-queue-v2-load-partition')
54
+ .create()
55
+ if (!queue.configured) {
56
+ return { success: false, message: 'Queue not created' }
57
+ }
58
+
59
+ const messagesToPush = 100000;
60
+
61
+ let messages = [];
62
+ let k = 0
63
+ for (let i = 0; i < messagesToPush; i++) {
64
+ messages.push({ data: { id: i } })
65
+ if (messages.length >= 10000) {
66
+ await client
67
+ .queue('test-queue-v2-load-partition')
68
+ .partition(k.toString())
69
+ .push(messages)
70
+ messages = [];
71
+ k++;
72
+ }
73
+ }
74
+ await client.queue('test-queue-v2-load-partition').push(messages)
75
+
76
+ let uniqueIds = new Set();
77
+ let lastId = null;
78
+
79
+ for (let i = 0; i < 10; i++) {
80
+ await client
81
+ .queue('test-queue-v2-load-partition')
82
+ .partition(i.toString())
83
+ .batch(10000)
84
+ .wait(false)
85
+ .limit(1)
86
+ .consume(async msgs => {
87
+ for (const msg of msgs) {
88
+ if (lastId === null) {
89
+ lastId = msg.data.id
90
+ } else {
91
+ if (msg.data.id !== lastId + 1) {
92
+ throw new Error('Message ordering violation')
93
+ }
94
+ lastId = msg.data.id
95
+ }
96
+ uniqueIds.add(msg.data.id)
97
+ }
98
+ })
99
+ }
100
+
101
+ const uniqueIdsCount = uniqueIds.size;
102
+
103
+ return { success: uniqueIdsCount === messagesToPush, message: 'Load test completed successfully' }
104
+ }
105
+
106
+ export async function testLoadConsumerGroup(client) {
107
+ const queue = await client
108
+ .queue('test-queue-v2-load-consumer-group')
109
+ .create()
110
+ if (!queue.configured) {
111
+ return { success: false, message: 'Queue not created' }
112
+ }
113
+
114
+ const messagesToPush = 100000;
115
+
116
+ let messages = [];
117
+ for (let i = 0; i < messagesToPush; i++) {
118
+ messages.push({ data: { id: i } })
119
+ if (messages.length >= 10000) {
120
+ await client.queue('test-queue-v2-load-consumer-group').push(messages)
121
+ messages = [];
122
+ }
123
+ }
124
+ await client.queue('test-queue-v2-load-consumer-group').push(messages)
125
+
126
+ let uniqueIdsA = new Set();
127
+ let lastIdA = null;
128
+
129
+ await client
130
+ .queue('test-queue-v2-load-consumer-group')
131
+ .group('test-consumer-group-a')
132
+ .concurrency(10)
133
+ .batch(10000)
134
+ .wait(false)
135
+ .limit(1)
136
+ .consume(async msgs => {
137
+ for (const msg of msgs) {
138
+ if (lastIdA === null) {
139
+ lastIdA = msg.data.id
140
+ } else {
141
+ if (msg.data.id !== lastIdA + 1) {
142
+ throw new Error('Message ordering violation')
143
+ }
144
+ lastIdA = msg.data.id
145
+ }
146
+ uniqueIdsA.add(msg.data.id)
147
+ }
148
+ })
149
+
150
+ let uniqueIdsB = new Set();
151
+ let lastIdB = null;
152
+
153
+ await client
154
+ .queue('test-queue-v2-load-consumer-group')
155
+ .group('test-consumer-group-b')
156
+ .concurrency(10)
157
+ .batch(10000)
158
+ .wait(false)
159
+ .limit(1)
160
+ .consume(async msgs => {
161
+ for (const msg of msgs) {
162
+ if (lastIdB === null) {
163
+ lastIdB = msg.data.id
164
+ } else {
165
+ if (msg.data.id !== lastIdB + 1) {
166
+ throw new Error('Message ordering violation')
167
+ }
168
+ lastIdB = msg.data.id
169
+ }
170
+ uniqueIdsB.add(msg.data.id)
171
+ }
172
+ })
173
+
174
+ const uniqueIdsCountA = uniqueIdsA.size;
175
+ const uniqueIdsCountB = uniqueIdsB.size;
176
+ return { success: uniqueIdsCountA === messagesToPush && uniqueIdsCountB === messagesToPush, message: 'Load test completed successfully' }
177
+ }
@@ -0,0 +1,114 @@
1
+ export async function popEmptyQueue(client) {
2
+ const queue = await client.queue('test-queue-v2-pop-empty').create()
3
+ if (!queue.configured) {
4
+ return { success: false, message: 'Queue not created' }
5
+ }
6
+ const res = await client
7
+ .queue('test-queue-v2-pop-empty')
8
+ .batch(1) // Fetch 1 message
9
+ .wait(false)
10
+ .pop()
11
+ return { success: res.length === 0 }
12
+ }
13
+
14
+ export async function popNonEmptyQueue(client) {
15
+ const queue = await client.queue('test-queue-v2-pop-non-empty').create()
16
+ if (!queue.configured) {
17
+ return { success: false, message: 'Queue not created' }
18
+ }
19
+ await client
20
+ .queue('test-queue-v2-pop-non-empty')
21
+ .push([{ data: { message: 'Hello, world!' } }])
22
+
23
+ const res = await client
24
+ .queue('test-queue-v2-pop-non-empty')
25
+ .batch(1)
26
+ .wait(false)
27
+ .pop()
28
+ return { success: res.length === 1 }
29
+ }
30
+
31
+ export async function popWithWait(client) {
32
+ const queue = await client.queue('test-queue-v2-pop-with-wait').create()
33
+ if (!queue.configured) {
34
+ return { success: false, message: 'Queue not created' }
35
+ }
36
+ setTimeout(async () => {
37
+ await client
38
+ .queue('test-queue-v2-pop-with-wait')
39
+ .push([{ data: { message: 'Hello, world!' } }])
40
+ }, 2000);
41
+
42
+ const res = await client
43
+ .queue('test-queue-v2-pop-with-wait')
44
+ .batch(1)
45
+ .wait(true)
46
+ .pop()
47
+
48
+ return { success: res.length === 1 }
49
+ }
50
+
51
+ export async function popWithAck(client) {
52
+ const queue = await client.queue('test-queue-v2-pop-with-ack').create()
53
+ if (!queue.configured) {
54
+ return { success: false, message: 'Queue not created' }
55
+ }
56
+ await client
57
+ .queue('test-queue-v2-pop-with-ack')
58
+ .push([{ data: { message: 'Hello, world!' } }])
59
+
60
+
61
+ const res = await client
62
+ .queue('test-queue-v2-pop-with-ack')
63
+ .batch(1)
64
+ .wait(false)
65
+ .pop()
66
+
67
+ const resAck = await client.ack(res[0])
68
+
69
+ if (!resAck.success) {
70
+ return { success: false, message: `Ack failed: ${resAck.error}` }
71
+ }
72
+
73
+ return { success: true, message: 'Message popped and acked successfully' }
74
+ }
75
+
76
+ export async function popWithAckReconsume(client) {
77
+ const queue = await client
78
+ .queue('test-queue-v2-pop-with-ack-reconsume')
79
+ .config({
80
+ leaseTime: 1, // 1 second lease
81
+ })
82
+ .create()
83
+ if (!queue.configured) {
84
+ return { success: false, message: 'Queue not created' }
85
+ }
86
+
87
+ await client
88
+ .queue('test-queue-v2-pop-with-ack-reconsume')
89
+ .push([{ data: { message: 'Hello, world!' } }])
90
+
91
+ const res = await client
92
+ .queue('test-queue-v2-pop-with-ack-reconsume')
93
+ .batch(1)
94
+ .wait(false)
95
+ .pop()
96
+
97
+ if (res.length !== 1) {
98
+ return { success: false, message: `Expected 1 message, got ${res.length}` }
99
+ }
100
+
101
+ await new Promise(r => setTimeout(r, 2000))
102
+
103
+ const res2 = await client
104
+ .queue('test-queue-v2-pop-with-ack-reconsume')
105
+ .batch(1)
106
+ .wait(true)
107
+ .pop()
108
+
109
+ if (res2.length === 1) {
110
+ return { success: true, message: 'Message consumed and reconsumed after lease expiry' }
111
+ }
112
+ return { success: false, message: `Expected 1 message, got ${res2.length}` }
113
+ }
114
+
@@ -0,0 +1,333 @@
1
+ import crypto from 'crypto';
2
+
3
+ export async function pushMessage(client) {
4
+ const queue = await client.queue('test-queue-v2').create()
5
+ if (!queue.configured) {
6
+ return { success: false, message: 'Queue not created' }
7
+ }
8
+ const res = await client
9
+ .queue('test-queue-v2')
10
+ .push([{ data: { message: 'Hello, world!' } }])
11
+
12
+ return { success: res[0].status === 'queued' }
13
+ }
14
+
15
+ export async function pushDuplicateMessage(client) {
16
+ const queue = await client.queue('test-queue-v2').create()
17
+ if (!queue.configured) {
18
+ return { success: false, message: 'Queue not created' }
19
+ }
20
+ const res1 = await client
21
+ .queue('test-queue-v2')
22
+ .push([{ transactionId: 'test-transaction-id', data: { message: 'Hello, world!' } }])
23
+
24
+ const res2 = await client
25
+ .queue('test-queue-v2')
26
+ .push([{ transactionId: 'test-transaction-id', data: { message: 'Hello, world!' } }])
27
+
28
+ return { success: res1[0].status === 'queued' && res2[0].status === 'duplicate' }
29
+ }
30
+
31
+ export async function pushDuplicateMessageOnSpecificPartition(client) {
32
+ const queue = await client.queue('test-queue-partition-duplicate').create()
33
+ if (!queue.configured) {
34
+ return { success: false, message: 'Queue not created' }
35
+ }
36
+ const res1 = await client
37
+ .queue('test-queue-partition-duplicate')
38
+ .partition('0')
39
+ .push([{ transactionId: 'test-transaction-id', data: { message: 'Hello, world!' } }])
40
+
41
+ const res2 = await client
42
+ .queue('test-queue-partition-duplicate')
43
+ .partition('0')
44
+ .push([{ transactionId: 'test-transaction-id', data: { message: 'Hello, world!' } }])
45
+
46
+ return { success: res1[0].status === 'queued' && res2[0].status === 'duplicate' }
47
+ }
48
+
49
+ export async function pushDuplicateMessageOnDifferentPartition(client) {
50
+ const queue = await client.queue('test-queue-partition-duplicate-different').create()
51
+ if (!queue.configured) {
52
+ return { success: false, message: 'Queue not created' }
53
+ }
54
+ const res1 = await client
55
+ .queue('test-queue-partition-duplicate-different')
56
+ .partition('0')
57
+ .push([{ transactionId: 'test-transaction-id', data: { message: 'Hello, world!' } }])
58
+
59
+ const res2 = await client
60
+ .queue('test-queue-partition-duplicate-different')
61
+ .partition('1')
62
+ .push([{ transactionId: 'test-transaction-id', data: { message: 'Hello, world!' } }])
63
+ const success = res1[0].status === 'queued' && res2[0].status === 'queued'
64
+
65
+ return { success: success }
66
+ }
67
+
68
+ export async function pushMessageWithTransactionId(client) {
69
+ const queue = await client.queue('test-queue-transaction-id').create()
70
+ if (!queue.configured) {
71
+ return { success: false, message: 'Queue not created' }
72
+ }
73
+ const res = await client
74
+ .queue('test-queue-transaction-id')
75
+ .push([{ transactionId: 'test-transaction-id', data: { message: 'Hello, world!' } }])
76
+
77
+ if (res[0].status !== 'queued' && res[0].transactionId !== 'test-transaction-id') {
78
+ return { success: false, message: 'Transaction ID mismatch' }
79
+ }
80
+ return { success: true }
81
+ }
82
+
83
+ export async function pushBufferedMessage(client) {
84
+ const queue = await client.queue('test-queue-buffered').create()
85
+ if (!queue.configured) {
86
+ return { success: false, message: 'Queue not created' }
87
+ }
88
+ const res = await client
89
+ .queue('test-queue-buffered')
90
+ .buffer({ messageCount: 10, timeMillis: 1000 })
91
+ .push([{ data: { message: 'Hello, world!' } }])
92
+
93
+ const pop = await client
94
+ .queue('test-queue-buffered')
95
+ .batch(1)
96
+ .wait(false)
97
+ .pop()
98
+
99
+ if (pop.length !== 0) {
100
+ return { success: false, message: 'Message not buffered' }
101
+ }
102
+
103
+ await new Promise(r => setTimeout(r, 2000));
104
+
105
+ const pop2 = await client
106
+ .queue('test-queue-buffered')
107
+ .batch(1)
108
+ .wait(false)
109
+ .pop()
110
+
111
+ if (pop2.length === 0) {
112
+ return { success: false, message: 'Message not popped' }
113
+ }
114
+
115
+ return { success: true }
116
+ }
117
+
118
+ export async function pushMaxQueueSize(client) {
119
+ const queue = await client.queue('test-queue-max-size').config({ maxSize: 10 }).create()
120
+ if (!queue.configured) {
121
+ return { success: false, message: 'Queue not created' }
122
+ }
123
+
124
+ // Necessary to create a partition consumer to trigger the capacity check
125
+ const popToCreateParititonConsumer = await client
126
+ .queue('test-queue-max-size')
127
+ .batch(1)
128
+ .wait(false)
129
+ .pop()
130
+
131
+ try {
132
+ for (let i = 0; i < 20; i++) {
133
+ const result = await client
134
+ .queue('test-queue-max-size')
135
+ .push([{ data: { message: i } }])
136
+ }
137
+ } catch (error) {
138
+ if (!error.message.includes(' Queue "test-queue-max-size" would exceed max capacity (10).')) {
139
+ return { success: true, message: 'Correct error message' }
140
+ } else {
141
+ return { success: false, message: 'Incorrect error message' }
142
+ }
143
+ }
144
+ return { success: false }
145
+ }
146
+
147
+ export async function pushDelayedMessage(client) {
148
+ const queue = await client.queue('test-queue-delayed')
149
+ .config({ delayedProcessing: 2 })
150
+ .create()
151
+ if (!queue.configured) {
152
+ return { success: false, message: 'Queue not created' }
153
+ }
154
+ const res = await client
155
+ .queue('test-queue-delayed')
156
+ .push([{ transactionId: 'test-transaction-dealyed-id', data: { message: 'Hello, world!', aaa: '1' } }])
157
+
158
+ const pop = await client
159
+ .queue('test-queue-delayed')
160
+ .batch(1)
161
+ .wait(false)
162
+ .pop()
163
+
164
+
165
+
166
+ if (pop.length !== 0) {
167
+ return { success: false, message: 'Message not delayed' }
168
+ }
169
+
170
+ await new Promise(r => setTimeout(r, 2500));
171
+
172
+ const pop2 = await client
173
+ .queue('test-queue-delayed')
174
+ .batch(1)
175
+ .wait(true)
176
+ .pop()
177
+
178
+ if (pop2.length === 1) {
179
+ return { success: true, message: 'Message delayed' }
180
+ }
181
+
182
+ return { success: false, message: 'Message not delayed' }
183
+ }
184
+
185
+ export async function pushWindowBuffer(client) {
186
+ const queue = await client.queue('test-queue-window-buffer')
187
+ .config({ windowBuffer: 2 })
188
+ .create()
189
+ if (!queue.configured) {
190
+ return { success: false, message: 'Queue not created' }
191
+ }
192
+ const res = await client
193
+ .queue('test-queue-window-buffer')
194
+ .push(
195
+ [
196
+ { data: { message: 'Hello, world 1!' } },
197
+ { data: { message: 'Hello, world 2!' } },
198
+ { data: { message: 'Hello, world 3!' } }
199
+ ])
200
+
201
+ const pop = await client
202
+ .queue('test-queue-window-buffer')
203
+ .batch(1)
204
+ .wait(false)
205
+ .pop()
206
+
207
+ if (pop.length !== 0) {
208
+ return { success: false, message: 'Message not delayed' }
209
+ }
210
+
211
+ await new Promise(r => setTimeout(r, 2500));
212
+
213
+ const pop2 = await client
214
+ .queue('test-queue-window-buffer')
215
+ .batch(4)
216
+ .wait(false)
217
+ .pop()
218
+ if (pop2.length === 3) {
219
+ return { success: true, message: 'Window buffer works correctly' }
220
+ }
221
+
222
+ return { success: false, message: 'Window buffer does not work correctly' }
223
+ }
224
+
225
+ export async function pushLargePayload(client) {
226
+ const queue = await client.queue('test-queue-large-payload').create()
227
+ if (!queue.configured) {
228
+ return { success: false, message: 'Queue not created' }
229
+ }
230
+ // Create a large payload (1MB of data)
231
+ const largeArray = new Array(10000).fill({
232
+ id: crypto.randomBytes(16).toString('hex'),
233
+ data: 'x'.repeat(100),
234
+ nested: {
235
+ field1: 'value1',
236
+ field2: 'value2',
237
+ field3: 'value3'
238
+ }
239
+ });
240
+
241
+ const largePayload = {
242
+ array: largeArray,
243
+ metadata: {
244
+ size: JSON.stringify(largeArray).length,
245
+ timestamp: Date.now()
246
+ }
247
+ };
248
+
249
+ const res = await client
250
+ .queue('test-queue-large-payload')
251
+ .push([{ data: largePayload }])
252
+
253
+ const received = await client
254
+ .queue('test-queue-large-payload')
255
+ .batch(1)
256
+ .wait(false)
257
+ .pop()
258
+
259
+ if (!received || !received[0].data || !received[0].data.array || received[0].data.array.length !== 10000) {
260
+ return { success: false, message: 'Large payload corrupted' }
261
+ }
262
+
263
+ return { success: true }
264
+ }
265
+
266
+ export async function pushNullPayload(client) {
267
+ const queue = await client.queue('test-queue-null-payload').create()
268
+ if (!queue.configured) {
269
+ return { success: false, message: 'Queue not created' }
270
+ }
271
+ const res = await client
272
+ .queue('test-queue-null-payload')
273
+ .push([{ data: null }])
274
+
275
+ const received = await client
276
+ .queue('test-queue-null-payload')
277
+ .batch(1)
278
+ .wait(false)
279
+ .pop()
280
+
281
+ if (!received || received[0].data !== null) {
282
+ return { success: false, message: 'Null data corrupted' }
283
+ }
284
+
285
+ return { success: true }
286
+ }
287
+
288
+ export async function pushEmptyPayload(client) {
289
+ const queue = await client.queue('test-queue-empty-payload').create()
290
+ if (!queue.configured) {
291
+ return { success: false, message: 'Queue not created' }
292
+ }
293
+ const res = await client
294
+ .queue('test-queue-empty-payload')
295
+ .push([{ data: {} }])
296
+
297
+ const received = await client
298
+ .queue('test-queue-empty-payload')
299
+ .batch(1)
300
+ .wait(false)
301
+ .pop()
302
+
303
+ if (!received || Object.keys(received[0].data).length !== 0) {
304
+ return { success: false, message: 'Empty object payload corrupted' }
305
+ }
306
+
307
+ return { success: true }
308
+ }
309
+
310
+ export async function pushEncryptedPayload(client) {
311
+ const queue = await client.queue('test-queue-encrypted-payload')
312
+ .config({ encryptionEnabled: true })
313
+ .create()
314
+ if (!queue.configured) {
315
+ return { success: false, message: 'Queue not created' }
316
+ }
317
+ const res = await client
318
+ .queue('test-queue-encrypted-payload')
319
+ .push([{ data: { message: 'Hello, world!' } }])
320
+
321
+ const received = await client
322
+ .queue('test-queue-encrypted-payload')
323
+ .batch(1)
324
+ .wait(false)
325
+ .pop()
326
+
327
+
328
+ if (!received || received[0].data.message !== 'Hello, world!') {
329
+ return { success: false, message: 'Encrypted payload corrupted' }
330
+ }
331
+
332
+ return { success: true }
333
+ }