ti2-tourplan 1.0.65 → 1.0.67

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 (21) hide show
  1. package/__fixtures__/GetServicesRequest_a1d6da590c93bb39ee48ad95e3204590c25b4bc4.txt +12 -0
  2. package/index.js +68 -61
  3. package/index.test.js +6 -1
  4. package/package.json +1 -1
  5. /package/__fixtures__/{7ff49d0caa3c1349cf6d55d3b7497179bbf5472d.txt → AgentInfoRequest_7ff49d0caa3c1349cf6d55d3b7497179bbf5472d.txt} +0 -0
  6. /package/__fixtures__/{3a93adfe4d454ce2b9a1c502df2837b7e40ce557.txt → AuthenticationRequest_3a93adfe4d454ce2b9a1c502df2837b7e40ce557.txt} +0 -0
  7. /package/__fixtures__/{86cc38d139b96a80da0de26e2a33a23465ef288d.txt → AuthenticationRequest_86cc38d139b96a80da0de26e2a33a23465ef288d.txt} +0 -0
  8. /package/__fixtures__/{2aa5ea5356a2bcb8b62e1b295e96417ace28dfb4.txt → GetBookingRequest_2aa5ea5356a2bcb8b62e1b295e96417ace28dfb4.txt} +0 -0
  9. /package/__fixtures__/{7ea998a3af5ed34be6df5f35685c0393ea65735c.txt → GetInventoryRequest_7ea998a3af5ed34be6df5f35685c0393ea65735c.txt} +0 -0
  10. /package/__fixtures__/{f7a1a40ec527a4f67f7619ffae01ef31470bee0b.txt → GetInventoryRequest_f7a1a40ec527a4f67f7619ffae01ef31470bee0b.txt} +0 -0
  11. /package/__fixtures__/{6f00b9788779772b77bbf444cbd77b1554f9146f.txt → GetInventory_Request_6f00b9788779772b77bbf444cbd77b1554f9146f.txt} +0 -0
  12. /package/__fixtures__/{886b85f63265b8b0f5d16706faa2614a88da4261.txt → ListBookingsRequest_886b85f63265b8b0f5d16706faa2614a88da4261.txt} +0 -0
  13. /package/__fixtures__/{9643a6606dfd496a5e37ae956d56d09e98848505.txt → ListBookingsRequest_9643a6606dfd496a5e37ae956d56d09e98848505.txt} +0 -0
  14. /package/__fixtures__/{aeb193f31b797722f6cd5ce0f60bb04fe624af43.txt → ListBookingsRequest_aeb193f31b797722f6cd5ce0f60bb04fe624af43.txt} +0 -0
  15. /package/__fixtures__/{1f31a4c2a86da422468b2d63e91aee5af5f474a4.txt → OptionInfoRequest_1f31a4c2a86da422468b2d63e91aee5af5f474a4.txt} +0 -0
  16. /package/__fixtures__/{2dddcacad6843b2e1925595ba5a83729f73d9255.txt → OptionInfoRequest_2dddcacad6843b2e1925595ba5a83729f73d9255.txt} +0 -0
  17. /package/__fixtures__/{53bbb66ab400767d8acbf07cbbf0a209425dbe5a.txt → OptionInfoRequest_53bbb66ab400767d8acbf07cbbf0a209425dbe5a.txt} +0 -0
  18. /package/__fixtures__/{5dc8cf72c01e5936707bca9dc93886b052876710.txt → OptionInfoRequest_5dc8cf72c01e5936707bca9dc93886b052876710.txt} +0 -0
  19. /package/__fixtures__/{a3e4b3058ef73d681664b78229eef213464fb64d.txt → OptionInfoRequest_a3e4b3058ef73d681664b78229eef213464fb64d.txt} +0 -0
  20. /package/__fixtures__/{e63f8e40781f63c39437422e5be8f5aa73e99bb6.txt → OptionInfoRequest_e63f8e40781f63c39437422e5be8f5aa73e99bb6.txt} +0 -0
  21. /package/__fixtures__/{dfc0d0474d53d75cee5d309c674d3b47fdc22861.txt → OptionInfoRequest_f6aa39ed6ad63edeafbb20dce819b95ad2db6b46.txt} +0 -0
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE Reply SYSTEM "http://localhost:8080/iCom_Test/hostConnect_4_06_009.dtd">
3
+ <Reply>
4
+ <GetServicesReply>
5
+ <TPLServices>
6
+ <TPLService>
7
+ <Code>AC</Code>
8
+ <Name>Activity</Name>
9
+ </TPLService>
10
+ </TPLServices>
11
+ </GetServicesReply>
12
+ </Reply>
package/index.js CHANGED
@@ -248,6 +248,12 @@ class BuyerPlugin {
248
248
  .replace(BAD_XML_CHARS, '')
249
249
  };
250
250
 
251
+ this.cacheSettings = {
252
+ bookingsProductSearch: {
253
+ // ttl: 60 * 60 * 24, // 1 day
254
+ },
255
+ };
256
+
251
257
  // this.errorPathsAxiosErrors = () => ([ // axios triggered errors
252
258
  // ['response', 'data', 'error'],
253
259
  // ]);
@@ -296,7 +302,7 @@ class BuyerPlugin {
296
302
  assert(R.path(['AuthenticationReply'], replyObj) === '');
297
303
  return true;
298
304
  } catch (err) {
299
- console.log(err)
305
+ console.log(err.message);
300
306
  return false;
301
307
  }
302
308
  }
@@ -434,74 +440,75 @@ class BuyerPlugin {
434
440
  lastUpdatedFrom,
435
441
  },
436
442
  }) {
437
- const model = {
438
- OptionInfoRequest: {
439
- Opt: optionId || '?????????????????',
440
- Info: 'G',
443
+ /*
444
+ Pseudo
445
+ 1. getServiceCodes -> [AC, BD]
446
+ 2. for each serviceCode getoptions
447
+ 3. convert them to ti2 products structure
448
+ 4. merge all products from all serviceCodes
449
+ */
450
+ // getServices
451
+ const getServicesModel = {
452
+ GetServicesRequest: {
441
453
  AgentID: hostConnectAgentID,
442
454
  Password: hostConnectAgentPassword,
443
- ...(lastUpdatedFrom ? {
444
- LastUpdateFrom: lastUpdatedFrom,
445
- } : {}),
446
455
  },
447
456
  };
448
- const payload = {
449
- model,
457
+ const getServicesReply = await this.callTourplan({
458
+ model: getServicesModel,
450
459
  endpoint: hostConnectEndpoint,
451
460
  axios,
452
461
  xmlOptions: hostConnectXmlOptions,
453
- };
454
- // use cache if we are getting the full list
455
- // for example: for searchInput (backend search), we shouldn't get the full list from
456
- // tourplan each time user search
457
- const replyObj = optionId
458
- ? await this.callTourplan(payload)
459
- : await this.cache.getOrExec({
460
- // goway and pdnz uses the same AgentID and Password for agents
461
- // but their endpoint is different
462
- // so they had been overwritting each other's cache
463
- fnParams: [model, hostConnectEndpoint],
464
- fn: () => this.callTourplan(payload),
465
- ttl: 60 * 60 * 2, // 2 hours
466
- forceRefresh: Boolean(forceRefresh),
462
+ });
463
+ let serviceCodes = R.pathOr([], ['GetServicesReply', 'TPLServices', 'TPLService'], getServicesReply);
464
+ if (!Array.isArray(serviceCodes)) serviceCodes = [serviceCodes];
465
+ serviceCodes = serviceCodes.map(s => s.Code);
466
+ let products = [];
467
+ await Promise.each(serviceCodes, async serviceCode => {
468
+ const getOptionsModel = {
469
+ OptionInfoRequest: {
470
+ Opt: `???${serviceCode}????????????`,
471
+ Info: 'G',
472
+ AgentID: hostConnectAgentID,
473
+ Password: hostConnectAgentPassword,
474
+ ...(lastUpdatedFrom ? {
475
+ LastUpdateFrom: lastUpdatedFrom,
476
+ } : {}),
477
+ },
478
+ };
479
+ const getOptionsReply = await this.callTourplan({
480
+ model: getOptionsModel,
481
+ endpoint: hostConnectEndpoint,
482
+ axios,
483
+ xmlOptions: hostConnectXmlOptions,
467
484
  });
468
- const arrayOfOptionsGroupedBySupplierId = R.call(R.compose(
469
- R.values,
470
- R.groupBy(R.path(['OptGeneral', 'SupplierId'])),
471
- root => {
472
- if (!searchInput) return root;
473
- const getFullSearchStr = o => {
474
- const fullPptionName = `${R.path(['OptGeneral', 'Description'], o) || ''}-${R.path(['OptGeneral', 'Comment'], o) || ''}`;
475
- return `${R.path(['OptGeneral', 'SupplierName'], o) || ''} ${fullPptionName} ${R.path(['Opt'], o)} ${R.path(['OptGeneral', 'SupplierId'], o) || ''}`;
476
- };
477
- const inputValueLower = searchInput.trim().toLowerCase();
478
- const parts = inputValueLower.split(' ').filter(Boolean); // Filter out any empty strings just in case
479
- return root.filter(option => {
480
- const fullSearchStr = getFullSearchStr(option).toLowerCase();
481
- return parts.every(part => fullSearchStr.includes(part));
482
- });
483
- },
484
- root => {
485
- const options = R.pathOr([], ['OptionInfoReply', 'Option'], root);
486
- // due to the new parser, single option will be returned as an object
487
- // instead of an array
488
- if (Array.isArray(options)) return options;
489
- return [options];
490
- },
491
- ), replyObj);
492
- const products = await Promise.map(
493
- arrayOfOptionsGroupedBySupplierId,
494
- optionsGroupedBySupplierId => translateTPOption({
495
- rootValue: {
496
- optionsGroupedBySupplierId,
485
+ const arrayOfOptionsGroupedBySupplierId = R.call(R.compose(
486
+ R.values,
487
+ R.groupBy(R.path(['OptGeneral', 'SupplierId'])),
488
+ root => {
489
+ let options = R.pathOr([], ['OptionInfoReply', 'Option'], root);
490
+ // due to the new parser, single option will be returned as an object
491
+ // instead of an array
492
+ if (!Array.isArray(options)) options = [options];
493
+ console.log(`got ${options.length} options for serviceCode ${serviceCode}`);
494
+ return options;
497
495
  },
498
- typeDefs: itineraryProductTypeDefs,
499
- query: itineraryProductQuery,
500
- }),
501
- {
502
- concurrency: 10,
503
- },
504
- );
496
+ ), getOptionsReply);
497
+ const productsForServiceCode = await Promise.map(
498
+ arrayOfOptionsGroupedBySupplierId,
499
+ optionsGroupedBySupplierId => translateTPOption({
500
+ rootValue: {
501
+ optionsGroupedBySupplierId,
502
+ },
503
+ typeDefs: itineraryProductTypeDefs,
504
+ query: itineraryProductQuery,
505
+ }),
506
+ {
507
+ concurrency: 10,
508
+ },
509
+ );
510
+ products = products.concat(productsForServiceCode);
511
+ });
505
512
  if (!(products && products.length)) {
506
513
  throw new Error('No products found');
507
514
  }
@@ -917,7 +924,7 @@ class BuyerPlugin {
917
924
  });
918
925
  return newBooking;
919
926
  } catch (err) {
920
- console.log('error in searchBooking', err);
927
+ console.log('error in searchBooking', err.message);
921
928
  return null;
922
929
  }
923
930
  }, { concurrency: 10 });
package/index.test.js CHANGED
@@ -23,8 +23,12 @@ jest.mock('axios');
23
23
  const actualAxios = jest.requireActual('axios');
24
24
 
25
25
  const getFixture = async requestObject => {
26
+ // Extract request name using regex
27
+ const requestName = requestObject.data && typeof requestObject.data === 'string' && R.pathOr('UnknownRequest', [1], requestObject.data.match(/<(\w+Request)>/))
28
+ ? R.pathOr('UnknownRequest', [1], requestObject.data.match(/<(\w+Request)>/))
29
+ : 'UnknownRequest';
26
30
  const requestHash = hash(requestObject);
27
- const file = path.resolve(__dirname, `./__fixtures__/${requestHash}.txt`);
31
+ const file = path.resolve(__dirname, `./__fixtures__/${requestName}_${requestHash}.txt`);
28
32
  try {
29
33
  const fixture = (
30
34
  await readFile(file)
@@ -235,6 +239,7 @@ describe('search tests', () => {
235
239
  expect(retVal.rates.length).toBeGreaterThan(0);
236
240
  expect(retVal.type).toBe('inventory');
237
241
  });
242
+ // Skip this test because we aren't using A check anymore
238
243
  it.skip('searchAvailabilityForItinerary - bookable - on request', async () => {
239
244
  axios.mockImplementation(getFixture);
240
245
  const retVal = await app.searchAvailabilityForItinerary({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ti2-tourplan",
3
- "version": "1.0.65",
3
+ "version": "1.0.67",
4
4
  "description": "Tourplan's TI2 Plugin",
5
5
  "main": "index.js",
6
6
  "scripts": {