ti2 1.0.59 → 1.0.60

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.
@@ -1,6 +1,9 @@
1
1
  /* globals beforeAll describe it expect */
2
-
2
+ const axios = require('axios');
3
+ const MockAdapter = require('axios-mock-adapter');
3
4
  const chance = require('chance').Chance();
5
+
6
+
4
7
  const testUtils = require('../../test/utils');
5
8
 
6
9
  const { env: { adminKey } } = process;
@@ -26,6 +29,7 @@ describe('allotment', () => {
26
29
  let doApiGet;
27
30
  let doApiPost;
28
31
  let plugins;
32
+ let userToken;
29
33
  beforeAll(async () => {
30
34
  ({
31
35
  doApiDelete,
@@ -35,10 +39,8 @@ describe('allotment', () => {
35
39
  } = await testUtils({
36
40
  plugins: [appKey],
37
41
  }));
38
- });
39
42
 
40
- let userToken;
41
- it('drop any existing user integration', async () => {
43
+ // drop any existing user integrations
42
44
  try {
43
45
  await doApiDelete({
44
46
  url: `/${appKey}/${userId}`,
@@ -48,16 +50,16 @@ describe('allotment', () => {
48
50
  } catch (err) {
49
51
  // console.debug(err);
50
52
  }
51
- });
52
- it('create the user', async () => {
53
+
54
+ // create the user
53
55
  ({ value: userToken } = await doApiPost({
54
56
  url: '/user',
55
57
  token: adminKey,
56
58
  payload: { userId },
57
59
  }));
58
60
  expect(userToken).toBeTruthy();
59
- });
60
- it('create the App+User setup', async () => {
61
+
62
+ // create the App+User setup
61
63
  const { userAppKeys } = await doApiGet({
62
64
  url: `/user/${userId}/apps`,
63
65
  token: userToken,
@@ -103,4 +105,32 @@ describe('allotment', () => {
103
105
  expect(call.payload).toEqual(payload);
104
106
  expect(call.token).toEqual(token);
105
107
  });
108
+ it('should be able to receive an axios error', async () => {
109
+ let urlParamsError = new URLSearchParams({
110
+ ...payload,
111
+ keyPath: 'errorAxios',
112
+ }).toString();
113
+ const returnValue = await doApiGet({
114
+ url: `/allotment/${appKey}/${newIntegration.tokenHint}/${userId}?${urlParamsError}`,
115
+ token: userToken,
116
+ expectStatusCode: 500,
117
+ });
118
+ expect(returnValue.allotments).toBeFalsy();
119
+ expect(returnValue.message).toBe('ECONNREFUSED');
120
+ });
121
+ it('should be able to receive an error from a regular response', async () => {
122
+ const mock = new MockAdapter(axios);
123
+ mock.onGet('http://www.example.com').reply(200, { error: 'something went wrong' });
124
+ let urlParamsError = new URLSearchParams({
125
+ ...payload,
126
+ keyPath: 'errorGeneral',
127
+ }).toString();
128
+ const returnValue = await doApiGet({
129
+ url: `/allotment/${appKey}/${newIntegration.tokenHint}/${userId}?${urlParamsError}`,
130
+ token: userToken,
131
+ expectStatusCode: 500,
132
+ });
133
+ expect(returnValue.allotments).toBeFalsy();
134
+ expect(returnValue.message).toBe('something went wrong');
135
+ });
106
136
  });
package/index.js CHANGED
@@ -40,6 +40,7 @@ const bookingsController = require('./controllers/bookings');
40
40
  const allotmentController = require('./controllers/allotment');
41
41
  const { Integration } = require('./models');
42
42
  const cache = require('./cache');
43
+ const getErrorMessage = require('./lib/get-error-message.js');
43
44
 
44
45
  // src : https://github.com/ramda/ramda/issues/3137#issuecomment-1016012904
45
46
  const rebuild = fn => obj =>
@@ -217,36 +218,20 @@ module.exports = async ({
217
218
  });
218
219
  axiosPlugin.interceptors.response.use(response => {
219
220
  ti2Events.emit(`${pluginName}.axios.response`, { ...axiosSafeResponse(response), userId });
220
- if (errorPathsAxiosAny.length > 0) {
221
- const pathMatch = errorPathsAxiosAny.find(errorPath => R.path(errorPath, response));
222
- if (pathMatch) {
223
- const errMsg = R.path(pathMatch, response);
224
- if (process.env.debug) console.error(`error in ${pluginName}`, errMsg);
225
- if (ti2Events.events) {
226
- ti2Events.events.emit(`${pluginName}.axios.error`, {
227
- response: axiosSafeResponse(response),
228
- err: errMsg,
229
- });
230
- }
231
- throw new Eror(errMsg);
221
+ const errMsg = getErrorMessage({ err: response, handlers: errorPathsAxiosAny, force: false });
222
+ if (errMsg) {
223
+ if (process.env.debug) console.error(`error in ${pluginName}`, errMsg);
224
+ if (ti2Events.events) {
225
+ ti2Events.events.emit(`${pluginName}.axios.error`, {
226
+ response: axiosSafeResponse(response),
227
+ err: errMsg,
228
+ });
232
229
  }
230
+ throw new Error(errMsg);
233
231
  }
234
232
  return response;
235
- });
236
- if (process.env.debug) {
237
- curlirize(axiosPlugin);
238
- }
239
- req.axios = async (...args) => axiosPlugin(...args).catch(err => {
240
- const errMsg = (() => {
241
- const defaultErr = R.omit(['config'], err.toJSON()); // default error
242
- if (errorPathsAxiosErrors.length > 0) {
243
- const pathMatch = errorPathsAxiosErrors.find(errorPath => R.path(errorPath, err));
244
- if (pathMatch) {
245
- return R.path(pathMatch, err);
246
- }
247
- }
248
- return defaultErr;
249
- })();
233
+ }, err => {
234
+ const errMsg = getErrorMessage({ err, handlers: errorPathsAxiosErrors });
250
235
  if (process.env.debug) console.error(`error in ${pluginName}`, args[0], errMsg);
251
236
  if (ti2Events.events) {
252
237
  ti2Events.events.emit(`${pluginName}.axios.error`, {
@@ -254,9 +239,12 @@ module.exports = async ({
254
239
  err: errMsg,
255
240
  });
256
241
  }
257
- throw new Error(errMsg);
242
+ return Promise.reject(errMsg);
258
243
  });
259
-
244
+ if (process.env.debug) {
245
+ curlirize(axiosPlugin);
246
+ }
247
+ req.axios = axiosPlugin;
260
248
  next();
261
249
  });
262
250
 
@@ -309,7 +297,7 @@ module.exports = async ({
309
297
  return next(err);
310
298
  }
311
299
  if (process.env.CONSOLE_ERRORS || process.env.JEST_WORKER_ID) {
312
- console.error(R.path(['response', 'data'], err));
300
+ console.error(R.pathOr(err, ['response', 'data'], err));
313
301
  }
314
302
  return res.status((() => {
315
303
  if (!isNumber(err.status)) return 500;
@@ -0,0 +1,21 @@
1
+ const R = require('ramda');
2
+
3
+ const getErrorMessage = ({ err, handlers = [], force = true }) => {
4
+ for (const handler of handlers) {
5
+ let errorMessage;
6
+ if (Array.isArray(handler)) {
7
+ errorMessage = R.path(handler, err);
8
+ } else if (typeof handler === 'function') {
9
+ errorMessage = handler(err);
10
+ }
11
+ if (errorMessage) {
12
+ return errorMessage;
13
+ }
14
+ }
15
+ if (force) return R.pathOr(
16
+ err,
17
+ ['message'],
18
+ err
19
+ );
20
+ }
21
+ module.exports = getErrorMessage;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ti2",
3
- "version": "1.0.59",
3
+ "version": "1.0.60",
4
4
  "description": "Tourist Industry Exchange (TI2)",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -52,6 +52,7 @@
52
52
  },
53
53
  "devDependencies": {
54
54
  "@salvador/minami": "^1.2.3",
55
+ "axios-mock-adapter": "^1.21.4",
55
56
  "chance": "^1.1.8",
56
57
  "eslint": "^8.7.0",
57
58
  "eslint-config-airbnb-base": "^15.0.0",
package/test/plugin.js CHANGED
@@ -1,5 +1,6 @@
1
1
  /* global jest, expect */
2
2
  /* eslint class-methods-use-this: "off", max-len: "off" */
3
+ const R = require('ramda');
3
4
 
4
5
  const jestPlugin = (() => {
5
6
  if (typeof jest === 'undefined') {
@@ -53,7 +54,19 @@ class Plugin {
53
54
  });
54
55
  this.searchQuote = jestPlugin.fn(() => ({ quote: [{ id: chance.guid() }] }));
55
56
  this.createBooking = jestPlugin.fn(() => {});
56
- this.queryAllotment = jestPlugin.fn(() => ({ allotments: [] }));
57
+ this.queryAllotment = jestPlugin.fn(async (args) => {
58
+ const {
59
+ axios,
60
+ payload,
61
+ } = args;
62
+ if (payload.keyPath === 'errorAxios') {
63
+ await axios.get('http://localhost:1235/');
64
+ }
65
+ if (payload.keyPath === 'errorGeneral') {
66
+ await axios.get('http://www.example.com');
67
+ }
68
+ return { allotments: [] }
69
+ });
57
70
  this.tokenTemplate = jestPlugin.fn(() => ({
58
71
  apiKey: {
59
72
  type: 'text',
@@ -61,6 +74,14 @@ class Plugin {
61
74
  description: 'Api Key',
62
75
  },
63
76
  }));
77
+ this.errorPathsAxiosErrors = jestPlugin.fn(() => ([
78
+ ['code'],
79
+ ]));
80
+ this.errorPathsAxiosAny = jestPlugin.fn(() => ([
81
+ err => {
82
+ return R.path(['data', 'error'], err);
83
+ }
84
+ ]));
64
85
 
65
86
  /**
66
87
  * Background and schedule Jos
@@ -458,6 +479,23 @@ class Plugin {
458
479
  */
459
480
  createBooking() {}
460
481
 
482
+ /**
483
+ * Allotment Object
484
+ /**
485
+ * @typedef {Object} Allotment
486
+ * @property {string} name - The name of the allotment.
487
+ * @property {string} description - A description of the allotment.
488
+ * @property {string} appliesTo - Specifies what the allotment applies to.
489
+ * @property {string} splitCode - The code used to split the allotment.
490
+ * @property {string} unitType - The type of unit used for the allotment.
491
+ * @property {Date} date - The date associated with the allotment using the input format.
492
+ * @property {string} release - The release period of the allotment as specified in the day inventory.
493
+ * @property {number} max - The maximum quantity allowed for the allotment as specified in the day inventory.
494
+ * @property {number} booked - The booked quantity of the allotment as specified in the day inventory.
495
+ * @property {boolean} request - Indicates whether requests are allowed for the allotment, based on the day inventory.
496
+ * @property {string[]} keyPaths - An array of key paths generated by combining supplier code and product codes.
497
+ */
498
+
461
499
  /**
462
500
  * Query Allotment
463
501
  * @async
@@ -473,7 +511,7 @@ class Plugin {
473
511
  * @param {string} args.payload.endDate - End date for the query of allotment objects
474
512
  * @param {string} args.payload.keyPath - End date for the query of allotment objects
475
513
  * @returns {object} retVal - the return object.
476
- * @returns {Booking} retVal.booking - A Booking object.
514
+ * @returns {Allotment[]} retVal.allotment - An array of allotment spec objects.
477
515
  */
478
516
  queryAllotment() {}
479
517
  }