ti2-ventrata 1.0.9 → 1.0.11

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/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const axios = require('axios');
2
+ const curlirize = require('axios-curlirize');
2
3
  const R = require('ramda');
3
4
  const Promise = require('bluebird');
4
5
  const assert = require('assert');
@@ -7,6 +8,9 @@ const jwt = require('jsonwebtoken');
7
8
  const wildcardMatch = require('./utils/wildcardMatch');
8
9
 
9
10
  const CONCURRENCY = 3; // is this ok ?
11
+ if (process.env.debug) {
12
+ curlirize(axios);
13
+ }
10
14
 
11
15
  const isNilOrEmpty = R.either(R.isNil, R.isEmpty);
12
16
  const isNilOrEmptyArray = el => {
@@ -54,12 +58,26 @@ const rateMap = {
54
58
  pricing: R.path(['pricingFrom']),
55
59
  };
56
60
 
61
+ const unitPricingMap = {
62
+ unitId: R.prop('unitId'),
63
+ original: R.prop('original'),
64
+ retail: R.prop('retail'),
65
+ net: R.prop('net'),
66
+ currencyPrecision: R.prop('currencyPrecision'),
67
+ };
68
+
57
69
  const availabilityMap = {
58
70
  dateTimeStart: root => R.path(['localDateTimeStart'], root) || R.path(['localDate'], root),
59
- dateTimeEnd: root => R.path(['localDateTimeEnd']) || R.path(['localDate'], root),
71
+ dateTimeEnd: root => R.path(['localDateTimeEnd'], root) || R.path(['localDate'], root),
60
72
  allDay: R.path(['allDay']),
61
73
  pricing: root => R.path(['pricing'], root) || R.path(['pricingFrom'], root),
62
- unitPricing: root => R.path(['unitPricing'], root) || R.path(['unitPricingFrom'], root),
74
+ unitPricing: root => {
75
+ let before = [];
76
+ if (R.path(['unitPricing'], root)) before = R.path(['unitPricing'], root);
77
+ else before = R.path(['unitPricingFrom'], root) || [];
78
+ return before.map(item => doMap(item, unitPricingMap));
79
+ },
80
+ vacancies: R.prop('vacancies'),
63
81
  offer: avail => (avail.offerCode ? doMap(avail, {
64
82
  offerId: R.path(['offerCode']),
65
83
  title: R.pathOr(undefined, ['offerTitle']),
@@ -109,7 +127,7 @@ const unitItemMap = {
109
127
  unitItemId: R.path(['uuid']),
110
128
  unitId: R.path(['unitId']),
111
129
  unitName: R.path(['unit', 'title']),
112
- supplierId: R.path(['supplierReference']),
130
+ supplierBookingId: R.path(['supplierReference']),
113
131
  status: e => capitalize(R.path(['status'], e)),
114
132
  contact: R.path(['contact']),
115
133
  pricing: R.path(['pricing']),
@@ -131,7 +149,7 @@ const bookingMap = {
131
149
  id: R.path(['id']),
132
150
  orderId: R.path(['orderReference']),
133
151
  bookingId: R.path(['supplierReference']),
134
- supplierId: R.path(['supplierReference']),
152
+ supplierBookingId: R.path(['supplierReference']),
135
153
  status: e => capitalize(R.path(['status'], e)),
136
154
  productId: R.path(['product', 'id']),
137
155
  productName: R.path(['product', 'title']),
@@ -171,11 +189,17 @@ const contactMap = {
171
189
  country: R.path(['country']),
172
190
  };
173
191
 
174
- const getHeaders = ({ apiKey, acceptLanguage, octoEnv }) => ({
192
+ const getHeaders = ({
193
+ apiKey,
194
+ acceptLanguage,
195
+ octoEnv,
196
+ referrer,
197
+ }) => ({
175
198
  Authorization: `Bearer ${apiKey}`,
176
199
  'Octo-Env': octoEnv,
177
200
  ...acceptLanguage ? { 'Accept-Language': acceptLanguage } : {},
178
201
  'Content-Type': 'application/json',
202
+ ...referrer ? { Referer: referrer } : {},
179
203
  });
180
204
 
181
205
  class Plugin {
@@ -454,9 +478,11 @@ class Plugin {
454
478
  },
455
479
  payload: {
456
480
  availabilityKey,
481
+ holder,
457
482
  notes,
458
483
  reference,
459
- holder,
484
+ referrer,
485
+ settlementMethod,
460
486
  },
461
487
  }) {
462
488
  assert(availabilityKey, 'an availability code is required !');
@@ -468,21 +494,27 @@ class Plugin {
468
494
  endpoint,
469
495
  octoEnv,
470
496
  acceptLanguage,
497
+ referrer,
471
498
  });
472
499
  let url = `${endpoint || this.endpoint}/bookings`;
473
500
  let data = await jwt.verify(availabilityKey, this.jwtKey);
474
501
  let booking = R.path(['data'], await axios({
475
502
  method: 'post',
476
503
  url,
477
- data: { ...data, notes },
504
+ data: {
505
+ settlementMethod,
506
+ ...data,
507
+ notes,
508
+ },
478
509
  headers,
479
510
  }));
480
511
  url = `${endpoint || this.endpoint}/bookings/${booking.uuid}/confirm`;
481
512
  const contact = doMap(holder, contactMap);
482
513
  data = {
483
- notes,
484
514
  contact,
515
+ notes,
485
516
  resellerReference: reference,
517
+ settlementMethod,
486
518
  };
487
519
  booking = R.path(['data'], await axios({
488
520
  method: 'post',
@@ -533,7 +565,7 @@ class Plugin {
533
565
  payload: {
534
566
  bookingId,
535
567
  resellerReference,
536
- supplierId,
568
+ supplierBookingId,
537
569
  travelDateStart,
538
570
  travelDateEnd,
539
571
  dateFormat,
@@ -542,7 +574,7 @@ class Plugin {
542
574
  assert(
543
575
  !isNilOrEmpty(bookingId)
544
576
  || !isNilOrEmpty(resellerReference)
545
- || !isNilOrEmpty(supplierId)
577
+ || !isNilOrEmpty(supplierBookingId)
546
578
  || !(
547
579
  isNilOrEmpty(travelDateStart) && isNilOrEmpty(travelDateEnd) && isNilOrEmpty(dateFormat)
548
580
  ),
@@ -582,8 +614,8 @@ class Plugin {
582
614
  headers,
583
615
  }));
584
616
  }
585
- if (!isNilOrEmpty(supplierId)) {
586
- url = `${endpoint || this.endpoint}/bookings?supplierReference=${supplierId}`;
617
+ if (!isNilOrEmpty(supplierBookingId)) {
618
+ url = `${endpoint || this.endpoint}/bookings?supplierReference=${supplierBookingId}`;
587
619
  return R.path(['data'], await axios({
588
620
  method: 'get',
589
621
  url,
package/index.test.js CHANGED
@@ -175,6 +175,7 @@ describe('search tests', () => {
175
175
  payload: {
176
176
  availabilityKey,
177
177
  notes: faker.lorem.paragraph(),
178
+ settlementMethod: 'DEFERRED',
178
179
  holder: {
179
180
  name: fullName[0],
180
181
  surname: fullName[1],
@@ -190,7 +191,7 @@ describe('search tests', () => {
190
191
  ({ booking } = retVal);
191
192
  expect(booking).toBeTruthy();
192
193
  expect(R.path(['id'], booking)).toBeTruthy();
193
- expect(R.path(['supplierId'], booking)).toBeTruthy();
194
+ expect(R.path(['supplierBookingId'], booking)).toBeTruthy();
194
195
  expect(R.path(['cancellable'], booking)).toBeTruthy();
195
196
  // console.log({ booking });
196
197
  });
@@ -231,11 +232,11 @@ describe('search tests', () => {
231
232
  ({ bookings } = retVal);
232
233
  expect(R.path([0, 'id'], bookings)).toBeTruthy();
233
234
  });
234
- it('it should be able to search bookings by supplierId', async () => {
235
+ it('it should be able to search bookings by supplierBookingId', async () => {
235
236
  const retVal = await app.searchBooking({
236
237
  token,
237
238
  payload: {
238
- bookingId: booking.supplierId,
239
+ bookingId: booking.supplierBookingId,
239
240
  },
240
241
  });
241
242
  expect(Array.isArray(retVal.bookings)).toBeTruthy();
@@ -255,5 +256,32 @@ describe('search tests', () => {
255
256
  ({ bookings } = retVal);
256
257
  expect(R.path([0, 'id'], bookings)).toBeTruthy();
257
258
  });
259
+ it('should be able to create a booking for a referrer', async () => {
260
+ const fullName = faker.name.findName().split(' ');
261
+ const retVal = await app.createBooking({
262
+ token,
263
+ payload: {
264
+ availabilityKey,
265
+ notes: faker.lorem.paragraph(),
266
+ holder: {
267
+ name: fullName[0],
268
+ surname: fullName[1],
269
+ phoneNumber: faker.phone.phoneNumber(),
270
+ emailAddress: `salvador+tests_${faker.lorem.slug()}@tourconnect.com`,
271
+ country: faker.address.countryCode(),
272
+ locales: ['en-US', 'en', 'es'],
273
+ },
274
+ reference,
275
+ referrer: 'referrerforapitest',
276
+ settlementMethod: 'DEFERRED',
277
+ },
278
+ });
279
+ expect(retVal.booking).toBeTruthy();
280
+ ({ booking } = retVal);
281
+ expect(booking).toBeTruthy();
282
+ expect(R.path(['id'], booking)).toBeTruthy();
283
+ expect(R.path(['supplierBookingId'], booking)).toBeTruthy();
284
+ expect(R.path(['cancellable'], booking)).toBeTruthy();
285
+ });
258
286
  });
259
287
  });
@@ -0,0 +1,81 @@
1
+ const NodeEnvironment = require('jest-environment-node');
2
+ const chalk = require('chalk');
3
+
4
+ const { debug } = process.env;
5
+
6
+ class NodeEnvironmentFailFast extends NodeEnvironment {
7
+ constructor(config, context) {
8
+ super(config, context);
9
+ this.failedDescribeMap = {};
10
+ this.registeredEventHandler = [];
11
+ this.lastParent = undefined;
12
+ }
13
+
14
+ async setup() {
15
+ await super.setup();
16
+ this.global.testEnvironment = this;
17
+ }
18
+
19
+ registerTestEventHandler(registeredEventHandler) {
20
+ this.registeredEventHandler.push(registeredEventHandler);
21
+ }
22
+
23
+ async executeTestEventHandlers(event, state) {
24
+ for (const handler of this.registeredEventHandler) {
25
+ await handler(event, state);
26
+ }
27
+ }
28
+
29
+ async handleTestEvent(event, state) {
30
+ await this.executeTestEventHandlers(event, state);
31
+
32
+ switch (event.name) {
33
+ case 'hook_failure': {
34
+ const describeBlockName = event.hook.parent.name;
35
+ this.failedDescribeMap[describeBlockName] = true;
36
+ // hook errors are not displayed if tests are skipped, so display them manually
37
+ console.error(`ERROR: ${describeBlockName} > ${event.hook.type}\n\n`, event.error, '\n');
38
+ break;
39
+ }
40
+ case 'test_fn_success': {
41
+ if (debug) {
42
+ if (this.lastParent !== event.test.parent.name) {
43
+ console.log(`${event.test.parent.name}\n ${chalk.green('\u2713')} ${event.test.name}`);
44
+ } else {
45
+ console.log(` ${chalk.green('\u2713')} ${event.test.name}`);
46
+ }
47
+ this.lastParent = event.test.parent.name;
48
+ }
49
+ break;
50
+ }
51
+ case 'test_fn_failure': {
52
+ this.failedDescribeMap[event.test.parent.name] = true;
53
+ if (debug) {
54
+ if (this.lastParent !== event.test.parent.name) {
55
+ console.log(`${event.test.parent.name}\n ${chalk.red('\u2715')} ${event.test.name}`);
56
+ } else {
57
+ console.log(` ${chalk.red('\u2715')} ${event.test.name}`);
58
+ }
59
+ this.lastParent = event.test.parent.name;
60
+ console.error(event.error.message);
61
+ }
62
+ break;
63
+ }
64
+ case 'test_start': {
65
+ if (this.failedDescribeMap[event.test.parent.name]) {
66
+ event.test.mode = 'skip';
67
+ }
68
+ break;
69
+ }
70
+ }
71
+
72
+ if (super.handleTestEvent) {
73
+ super.handleTestEvent(event, state);
74
+ }
75
+ }
76
+
77
+ async teardown() {
78
+ await super.teardown();
79
+ }
80
+ }
81
+ module.exports = NodeEnvironmentFailFast;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ti2-ventrata",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Ventrata's TI2 Plugin",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -17,7 +17,7 @@
17
17
  },
18
18
  "homepage": "https://github.com/TourConnect/ti2-ventrata#readme",
19
19
  "jest": {
20
- "testEnvironment": "node",
20
+ "testEnvironment": "<rootDir>/jestEnvironment.js",
21
21
  "coveragePathIgnorePatterns": [
22
22
  "/node_modules/"
23
23
  ],
@@ -34,12 +34,16 @@
34
34
  "ramda": "^0.27.1"
35
35
  },
36
36
  "devDependencies": {
37
+ "axios-curlirize": "^1.3.7",
38
+ "chalk": "^4.1.2",
37
39
  "eslint": "^8.4.1",
38
40
  "eslint-config-airbnb": "^19.0.2",
39
41
  "eslint-plugin-import": "^2.25.4",
40
42
  "faker": "^5.5.3",
41
43
  "jest": "^27.4.5",
42
44
  "jest-cli": "^27.4.7",
43
- "jest-diff": "^27.4.2"
45
+ "jest-diff": "^27.4.2",
46
+ "jest-environment-node": "27.4",
47
+ "jest-util": "27.4"
44
48
  }
45
49
  }