node-tdd 4.0.5 → 4.1.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.
@@ -0,0 +1,106 @@
1
+ // This code logic is used to migrate legacy AWS SQS xml to json
2
+ import xml2js from 'xml2js';
3
+ import objectScan from 'object-scan';
4
+
5
+ const tryParseXML = (body) => {
6
+ let parsed = body;
7
+ try {
8
+ xml2js.parseString(body, (err, result) => {
9
+ parsed = JSON.parse(JSON.stringify(result));
10
+ });
11
+ } catch (e) {
12
+ return null;
13
+ }
14
+ return parsed;
15
+ };
16
+
17
+ export default ({ responseBody, header }) => {
18
+ const responseXml = tryParseXML(responseBody);
19
+ if (responseXml !== null) {
20
+ if (header === 'AmazonSQS.ListQueueTags') {
21
+ const scanner = objectScan(['ListQueueTagsResponse.ListQueueTagsResult[0].Tag[*]'], {
22
+ rtn: ({ value }) => [value.Key, value.Value[0]],
23
+ afterFn: ({ result }) => Object.fromEntries(result)
24
+ });
25
+ const Tags = scanner(responseXml);
26
+ return { Tags };
27
+ }
28
+ if (header === 'AmazonSQS.GetQueueAttributes') {
29
+ const scanner = objectScan(['GetQueueAttributesResponse.GetQueueAttributesResult[0].Attribute[*]'], {
30
+ rtn: ({ value }) => [value.Name[0], value.Value[0]],
31
+ afterFn: ({ result }) => Object.fromEntries(result)
32
+ });
33
+ const Attributes = scanner(responseXml);
34
+ return { Attributes };
35
+ }
36
+ if (header === 'AmazonSQS.GetQueueUrl') {
37
+ if (responseXml?.ErrorResponse?.Error?.[0]?.Code?.[0] === 'AWS.SimpleQueueService.NonExistentQueue') {
38
+ return {
39
+ __type: 'com.amazonaws.sqs#QueueDoesNotExist',
40
+ message: 'The specified queue does not exist.'
41
+ };
42
+ }
43
+ const QueueUrl = responseXml?.GetQueueUrlResponse?.GetQueueUrlResult?.[0]?.QueueUrl?.[0];
44
+ return { QueueUrl };
45
+ }
46
+ if (header === 'AmazonSQS.CreateQueue') {
47
+ if (responseXml?.ErrorResponse?.Error?.[0]?.Code?.[0] === 'QueueAlreadyExists') {
48
+ return {
49
+ __type: 'com.amazonaws.sqs#QueueNameExists',
50
+ message: 'The specified queue name does exist.'
51
+ };
52
+ }
53
+ const QueueUrl = responseXml?.CreateQueueResponse?.CreateQueueResult?.[0]?.QueueUrl?.[0];
54
+ return { QueueUrl };
55
+ }
56
+ if (header === 'AmazonSQS.ListQueues') {
57
+ const scannerQueueUrls = objectScan(
58
+ ['ListQueuesResponse.ListQueuesResult[0].QueueUrl[*]'],
59
+ { rtn: 'value', reverse: false }
60
+ );
61
+ const scannerNextToken = objectScan(
62
+ ['ListQueuesResponse.ListQueuesResult[0].NextToken[0]'],
63
+ { rtn: 'value', reverse: false, abort: true }
64
+ );
65
+ return {
66
+ QueueUrls: scannerQueueUrls(responseXml),
67
+ NextToken: scannerNextToken(responseXml)
68
+ };
69
+ }
70
+ if (header === 'AmazonSQS.TagQueue') {
71
+ return {};
72
+ }
73
+ if (header === 'AmazonSQS.SetQueueAttributes') {
74
+ return {};
75
+ }
76
+ if (header === 'AmazonSQS.SendMessageBatch') {
77
+ const scannerSuccessful = objectScan(
78
+ ['SendMessageBatchResponse.SendMessageBatchResult[0].SendMessageBatchResultEntry[*]'],
79
+ {
80
+ rtn: ({ value }) => ({
81
+ Id: value.Id[0],
82
+ MessageId: value.MessageId[0],
83
+ MD5OfMessageBody: value.MD5OfMessageBody[0]
84
+ }),
85
+ reverse: false
86
+ }
87
+ );
88
+ const scannerFailed = objectScan(
89
+ ['SendMessageBatchResponse.SendMessageBatchResult[0].BatchResultErrorEntry[*]'],
90
+ {
91
+ rtn: ({ value }) => ({
92
+ Id: value.Id[0],
93
+ SenderFault: value.SenderFault[0],
94
+ Code: value.Code[0]
95
+ }),
96
+ reverse: false
97
+ }
98
+ );
99
+ return {
100
+ Successful: scannerSuccessful(responseXml),
101
+ Failed: scannerFailed(responseXml)
102
+ };
103
+ }
104
+ }
105
+ return responseBody;
106
+ };
@@ -0,0 +1,30 @@
1
+ import crypto from 'crypto';
2
+ import { tryParseJson } from './util.js';
3
+ import migration from './heal-sqs/migration.js';
4
+
5
+ export default (requestBody, responseBody, scope, req) => {
6
+ if (scope?.basePath !== 'https://sqs.us-west-2.amazonaws.com:443') {
7
+ return responseBody;
8
+ }
9
+
10
+ const header = req?.options?.headers?.['x-amz-target'];
11
+
12
+ if (typeof responseBody === 'string' && responseBody.startsWith('<?xml')) {
13
+ return migration({ responseBody, header });
14
+ }
15
+
16
+ const requestJson = tryParseJson(requestBody);
17
+ const responseJson = tryParseJson(responseBody);
18
+
19
+ if (header === 'AmazonSQS.SendMessageBatch') {
20
+ return {
21
+ Successful: requestJson.Entries.map(({ Id, MessageBody }, idx) => ({
22
+ Id,
23
+ MessageId: responseJson?.Successful?.[idx]?.MessageId || crypto.randomUUID(),
24
+ MD5OfMessageBody: crypto.createHash('md5').update(MessageBody).digest('hex')
25
+ }))
26
+ };
27
+ }
28
+
29
+ return responseBody;
30
+ };
@@ -11,7 +11,7 @@ import nockCommon from 'nock/lib/common.js';
11
11
  import compareUrls from '../util/compare-urls.js';
12
12
  import nockListener from './request-recorder/nock-listener.js';
13
13
  import nockMock from './request-recorder/nock-mock.js';
14
- import healSqsSendMessageBatch from './request-recorder/heal-sqs-send-message-batch.js';
14
+ import healSqs from './request-recorder/heal-sqs.js';
15
15
  import applyModifiers from './request-recorder/apply-modifiers.js';
16
16
  import requestInjector from './request-recorder/request-injector.js';
17
17
 
@@ -223,7 +223,7 @@ export default (opts) => {
223
223
 
224
224
  if (anyFlagPresent(['magic', 'response'])) {
225
225
  const responseBody = tryParseJson([
226
- healSqsSendMessageBatch
226
+ healSqs
227
227
  ].reduce(
228
228
  (respBody, fn) => fn(requestBodyString, respBody, scope, req),
229
229
  interceptor.body
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "node-tdd",
3
3
  "type": "module",
4
- "version": "4.0.5",
4
+ "version": "4.1.0",
5
5
  "description": "Drop in extension for mocha to abstract commonly used test setups",
6
6
  "main": "lib/index.js",
7
7
  "scripts": {
@@ -86,6 +86,7 @@
86
86
  "object-scan": "19.0.5",
87
87
  "smart-fs": "4.0.1",
88
88
  "timekeeper": "2.3.1",
89
- "tmp": "0.2.1"
89
+ "tmp": "0.2.1",
90
+ "xml2js": "0.6.2"
90
91
  }
91
92
  }
@@ -1,21 +0,0 @@
1
- import crypto from 'crypto';
2
- import { tryParseJson } from './util.js';
3
-
4
- export default (requestBody, responseBody, scope, req) => {
5
- if (
6
- scope?.basePath !== 'https://sqs.us-west-2.amazonaws.com:443'
7
- || req?.options?.headers?.['x-amz-target'] !== 'AmazonSQS.SendMessageBatch'
8
- ) {
9
- return responseBody;
10
- }
11
-
12
- const requestJson = tryParseJson(requestBody);
13
- const responseJson = tryParseJson(responseBody);
14
- return {
15
- Successful: requestJson.Entries.map(({ Id, MessageBody }, idx) => ({
16
- Id,
17
- MessageId: responseJson?.Successful?.[idx]?.MessageId || crypto.randomUUID(),
18
- MD5OfMessageBody: crypto.createHash('md5').update(MessageBody).digest('hex')
19
- }))
20
- };
21
- };