ftmocks-utils 1.2.5 → 1.3.1

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,6 +1,6 @@
1
1
  {
2
2
  "name": "ftmocks-utils",
3
- "version": "1.2.5",
3
+ "version": "1.3.1",
4
4
  "description": "Util functions for FtMocks",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -1,21 +1,31 @@
1
1
  const path = require("path");
2
2
  const fs = require("fs");
3
+ const { FtJSON } = require("./json-utils");
3
4
 
4
5
  const charDifference = (str1, str2) => {
5
- let count1 = {},
6
- count2 = {};
6
+ if (str1 && str2) {
7
+ let count1 = {};
8
+ let count2 = {};
7
9
 
8
- for (let ch of str1) count1[ch] = (count1[ch] || 0) + 1;
9
- for (let ch of str2) count2[ch] = (count2[ch] || 0) + 1;
10
+ for (let ch of str1) count1[ch] = (count1[ch] || 0) + 1;
11
+ for (let ch of str2) count2[ch] = (count2[ch] || 0) + 1;
10
12
 
11
- let diff = 0;
12
- let chars = new Set([...Object.keys(count1), ...Object.keys(count2)]);
13
+ let diff = 0;
14
+ let chars = new Set([...Object.keys(count1), ...Object.keys(count2)]);
13
15
 
14
- for (let ch of chars) {
15
- diff += Math.abs((count1[ch] || 0) - (count2[ch] || 0));
16
- }
16
+ for (let ch of chars) {
17
+ diff += Math.abs((count1[ch] || 0) - (count2[ch] || 0));
18
+ }
17
19
 
18
- return diff;
20
+ return diff;
21
+ } else {
22
+ if (!str1 && str2) {
23
+ return str2.length;
24
+ } else if (str1 && !str2) {
25
+ return str1.length;
26
+ }
27
+ return 0;
28
+ }
19
29
  };
20
30
 
21
31
  const nameToFolder = (name) => {
@@ -52,37 +62,6 @@ const capitalizeHeaders = (headers) => {
52
62
  );
53
63
  };
54
64
 
55
- const areJsonEqual = (jsonObj1, jsonObj2) => {
56
- // Check if both are objects and not null
57
- if (
58
- typeof jsonObj1 === "object" &&
59
- jsonObj1 !== null &&
60
- typeof jsonObj2 === "object" &&
61
- jsonObj2 !== null
62
- ) {
63
- // Get the keys of both objects
64
- const keys1 = Object.keys(jsonObj1);
65
- const keys2 = Object.keys(jsonObj2);
66
-
67
- // Check if the number of keys is different
68
- if (keys1.length !== keys2.length) {
69
- return false;
70
- }
71
-
72
- // Recursively check each key-value pair
73
- for (let key of keys1) {
74
- if (!keys2.includes(key) || !areJsonEqual(jsonObj1[key], jsonObj2[key])) {
75
- return false;
76
- }
77
- }
78
-
79
- return true;
80
- } else {
81
- // For non-object types, use strict equality comparison
82
- return jsonObj1 === jsonObj2;
83
- }
84
- };
85
-
86
65
  const clearNulls = (postData) => {
87
66
  Object.keys(postData || {}).forEach((key) => {
88
67
  if (postData[key] === null) {
@@ -162,7 +141,6 @@ module.exports = {
162
141
  getFallbackDir,
163
142
  capitalizeHeader,
164
143
  capitalizeHeaders,
165
- areJsonEqual,
166
144
  clearNulls,
167
145
  processURL,
168
146
  getHeaders,
package/src/index.js CHANGED
@@ -6,16 +6,20 @@ const {
6
6
  nameToFolder,
7
7
  getMockDir,
8
8
  getFallbackDir,
9
- areJsonEqual,
10
9
  clearNulls,
11
10
  processURL,
12
11
  getHeaders,
13
12
  countFilesInDirectory,
14
13
  getTestByName,
15
14
  } = require("./common-utils");
15
+ const { FtJSON } = require("./json-utils");
16
16
 
17
17
  const getDefaultMockDataFromConfig = (testConfig) => {
18
- const defaultPath = path.join(getMockDir(testConfig), "default.json");
18
+ const defaultPath = path.join(
19
+ getMockDir(testConfig),
20
+ "defaultMocks",
21
+ "_mock_list.json"
22
+ );
19
23
 
20
24
  try {
21
25
  const defaultData = fs.readFileSync(defaultPath, "utf8");
@@ -38,7 +42,7 @@ const getDefaultMockDataFromConfig = (testConfig) => {
38
42
  });
39
43
  return parsedData;
40
44
  } catch (error) {
41
- console.error(`Error reading or parsing default.json:`, error);
45
+ console.error(`Error reading or parsing default mocks:`, error);
42
46
  return [];
43
47
  }
44
48
  };
@@ -99,11 +103,11 @@ const isSameRequest = (req1, req2) => {
99
103
  (!req1.postData && req2.postData) ||
100
104
  (req1.postData && !req2.postData)
101
105
  ) {
102
- matched = areJsonEqual(req1.postData || {}, req2.postData || {});
106
+ matched = FtJSON.areJsonEqual(req1.postData || {}, req2.postData || {});
103
107
  } else if (
104
108
  req1.postData &&
105
109
  req2.postData &&
106
- !areJsonEqual(req1.postData, req2.postData)
110
+ !FtJSON.areJsonEqual(req1.postData, req2.postData)
107
111
  ) {
108
112
  matched = false;
109
113
  }
@@ -127,8 +131,8 @@ const getSameRequestRank = (req1, req2) => {
127
131
  rank = rank + queryDiff;
128
132
  // Compare post data
129
133
  const charDiff = charDifference(
130
- JSON.stringify(req1.postData || {}),
131
- JSON.stringify(req2.postData || {})
134
+ FtJSON.stringify(req1.postData || {}),
135
+ FtJSON.stringify(req2.postData || {})
132
136
  );
133
137
  rank = rank + charDiff;
134
138
  }
@@ -142,7 +146,7 @@ function compareMockToRequest(mock, req) {
142
146
  );
143
147
  const reqURL = processURL(req.originalUrl, mock.fileContent.ignoreParams);
144
148
  const postData = mock.fileContent.request?.postData?.text
145
- ? JSON.parse(mock.fileContent.request?.postData?.text)
149
+ ? FtJSON.parse(mock.fileContent.request?.postData?.text)
146
150
  : mock.fileContent.request?.postData;
147
151
  return isSameRequest(
148
152
  { url: mockURL, method: mock.fileContent.method, postData },
@@ -162,14 +166,14 @@ function compareMockToFetchRequest(mock, fetchReq) {
162
166
  );
163
167
  const reqURL = processURL(fetchReq.url, mock.fileContent.ignoreParams);
164
168
  const postData = mock.fileContent.request?.postData?.text
165
- ? JSON.parse(mock.fileContent.request?.postData?.text)
169
+ ? FtJSON.parse(mock.fileContent.request?.postData?.text)
166
170
  : mock.fileContent.request?.postData;
167
171
  return isSameRequest(
168
172
  { url: mockURL, method: mock.fileContent.method, postData },
169
173
  {
170
174
  method: fetchReq.options.method || "GET",
171
175
  postData: fetchReq.options.body?.length
172
- ? JSON.parse(fetchReq.options.body)
176
+ ? FtJSON.parse(fetchReq.options.body)
173
177
  : fetchReq.options.body,
174
178
  url: reqURL,
175
179
  }
@@ -189,14 +193,14 @@ function getCompareRankMockToFetchRequest(mock, fetchReq) {
189
193
  );
190
194
  const reqURL = processURL(fetchReq.url, mock.fileContent.ignoreParams);
191
195
  const postData = mock.fileContent.request?.postData?.text
192
- ? JSON.parse(mock.fileContent.request?.postData?.text)
196
+ ? FtJSON.parse(mock.fileContent.request?.postData?.text)
193
197
  : mock.fileContent.request?.postData;
194
198
  return getSameRequestRank(
195
199
  { url: mockURL, method: mock.fileContent.method, postData },
196
200
  {
197
201
  method: fetchReq.options.method || "GET",
198
202
  postData: fetchReq.options.body?.length
199
- ? JSON.parse(fetchReq.options.body)
203
+ ? FtJSON.parse(fetchReq.options.body)
200
204
  : fetchReq.options.body,
201
205
  url: reqURL,
202
206
  }
@@ -272,11 +276,18 @@ function getMatchingMockData({
272
276
  }
273
277
  // updating stats to mock file
274
278
  if (foundMock) {
275
- const mockFilePath = path.join(
279
+ let mockFilePath = path.join(
276
280
  getMockDir(testConfig),
277
281
  `test_${nameToFolder(testName)}`,
278
282
  `mock_${foundMock.id}.json`
279
283
  );
284
+ if (!fs.existsSync(mockFilePath)) {
285
+ mockFilePath = path.join(
286
+ getMockDir(testConfig),
287
+ "defaultMocks",
288
+ `mock_${foundMock.id}.json`
289
+ );
290
+ }
280
291
  foundMock.fileContent.served = true;
281
292
  fs.writeFileSync(
282
293
  mockFilePath,
@@ -351,12 +362,20 @@ async function initiatePlaywrightRoutes(
351
362
  };
352
363
 
353
364
  if (file) {
354
- const filePath = path.join(
365
+ let filePath = path.join(
355
366
  getMockDir(ftmocksConifg),
356
367
  `test_${nameToFolder(testName)}`,
357
368
  "_files",
358
369
  file
359
370
  );
371
+ if (!fs.existsSync(filePath)) {
372
+ filePath = path.join(
373
+ getMockDir(ftmocksConifg),
374
+ "defaultMocks",
375
+ "_files",
376
+ file
377
+ );
378
+ }
360
379
  if (fs.existsSync(filePath) && fs.lstatSync(filePath).isFile()) {
361
380
  const fileContent = fs.readFileSync(filePath);
362
381
  json.body = fileContent;
@@ -511,7 +530,7 @@ async function initiateJestFetch(jest, ftmocksConifg, testName) {
511
530
  return Promise.resolve({
512
531
  status,
513
532
  headers: new Map(Object.entries(headers)),
514
- json: () => Promise.resolve(JSON.parse(content)),
533
+ json: () => Promise.resolve(FtJSON.parse(content)),
515
534
  });
516
535
  });
517
536
 
@@ -748,17 +767,17 @@ const isSameResponse = (req1, req2) => {
748
767
  (!req1.response.content && req2.response.content) ||
749
768
  (req1.response.content && !req2.response.content)
750
769
  ) {
751
- matched = areJsonEqual(
752
- JSON.parse(req1.response.content) || {},
753
- JSON.parse(req2.response.content) || {}
770
+ matched = FtJSON.areJsonEqual(
771
+ FtJSON.parse(req1.response.content) || {},
772
+ FtJSON.parse(req2.response.content) || {}
754
773
  );
755
774
  // console.log('not matched at post Data 0', req1.postData, req2.postData);
756
775
  } else if (
757
776
  req1.response.content &&
758
777
  req2.response.content &&
759
- !areJsonEqual(
760
- JSON.parse(req1.response.content) || {},
761
- JSON.parse(req2.response.content) || {}
778
+ !FtJSON.areJsonEqual(
779
+ FtJSON.parse(req1.response.content) || {},
780
+ FtJSON.parse(req2.response.content) || {}
762
781
  )
763
782
  ) {
764
783
  matched = false;
@@ -0,0 +1,55 @@
1
+ class FtJSON {
2
+ static parse(text, reviver, reference) {
3
+ try {
4
+ return JSON.parse(text, reviver);
5
+ } catch (error) {
6
+ console.error("FtJSON parse error:", error, reference);
7
+ return text;
8
+ }
9
+ }
10
+
11
+ static stringify(value, replacer, space, reference) {
12
+ try {
13
+ return JSON.stringify(value, replacer, space);
14
+ } catch (error) {
15
+ console.error("FtJSON stringify error:", error, reference);
16
+ return value;
17
+ }
18
+ }
19
+
20
+ static areJsonEqual(jsonObj1, jsonObj2) {
21
+ // Check if both are objects and not null
22
+ if (
23
+ typeof jsonObj1 === "object" &&
24
+ jsonObj1 !== null &&
25
+ typeof jsonObj2 === "object" &&
26
+ jsonObj2 !== null
27
+ ) {
28
+ // Get the keys of both objects
29
+ const keys1 = Object.keys(jsonObj1);
30
+ const keys2 = Object.keys(jsonObj2);
31
+
32
+ // Check if the number of keys is different
33
+ if (keys1.length !== keys2.length) {
34
+ return false;
35
+ }
36
+
37
+ // Recursively check each key-value pair
38
+ for (let key of keys1) {
39
+ if (
40
+ !keys2.includes(key) ||
41
+ !FtJSON.areJsonEqual(jsonObj1[key], jsonObj2[key])
42
+ ) {
43
+ return false;
44
+ }
45
+ }
46
+
47
+ return true;
48
+ } else {
49
+ // For non-object types, use strict equality comparison
50
+ return jsonObj1 === jsonObj2;
51
+ }
52
+ }
53
+ }
54
+
55
+ module.exports = { FtJSON };