ftmocks-utils 1.1.2 → 1.1.4

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +60 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ftmocks-utils",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "Util functions for FtMocks",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
package/src/index.js CHANGED
@@ -14,6 +14,26 @@ const getMockDir = config => {
14
14
  return config.MOCK_DIR;
15
15
  }
16
16
 
17
+ const getFallbackDir = config => {
18
+ if(config.FALLBACK_DIR && !path.isAbsolute(config.FALLBACK_DIR)) {
19
+ return path.resolve( process.cwd(), config.FALLBACK_DIR);
20
+ }
21
+ return config.FALLBACK_DIR;
22
+ }
23
+
24
+ const capitalizeHeader = header => {
25
+ return header
26
+ .split('-')
27
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
28
+ .join('-');
29
+ }
30
+
31
+ const capitalizeHeaders = headers => {
32
+ return Object.fromEntries(
33
+ Object.entries(headers).map(([key, value]) => [capitalizeHeader(key), value])
34
+ );
35
+ };
36
+
17
37
  const areJsonEqual = (jsonObj1, jsonObj2) => {
18
38
  // Check if both are objects and not null
19
39
  if (typeof jsonObj1 === 'object' && jsonObj1 !== null &&
@@ -198,12 +218,12 @@ async function resetAllMockStats({testMockData, testConfig, testName}) {
198
218
  }
199
219
  }
200
220
 
201
- async function initiatePlaywrightRoutes (page, ftmocksConifg, testName, path = '**/*') {
221
+ async function initiatePlaywrightRoutes (page, ftmocksConifg, testName, mockPath = '**/*', excludeMockPath = null) {
202
222
  const testMockData = testName ? loadMockDataFromConfig(ftmocksConifg, testName) : [];
203
223
  resetAllMockStats({testMockData, testConfig: ftmocksConifg, testName});
204
224
  const defaultMockData = getDefaultMockDataFromConfig(ftmocksConifg);
205
225
  console.debug('calling initiatePlaywrightRoutes fetch');
206
- await page.route(path, async (route, request) => {
226
+ await page.route(mockPath, async (route, request) => {
207
227
  const url = request.url();
208
228
  const options = {
209
229
  options: {
@@ -212,21 +232,53 @@ async function initiatePlaywrightRoutes (page, ftmocksConifg, testName, path = '
212
232
  body: request.postData(),
213
233
  }
214
234
  }
235
+ if (excludeMockPath && new RegExp(excludeMockPath).test(url)) {
236
+ await route.fallback();
237
+ return;
238
+ }
215
239
  console.debug('got fetch request', request.method(), request.url(), request.postData());
216
240
  let mockData = getMatchingMockData({testMockData, defaultMockData, url, options, testConfig: ftmocksConifg, testName});
217
241
  if (mockData) {
218
242
  console.debug('mocked', url, options);
219
243
  const { content, headers, status } = mockData.response;
244
+
220
245
  const json = {
221
246
  status,
222
- headers: new Map(Object.entries(headers)),
247
+ headers: new Map(Object.entries(capitalizeHeaders(headers))),
223
248
  body: content,
224
249
  };
225
250
 
226
251
  await route.fulfill(json);
227
252
  } else {
228
253
  console.debug('missing mock data', url, options);
229
- await route.fallback();
254
+ const fallbackDir = getFallbackDir(ftmocksConifg);
255
+ if(!fallbackDir) {
256
+ await route.fallback();
257
+ return;
258
+ }
259
+ const urlObj = new URL(route.request().url());
260
+ const filePath = path.join(fallbackDir, urlObj.pathname === '/' || urlObj.pathname === '' ? (ftmocksConifg.FALLBACK_DIR_INDEX_FILE || 'index.html') : urlObj.pathname);
261
+ console.debug('serving file ', filePath);
262
+ if (fs.existsSync(filePath) && fs.lstatSync(filePath).isFile()) {
263
+ const fileContent = fs.readFileSync(filePath);
264
+ const ext = path.extname(filePath);
265
+ const contentType = {
266
+ '.html': 'text/html',
267
+ '.css': 'text/css',
268
+ '.js': 'application/javascript',
269
+ '.json': 'application/json',
270
+ '.png': 'image/png',
271
+ '.jpg': 'image/jpeg',
272
+ }[ext] || 'application/octet-stream';
273
+
274
+ console.debug('serving file', filePath);
275
+ await route.fulfill({
276
+ body: fileContent,
277
+ headers: { 'Content-Type': contentType },
278
+ });
279
+ } else {
280
+ await route.fallback();
281
+ }
230
282
  }
231
283
  });
232
284
  }
@@ -245,7 +297,7 @@ async function initiateJestFetch (jest, ftmocksConifg, testName) {
245
297
  console.debug('missing mock data', url, options);
246
298
  return Promise.resolve({
247
299
  status: 404,
248
- headers: new Map([['content-type', 'application/json']]),
300
+ headers: new Map([['Content-Type', 'application/json']]),
249
301
  json: () => Promise.resolve({ error: 'Mock data not found' }),
250
302
  });
251
303
  }
@@ -254,7 +306,7 @@ async function initiateJestFetch (jest, ftmocksConifg, testName) {
254
306
 
255
307
  return Promise.resolve({
256
308
  status,
257
- headers: new Map(Object.entries(headers)),
309
+ headers: new Map(Object.entries(capitalizeHeaders(headers))),
258
310
  json: () => Promise.resolve(JSON.parse(content)),
259
311
  });
260
312
  });
@@ -275,6 +327,7 @@ async function initiateJestFetch (jest, ftmocksConifg, testName) {
275
327
  status: 0,
276
328
  response: null,
277
329
  responseText: '',
330
+ headers: new Map(Object.entries(capitalizeHeaders(headers))),
278
331
  onreadystatechange: null,
279
332
  onload: null,
280
333
  onerror: null,
@@ -297,7 +350,7 @@ async function initiateJestFetch (jest, ftmocksConifg, testName) {
297
350
  xhrMock.status = status;
298
351
  xhrMock.responseText = content;
299
352
  xhrMock.response = content;
300
- xhrMock.headers = headers;
353
+ xhrMock.headers = new Map(Object.entries(capitalizeHeaders(headers)));
301
354
 
302
355
  if (xhrMock.onreadystatechange) {
303
356
  xhrMock.onreadystatechange();