@defra-fish/sqs-receiver-service 1.61.0-rc.9 → 1.62.0-rc.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.
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@defra-fish/sqs-receiver-service",
3
- "version": "1.61.0-rc.9",
3
+ "version": "1.62.0-rc.0",
4
4
  "description": "SQS Receiver service",
5
5
  "type": "module",
6
6
  "engines": {
7
- "node": ">=18.17"
7
+ "node": ">=20"
8
8
  },
9
9
  "keywords": [
10
10
  "rod",
@@ -35,7 +35,7 @@
35
35
  "test": "echo \"Error: run tests from root\" && exit 1"
36
36
  },
37
37
  "dependencies": {
38
- "@defra-fish/connectors-lib": "1.61.0-rc.9",
38
+ "@defra-fish/connectors-lib": "1.62.0-rc.0",
39
39
  "debug": "^4.3.1",
40
40
  "joi": "^17.3.0",
41
41
  "node-fetch": "^2.6.1",
@@ -44,5 +44,5 @@
44
44
  "devDependencies": {
45
45
  "pm2": "^4.5.6"
46
46
  },
47
- "gitHead": "b9c65c7827bb974c94056bf5e387d80564d3ddc6"
47
+ "gitHead": "d56e1a0d0f4b22f1dded800c0ed511b737cb91a7"
48
48
  }
@@ -1,9 +1,33 @@
1
1
  'use strict'
2
2
 
3
3
  import deleteMessages from '../delete-messages'
4
- import AWS from 'aws-sdk'
4
+ import { AWS } from '@defra-fish/connectors-lib'
5
+ const { sqs } = AWS.mock.results[0].value
6
+
7
+ const getSampleDeleteMessageBatchResponse = (successfulIds, failedIds = []) => ({
8
+ ResponseMetadata: {
9
+ RequestId: '00000000-0000-0000-0000-000000000000'
10
+ },
11
+ Successful: successfulIds.map(Id => ({ Id })),
12
+ Failed: failedIds.map(Id => ({ Id }))
13
+ })
14
+
15
+ jest.mock('@defra-fish/connectors-lib', () => ({
16
+ AWS: jest.fn(() => ({
17
+ sqs: {
18
+ deleteMessageBatch: jest.fn(() => {})
19
+ }
20
+ }))
21
+ }))
22
+
23
+ beforeEach(() => {
24
+ sqs.deleteMessageBatch.mockClear()
25
+ })
5
26
 
6
27
  test('Delete messages successfully', async () => {
28
+ sqs.deleteMessageBatch.mockResolvedValueOnce(
29
+ getSampleDeleteMessageBatchResponse(['58f6f3c9-97f8-405a-a3a7-5ac467277521', '58f6f3c9-97f8-405a-a3a7-5ac467277522'])
30
+ )
7
31
  const results = await deleteMessages('http://0.0.0.0:0000/queue', [
8
32
  {
9
33
  id: '58f6f3c9-97f8-405a-a3a7-5ac467277521',
@@ -26,6 +50,7 @@ test('Delete messages successfully', async () => {
26
50
  })
27
51
 
28
52
  test('Delete messages nothing to delete', async () => {
53
+ sqs.deleteMessageBatch.mockResolvedValueOnce(getSampleDeleteMessageBatchResponse([]))
29
54
  const results = await deleteMessages('http://0.0.0.0:0000/queue', [
30
55
  {
31
56
  id: '58f6f3c9-97f8-405a-a3a7-5ac467277521',
@@ -45,11 +70,14 @@ test('Delete messages nothing to delete', async () => {
45
70
  ])
46
71
 
47
72
  expect(results).toBeUndefined()
73
+ sqs.deleteMessageBatch.mockReset()
48
74
  })
49
75
 
50
76
  test('Delete messages with failures', async () => {
51
77
  const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {})
52
- AWS.__mockDeleteMessageFailures()
78
+ sqs.deleteMessageBatch.mockResolvedValueOnce(
79
+ getSampleDeleteMessageBatchResponse([], ['58f6f3c9-97f8-405a-a3a7-5ac467277521', '58f6f3c9-97f8-405a-a3a7-5ac467277522'])
80
+ )
53
81
  const results = await deleteMessages('http://0.0.0.0:0000/queue', [
54
82
  {
55
83
  id: '58f6f3c9-97f8-405a-a3a7-5ac467277521',
@@ -73,7 +101,9 @@ test('Delete messages with failures', async () => {
73
101
  })
74
102
 
75
103
  test('Delete message does not throw exception', async () => {
76
- AWS.__mockNotFound()
104
+ const exception = new Error('Not Found')
105
+ exception.code = 404
106
+ sqs.deleteMessageBatch.mockRejectedValueOnce(exception)
77
107
 
78
108
  const result = await deleteMessages('http://0.0.0.0:0000/queue', [
79
109
  {
@@ -84,3 +114,20 @@ test('Delete message does not throw exception', async () => {
84
114
  ])
85
115
  expect(result).toBeUndefined()
86
116
  })
117
+
118
+ test('Delete message batch logs exception with console.error', async () => {
119
+ const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {})
120
+ const exception = new Error('Not Found')
121
+ exception.code = 404
122
+ const url = 'http://0.0.0.0:0000/queue'
123
+ sqs.deleteMessageBatch.mockRejectedValueOnce(exception)
124
+
125
+ await deleteMessages(url, [
126
+ {
127
+ id: '58f6f3c9-97f8-405a-a3a7-5ac467277521',
128
+ handle: '58f6f3c9-97f8-405a-a3a7-5ac467277521#03f003bc-7770-41c2-9217-aed966b578b1',
129
+ status: 200
130
+ }
131
+ ])
132
+ expect(consoleError).toHaveBeenCalledWith('Error deleting messages for %s: %o', url, exception)
133
+ })
@@ -1,19 +1,73 @@
1
1
  'use strict'
2
2
 
3
3
  import readQueue from '../read-queue'
4
- import AWS from 'aws-sdk'
4
+ import { AWS } from '@defra-fish/connectors-lib'
5
+ const { sqs } = AWS.mock.results[0].value
6
+
7
+ jest.mock('@defra-fish/connectors-lib', () => ({
8
+ AWS: jest.fn(() => ({
9
+ sqs: {
10
+ receiveMessage: jest.fn(() => ({ Messages: [] }))
11
+ }
12
+ }))
13
+ }))
14
+
15
+ const getSampleError = (httpStatusCode = undefined) => {
16
+ const error = new Error('Queue error')
17
+ if (httpStatusCode) {
18
+ error.$metadata = { httpStatusCode }
19
+ }
20
+ return error
21
+ }
22
+
23
+ beforeEach(() => {
24
+ sqs.receiveMessage.mockClear()
25
+ })
5
26
 
6
27
  test('Nothing queued', async () => {
7
- AWS.__mockEmptyQueue()
8
28
  const messages = await readQueue('http://0.0.0.0:0000/queue')
9
29
  expect(messages).toHaveLength(0)
10
30
  })
11
31
 
32
+ test.each`
33
+ queueUrl | visibilityTimeoutMs | waitTimeMs | expectedVTS | expectedWTS
34
+ ${'http://0.0.0.0:0000/queue'} | ${1000} | ${2000} | ${1} | ${2}
35
+ ${'http://1.2.3.4:5432/line'} | ${3000} | ${4000} | ${3} | ${4}
36
+ ${'http://9.8.7.6:1234/joinThe'} | ${7000} | ${20000} | ${7} | ${20}
37
+ `(
38
+ 'Specifies message configuration: queue url $queueUrl read with visibility timeout $expectedVTS seconds and a wait time of $expectedWTS seconds',
39
+ async ({ queueUrl, visibilityTimeoutMs, waitTimeMs, expectedVTS, expectedWTS }) => {
40
+ await readQueue(queueUrl, visibilityTimeoutMs, waitTimeMs)
41
+ expect(sqs.receiveMessage).toHaveBeenCalledWith(
42
+ expect.objectContaining({
43
+ QueueUrl: queueUrl,
44
+ MaxNumberOfMessages: 10,
45
+ MessageAttributeNames: ['/*'],
46
+ AttributeNames: ['MessageGroupId'],
47
+ VisibilityTimeout: expectedVTS,
48
+ WaitTimeSeconds: expectedWTS
49
+ })
50
+ )
51
+ }
52
+ )
53
+
12
54
  test('One message queued', async () => {
13
- AWS.__mockOneMessage()
55
+ sqs.receiveMessage.mockResolvedValueOnce({
56
+ Messages: [
57
+ {
58
+ MessageId: '15eb8abc-c7c1-4167-9590-839c8feed6dd',
59
+ ReceiptHandle: '15eb8abc-c7c1-4167-9590-839c8feed6dd#9be8971c-f9a9-4bb2-8515-98cdab660e1b',
60
+ MD5OfBody: '640ad880b5be372fcb5c5ad8b5eb50af',
61
+ Body: '{"id":"7f6e04fe-4cec-4f40-b763-8c66d71062d9"}',
62
+ Attributes: {
63
+ MessageGroupId: 'service-1'
64
+ }
65
+ }
66
+ ]
67
+ })
14
68
  const messages = await readQueue('http://0.0.0.0:0000/queue')
15
69
  expect(messages).toHaveLength(1)
16
- expect(messages).toContainEqual({
70
+ expect(messages[0]).toMatchObject({
17
71
  MessageId: '15eb8abc-c7c1-4167-9590-839c8feed6dd',
18
72
  ReceiptHandle: '15eb8abc-c7c1-4167-9590-839c8feed6dd#9be8971c-f9a9-4bb2-8515-98cdab660e1b',
19
73
  MD5OfBody: '640ad880b5be372fcb5c5ad8b5eb50af',
@@ -25,29 +79,50 @@ test('One message queued', async () => {
25
79
  })
26
80
 
27
81
  test('Five messages queued', async () => {
28
- AWS.__mockNMessages(5)
29
- const messages = await readQueue('http://0.0.0.0:0000/queue')
30
- expect(messages).toHaveLength(5)
82
+ const messages = Array(5)
83
+ .fill(null)
84
+ .map((_, i) => ({
85
+ MessageId: `msg-${i}`,
86
+ ReceiptHandle: `handle-${i}`,
87
+ MD5OfBody: 'hash',
88
+ Body: '{}',
89
+ Attributes: { MessageGroupId: 'service-1' }
90
+ }))
91
+ sqs.receiveMessage.mockResolvedValueOnce({ Messages: messages })
92
+ const result = await readQueue('http://0.0.0.0:0000/queue')
93
+ expect(result).toHaveLength(5)
31
94
  })
32
95
 
33
- test('Throws exception on no queue available', async () => {
96
+ test.each([
97
+ ['when error contains http status code', 500],
98
+ ["when error doesn't contain http status code", undefined]
99
+ ])('Writes error to console %s', async (_d, httpStatusCode) => {
34
100
  const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {})
35
- AWS.__mockFailNoQueue()
36
- async function check () {
37
- try {
38
- return readQueue('http://0.0.0.0:0000/queue')
39
- } catch (error) {
40
- throw new Error()
41
- }
101
+ const e = getSampleError(httpStatusCode)
102
+ sqs.receiveMessage.mockRejectedValueOnce(e)
103
+ try {
104
+ await readQueue('http://0.0.0.0:0000/queue')
105
+ } catch {
106
+ // swallow error (if it's thrown) as we're not interested in it
42
107
  }
43
- await expect(check()).rejects.toThrow(Error)
44
108
  expect(consoleError).toHaveBeenCalled()
45
109
  })
46
110
 
47
- test('Completes on general processing error', async () => {
48
- const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {})
49
- AWS.__mockAWSError()
111
+ test('Handles queue errors gracefully', async () => {
112
+ jest.spyOn(console, 'error').mockImplementation(() => {})
113
+ sqs.receiveMessage.mockRejectedValueOnce(getSampleError(500))
50
114
  const result = await readQueue('http://0.0.0.0:0000/queue')
51
- expect(result).toStrictEqual([])
52
- expect(consoleError).toHaveBeenCalled()
115
+ expect(result).toEqual([])
116
+ })
117
+
118
+ test("If error doesn't contain an HTTP status code, it is re-thrown", async () => {
119
+ jest.spyOn(console, 'error').mockImplementation(() => {})
120
+ sqs.receiveMessage.mockRejectedValueOnce(getSampleError())
121
+ await expect(readQueue('http://0.0.0.0:0000/queue')).rejects.toThrow('Queue error')
122
+ })
123
+
124
+ test("messages default to an empty array if messages key isn't available on receiveMessage return value", async () => {
125
+ sqs.receiveMessage.mockResolvedValueOnce({})
126
+ const result = await readQueue('http://0.0.0.0:0000/queue')
127
+ expect(result).toEqual([])
53
128
  })
@@ -1,13 +1,57 @@
1
- import AWS from 'aws-sdk'
2
1
  import fetch from 'node-fetch'
3
2
  import testEnv from '../../test-env'
3
+ import { AWS } from '@defra-fish/connectors-lib'
4
+ import { v4 as uuidv4 } from 'uuid'
5
+
6
+ jest.mock('@defra-fish/connectors-lib', () => {
7
+ const AWS = jest.fn(() => ({
8
+ sqs: {
9
+ getQueueAttributes: jest.fn(() => ({
10
+ Attributes: {
11
+ ApproximateNumberOfMessagesDelayed: 0,
12
+ ApproximateNumberOfMessagesNotVisible: 0,
13
+ ApproximateNumberOfMessages: 0
14
+ }
15
+ })),
16
+ receiveMessage: jest.fn(() => ({
17
+ Messages: []
18
+ })),
19
+ send: jest.fn()
20
+ }
21
+ }))
22
+ return { AWS }
23
+ })
24
+
25
+ const getSampleMessages = (number = 1) => {
26
+ const Messages = []
27
+ for (let i = 0; i < number; i++) {
28
+ Messages.push({
29
+ MessageId: uuidv4(),
30
+ ReceiptHandle: '15eb8abc-c7c1-4167-9590-839c8feed6dd#9be8971c-f9a9-4bb2-8515-98cdab660e1b',
31
+ Body: `{"id":"${uuidv4()}"}`,
32
+ Attributes: {
33
+ MessageGroupId: 'service-1'
34
+ }
35
+ })
36
+ }
37
+ return {
38
+ ResponseMetadata: {
39
+ RequestId: '00000000-0000-0000-0000-000000000000'
40
+ },
41
+ Messages
42
+ }
43
+ }
4
44
 
5
45
  let receiver
46
+ let sqs
6
47
 
7
48
  beforeEach(() => {
8
49
  jest.clearAllMocks()
9
50
  process.env = Object.assign(process.env, testEnv)
10
51
  receiver = require('../receiver').default
52
+ if (!sqs) {
53
+ sqs = AWS.mock.results[0].value.sqs
54
+ }
11
55
  })
12
56
 
13
57
  afterAll(() => {
@@ -15,25 +59,24 @@ afterAll(() => {
15
59
  })
16
60
 
17
61
  test('One message: completes without error', async () => {
18
- AWS.__mockOneMessage()
62
+ sqs.receiveMessage.mockResolvedValueOnce(getSampleMessages())
19
63
  fetch.__goodResult()
20
64
  await expect(receiver()).resolves.toBeUndefined()
21
65
  })
22
66
 
23
67
  test('No messages: complete without error', async () => {
24
- AWS.__mockEmptyQueue()
25
68
  fetch.__goodResult()
26
69
  await expect(receiver()).resolves.toBeUndefined()
27
70
  })
28
71
 
29
72
  test('10 messages: complete without error', async () => {
30
- AWS.__mockNMessages(10)
73
+ sqs.receiveMessage.mockResolvedValueOnce(getSampleMessages(10))
31
74
  fetch.__goodResult()
32
75
  await expect(receiver()).resolves.toBeUndefined()
33
76
  })
34
77
 
35
78
  test('Imposes delay after several empty reads', async () => {
36
- AWS.__mockEmptyQueue()
79
+ sqs.receiveMessage.mockResolvedValueOnce({ Messages: [] })
37
80
  fetch.__goodResult()
38
81
  const setTimeoutSpy = jest.spyOn(global, 'setTimeout').mockImplementation(cb => cb())
39
82
  for (let i = 0; i < testEnv.TEST_ATTEMPTS_WITH_NO_DELAY; i++) {
@@ -44,7 +87,10 @@ test('Imposes delay after several empty reads', async () => {
44
87
 
45
88
  test('Receiver: throws exception on general error', async () => {
46
89
  const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {})
47
- AWS.__mockFailNoQueue()
90
+ const queueError = new Error('connect ECONNREFUSED 0.0.0.0:9325')
91
+ queueError.code = 'NetworkingError'
92
+ sqs.receiveMessage.mockRejectedValueOnce(queueError)
93
+
48
94
  await expect(receiver()).rejects.toThrow(Error)
49
95
  expect(consoleError).toHaveBeenCalled()
50
96
  })
@@ -1,11 +1,26 @@
1
- import AWS, { GetQueueAttributesMockImplementation } from 'aws-sdk'
1
+ import { AWS } from '@defra-fish/connectors-lib'
2
2
  import showQueueStatistics from '../show-queue-statistics.js'
3
3
  import testEnv from '../../test-env'
4
4
  import debug from 'debug'
5
+ const { sqs } = AWS.mock.results[0].value
6
+
7
+ jest.mock('@defra-fish/connectors-lib', () => ({
8
+ AWS: jest.fn(() => ({
9
+ sqs: {
10
+ getQueueAttributes: jest.fn(() => ({
11
+ Attributes: {
12
+ ApproximateNumberOfMessages: 0,
13
+ ApproximateNumberOfMessagesNotVisible: 0,
14
+ ApproximateNumberOfMessagesDelayed: 0
15
+ }
16
+ }))
17
+ }
18
+ }))
19
+ }))
5
20
 
6
21
  beforeEach(() => {
7
22
  process.env = Object.assign(process.env, testEnv)
8
- GetQueueAttributesMockImplementation.mockClear()
23
+ sqs.getQueueAttributes.mockClear()
9
24
  })
10
25
 
11
26
  test('shows queue statistics when debug is enabled', async () => {
@@ -15,20 +30,20 @@ test('shows queue statistics when debug is enabled', async () => {
15
30
  await showQueueStatistics('http://0.0.0.0:0000/queue')
16
31
  }
17
32
  await expect(check()).resolves.toBeUndefined()
18
- expect(GetQueueAttributesMockImplementation).toHaveBeenCalledTimes(2)
33
+ expect(sqs.getQueueAttributes).toHaveBeenCalledTimes(2)
19
34
  })
20
35
 
21
36
  test('does not throw errors if the AWS API call fails', async () => {
22
- AWS.__mockGetAttributesThrows()
37
+ sqs.getQueueAttributes.mockRejectedValueOnce(new Error('AWS API call failed'))
23
38
  debug.enable('sqs:queue-stats')
24
39
  const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {})
25
40
  await expect(showQueueStatistics('http://0.0.0.0:0000/queue')).resolves.toBeUndefined()
26
- expect(GetQueueAttributesMockImplementation).toHaveBeenCalledTimes(1)
41
+ expect(sqs.getQueueAttributes).toHaveBeenCalledTimes(1)
27
42
  expect(consoleError).toHaveBeenCalled()
28
43
  })
29
44
 
30
45
  test('does not query queue statistics if debug is not enabled', async () => {
31
46
  debug.disable()
32
47
  await expect(showQueueStatistics('http://0.0.0.0:0000/queue')).resolves.toBeUndefined()
33
- expect(GetQueueAttributesMockImplementation).not.toHaveBeenCalled()
48
+ expect(sqs.getQueueAttributes).not.toHaveBeenCalled()
34
49
  })
@@ -18,7 +18,7 @@ const deleteMessages = async (url, messageSubscriberResults) => {
18
18
  }
19
19
 
20
20
  if (params.Entries.length) {
21
- const results = await sqs.deleteMessageBatch(params).promise()
21
+ const results = await sqs.deleteMessageBatch(params)
22
22
 
23
23
  if (results.Failed.length) {
24
24
  console.error('Failed to delete messages from %s: %o', url, results.Failed)
package/src/read-queue.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict'
2
2
  import db from 'debug'
3
3
  import { AWS } from '@defra-fish/connectors-lib'
4
+
4
5
  const { sqs } = AWS()
5
6
  const debug = db('sqs:read-queue')
6
7
 
@@ -12,7 +13,7 @@ const debug = db('sqs:read-queue')
12
13
  * @param {number} waitTimeMs the amount of time to wait for messages to become available
13
14
  * @returns {Promise<SQS.Message[]|*[]>}
14
15
  */
15
- const readQueue = async (url, visibilityTimeoutMs, waitTimeMs) => {
16
+ export default async (url, visibilityTimeoutMs, waitTimeMs) => {
16
17
  try {
17
18
  const params = {
18
19
  QueueUrl: url,
@@ -22,7 +23,7 @@ const readQueue = async (url, visibilityTimeoutMs, waitTimeMs) => {
22
23
  VisibilityTimeout: visibilityTimeoutMs / 1000,
23
24
  WaitTimeSeconds: waitTimeMs / 1000
24
25
  }
25
- const data = await sqs.receiveMessage(params).promise()
26
+ const data = await sqs.receiveMessage(params)
26
27
  const messages = data.Messages || []
27
28
  debug('Retrieved %d messages from %s', messages.length, url)
28
29
  return messages
@@ -33,12 +34,9 @@ const readQueue = async (url, visibilityTimeoutMs, waitTimeMs) => {
33
34
  */
34
35
  console.error(`Error reading queue: ${url}`, err)
35
36
 
36
- if (!err.statusCode) {
37
+ if (!err.$metadata?.httpStatusCode) {
37
38
  throw err
38
- } else {
39
- return []
40
39
  }
40
+ return []
41
41
  }
42
42
  }
43
-
44
- export default readQueue
@@ -22,7 +22,7 @@ const showQueueStatistics = async url => {
22
22
  AttributeNames: ['ApproximateNumberOfMessages', 'ApproximateNumberOfMessagesNotVisible', 'ApproximateNumberOfMessagesDelayed']
23
23
  }
24
24
 
25
- const { Attributes } = await sqs.getQueueAttributes(params).promise()
25
+ const { Attributes } = await sqs.getQueueAttributes(params)
26
26
  const prt = attr => {
27
27
  const change = Number.parseInt(Attributes[attr]) - Number.parseInt(last[attr])
28
28
  if (change > 0) {
@@ -1,190 +0,0 @@
1
- 'use strict'
2
-
3
- import { v4 as uuidv4 } from 'uuid'
4
- import { configureAwsSdkMock } from '@defra-fish/connectors-lib/src/__mocks__/aws-mock-helper.js'
5
- const AwsSdk = configureAwsSdkMock()
6
-
7
- let result
8
- let exception
9
- let deleteFailures
10
-
11
- AwsSdk.__mockEmptyQueue = () => {
12
- exception = null
13
- result = Object.create({})
14
- }
15
-
16
- AwsSdk.__mockOneMessage = () => {
17
- exception = null
18
- result = Object.create({
19
- ResponseMetadata: {
20
- RequestId: '00000000-0000-0000-0000-000000000000'
21
- },
22
- Messages: [
23
- {
24
- MessageId: '15eb8abc-c7c1-4167-9590-839c8feed6dd',
25
- ReceiptHandle: '15eb8abc-c7c1-4167-9590-839c8feed6dd#9be8971c-f9a9-4bb2-8515-98cdab660e1b',
26
- MD5OfBody: '640ad880b5be372fcb5c5ad8b5eb50af',
27
- Body: '{"id":"7f6e04fe-4cec-4f40-b763-8c66d71062d9"}',
28
- Attributes: {
29
- MessageGroupId: 'service-1'
30
- }
31
- }
32
- ]
33
- })
34
- }
35
-
36
- AwsSdk.__mockNMessages = n => {
37
- exception = null
38
- result = Object.create(
39
- (result = Object.create({
40
- ResponseMetadata: {
41
- RequestId: '00000000-0000-0000-0000-000000000000'
42
- },
43
- Messages: []
44
- }))
45
- )
46
- for (let i = 0; i < n; i++) {
47
- result.Messages.push({
48
- MessageId: uuidv4(),
49
- ReceiptHandle: '15eb8abc-c7c1-4167-9590-839c8feed6dd#9be8971c-f9a9-4bb2-8515-98cdab660e1b',
50
- MD5OfBody: '640ad880b5be372fcb5c5ad8b5eb50af',
51
- Body: `{"id":"${uuidv4()}"}`,
52
- Attributes: {
53
- MessageGroupId: 'service-1'
54
- }
55
- })
56
- }
57
- }
58
-
59
- AwsSdk.__mockFailNoQueue = () => {
60
- exception = new Error('connect ECONNREFUSED 0.0.0.0:9325')
61
- exception.code = 'NetworkingError'
62
- }
63
-
64
- AwsSdk.__mockNotFound = () => {
65
- exception = new Error('Not Found')
66
- exception.code = 404
67
- }
68
-
69
- AwsSdk.__mockAWSError = () => {
70
- result = []
71
- exception = new Error()
72
- exception = Object.assign(exception, {
73
- message: 'ReadCountOutOfRange; see the SQS docs.',
74
- code: 'ReadCountOutOfRange',
75
- time: '2020-03-05T10:27:42.852Z',
76
- statusCode: 400,
77
- retryable: false,
78
- retryDelay: 49.19455461172468
79
- })
80
- }
81
-
82
- AwsSdk.__mockDeleteMessages = () => {
83
- exception = null
84
- result = Object.create({
85
- ResponseMetadata: {
86
- RequestId: '00000000-0000-0000-0000-000000000000'
87
- },
88
- Successful: [
89
- {
90
- Id: '705e5bc6-bd0f-4424-95aa-7caf9a8eaab4'
91
- },
92
- {
93
- Id: '7ae59705-333f-4d38-b5d9-2c71f4f4ecae'
94
- },
95
- {
96
- Id: '23207320-8c75-4a12-960d-b87455ce7826'
97
- }
98
- ],
99
- Failed: []
100
- })
101
- }
102
-
103
- const receiveMessage = () => {
104
- if (exception) {
105
- throw exception
106
- }
107
- return {
108
- promise: () => result
109
- }
110
- }
111
-
112
- AwsSdk.__mockDeleteMessageFailures = () => {
113
- deleteFailures = true
114
- }
115
-
116
- const deleteMessageBatch = params => {
117
- if (exception) {
118
- throw exception
119
- }
120
-
121
- result = () => {
122
- if (deleteFailures) {
123
- return {
124
- ResponseMetadata: {
125
- RequestId: '00000000-0000-0000-0000-000000000000'
126
- },
127
- Successful: [],
128
- Failed: params.Entries.map(p => ({ Id: p.Id }))
129
- }
130
- } else {
131
- return {
132
- ResponseMetadata: {
133
- RequestId: '00000000-0000-0000-0000-000000000000'
134
- },
135
- Successful: params.Entries.map(p => ({ Id: p.Id })),
136
- Failed: []
137
- }
138
- }
139
- }
140
-
141
- return {
142
- promise: () => result()
143
- }
144
- }
145
-
146
- AwsSdk.__mockGetAttributesThrows = () => {
147
- exception = new Error()
148
- }
149
-
150
- export const GetQueueAttributesMockImplementation = jest.fn()
151
-
152
- GetQueueAttributesMockImplementation.mockReturnValueOnce({
153
- promise: () => {
154
- if (exception) {
155
- throw exception
156
- }
157
-
158
- return {
159
- Attributes: {
160
- ApproximateNumberOfMessagesDelayed: 1,
161
- ApproximateNumberOfMessagesNotVisible: 2,
162
- ApproximateNumberOfMessages: 3
163
- }
164
- }
165
- }
166
- }).mockReturnValue({
167
- promise: () => {
168
- if (exception) {
169
- throw exception
170
- }
171
-
172
- return {
173
- Attributes: {
174
- ApproximateNumberOfMessagesDelayed: 0,
175
- ApproximateNumberOfMessagesNotVisible: 0,
176
- ApproximateNumberOfMessages: 0
177
- }
178
- }
179
- }
180
- })
181
-
182
- AwsSdk.SQS.mockImplementation(() => {
183
- return {
184
- receiveMessage: receiveMessage,
185
- deleteMessageBatch: deleteMessageBatch,
186
- getQueueAttributes: GetQueueAttributesMockImplementation
187
- }
188
- })
189
-
190
- export default AwsSdk