ti2 1.0.85 → 1.0.87
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/cache.js +6 -2
- package/controllers/__tests__/bookings.js +139 -20
- package/controllers/bookings.js +96 -5
- package/controllers/graphql-schemas/itinerary-booking.js +2 -0
- package/index.js +22 -3
- package/package.json +1 -1
- package/test/plugin.js +22 -1
package/cache.js
CHANGED
|
@@ -18,6 +18,7 @@ const save = async ({
|
|
|
18
18
|
}
|
|
19
19
|
return keyParam;
|
|
20
20
|
})()}`;
|
|
21
|
+
// console.log('saving key', key);
|
|
21
22
|
await cache.set(key, JSON.stringify(value));
|
|
22
23
|
if (!skipTTL) {
|
|
23
24
|
await cache.expire(key, ttl);
|
|
@@ -77,7 +78,7 @@ const drop = async ({
|
|
|
77
78
|
fn,
|
|
78
79
|
fnParams,
|
|
79
80
|
}) => {
|
|
80
|
-
|
|
81
|
+
const key = `${pluginName}:${(() => {
|
|
81
82
|
if (!keyParam) {
|
|
82
83
|
return hash({ fn, fnParams });
|
|
83
84
|
}
|
|
@@ -86,14 +87,17 @@ const drop = async ({
|
|
|
86
87
|
}
|
|
87
88
|
return keyParam;
|
|
88
89
|
})()}`;
|
|
89
|
-
|
|
90
|
+
// console.log('dropping key', key);
|
|
90
91
|
await cache.del(key);
|
|
91
92
|
};
|
|
92
93
|
|
|
94
|
+
const keys = async () => cache.keys('*');
|
|
95
|
+
|
|
93
96
|
module.exports = {
|
|
94
97
|
cache,
|
|
95
98
|
save,
|
|
96
99
|
getOrExec,
|
|
97
100
|
drop,
|
|
98
101
|
get,
|
|
102
|
+
keys,
|
|
99
103
|
};
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
/* globals beforeAll describe it expect */
|
|
1
|
+
/* globals beforeAll describe it expect jest beforeEach */
|
|
2
2
|
|
|
3
3
|
const chance = require('chance').Chance();
|
|
4
|
+
const hash = require('object-hash');
|
|
4
5
|
const testUtils = require('../../test/utils');
|
|
6
|
+
const cache = require('../../cache');
|
|
5
7
|
|
|
6
8
|
const { env: { adminKey } } = process;
|
|
7
9
|
|
|
8
|
-
describe('user:
|
|
10
|
+
describe('user: bookings controller', () => {
|
|
9
11
|
const newApp = {
|
|
10
12
|
name: 'travelgate',
|
|
11
13
|
packageName: 'ti2-travelgate',
|
|
@@ -35,6 +37,16 @@ describe('user: booking search', () => {
|
|
|
35
37
|
} = await testUtils({
|
|
36
38
|
plugins: [newApp.name],
|
|
37
39
|
}));
|
|
40
|
+
|
|
41
|
+
// drop all cache keys, clean slate
|
|
42
|
+
const cacheKeys = await cache.keys();
|
|
43
|
+
cacheKeys.forEach(key => cache.drop({
|
|
44
|
+
pluginName: key.split(':')[0],
|
|
45
|
+
key: key.split(':')[1],
|
|
46
|
+
}));
|
|
47
|
+
});
|
|
48
|
+
beforeEach(async () => {
|
|
49
|
+
jest.clearAllMocks();
|
|
38
50
|
});
|
|
39
51
|
|
|
40
52
|
let userToken;
|
|
@@ -77,7 +89,8 @@ describe('user: booking search', () => {
|
|
|
77
89
|
url: `/user/${userId}/apps`,
|
|
78
90
|
token: userToken,
|
|
79
91
|
});
|
|
80
|
-
if (!userAppKeys.
|
|
92
|
+
if (!userAppKeys.find(e => e.hint === newIntegration.tokenHint
|
|
93
|
+
&& e.integrationId === newApp.name)) {
|
|
81
94
|
// relation does not exits
|
|
82
95
|
const { value } = await doApiPost({
|
|
83
96
|
url: `/${appKey}/${userId}`,
|
|
@@ -92,7 +105,7 @@ describe('user: booking search', () => {
|
|
|
92
105
|
bookingId: '', supplierBookingId: '', name: '',
|
|
93
106
|
};
|
|
94
107
|
const { bookings } = await doApiPost({
|
|
95
|
-
url: `/bookings/${appKey}/${userId}/search`,
|
|
108
|
+
url: `/bookings/${appKey}/${userId}/testingToken/search`,
|
|
96
109
|
token: userToken,
|
|
97
110
|
payload,
|
|
98
111
|
});
|
|
@@ -105,21 +118,127 @@ describe('user: booking search', () => {
|
|
|
105
118
|
// expect(retVal.bookings.length > 0).toBeTruthy();
|
|
106
119
|
});
|
|
107
120
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
121
|
+
describe('searchProducts', () => {
|
|
122
|
+
it('should be able to get bookings products for most users without special setup: no cache', async () => {
|
|
123
|
+
const payload = {};
|
|
124
|
+
const { products } = await doApiPost({
|
|
125
|
+
url: `/products/${appKey}/${userId}/testingToken/search`,
|
|
126
|
+
token: userToken,
|
|
127
|
+
payload,
|
|
128
|
+
});
|
|
129
|
+
expect(plugins[0].searchProducts).toHaveBeenCalled();
|
|
130
|
+
expect(Array.isArray(products)).toBeTruthy();
|
|
131
|
+
expect(products.length).toBe(2);
|
|
132
|
+
expect(products[0].options.length).toBe(1);
|
|
133
|
+
expect(products[1].options.length).toBe(2);
|
|
134
|
+
});
|
|
135
|
+
it('should be able to get booking products: no cache, forceRefresh', async () => {
|
|
136
|
+
// NOTE: we need to remove the cache first
|
|
137
|
+
const cacheKey = hash({
|
|
138
|
+
appKey,
|
|
139
|
+
userId,
|
|
140
|
+
hint: 'testingToken',
|
|
141
|
+
operationId: 'bookingsProductSearch',
|
|
142
|
+
});
|
|
143
|
+
await cache.drop({
|
|
144
|
+
pluginName: appKey,
|
|
145
|
+
key: cacheKey,
|
|
146
|
+
});
|
|
147
|
+
const payload = {
|
|
148
|
+
forceRefresh: true,
|
|
149
|
+
};
|
|
150
|
+
const { products } = await doApiPost({
|
|
151
|
+
url: `/products/${appKey}/${userId}/testingToken/search`,
|
|
152
|
+
token: userToken,
|
|
153
|
+
payload,
|
|
154
|
+
});
|
|
155
|
+
expect(plugins[0].searchProducts).toHaveBeenCalled();
|
|
156
|
+
expect(Array.isArray(products)).toBeTruthy();
|
|
157
|
+
expect(products.length).toBe(2);
|
|
158
|
+
expect(products[0].options.length).toBe(1);
|
|
159
|
+
expect(products[1].options.length).toBe(2);
|
|
160
|
+
expect(plugins[0].searchProducts.mock.calls[0][0].token).toEqual(token);
|
|
161
|
+
});
|
|
162
|
+
it('should be able to get booking products: using cache', async () => {
|
|
163
|
+
const payload = {};
|
|
164
|
+
const { products } = await doApiPost({
|
|
165
|
+
url: `/products/${appKey}/${userId}/testingToken/search`,
|
|
166
|
+
token: userToken,
|
|
167
|
+
payload,
|
|
168
|
+
});
|
|
169
|
+
expect(plugins[0].searchProducts).not.toHaveBeenCalled();
|
|
170
|
+
expect(Array.isArray(products)).toBeTruthy();
|
|
171
|
+
expect(products.length).toBe(2);
|
|
172
|
+
expect(products[0].options.length).toBe(1);
|
|
173
|
+
expect(products[1].options.length).toBe(2);
|
|
174
|
+
});
|
|
175
|
+
it('should be able to get booking products with searchInput', async () => {
|
|
176
|
+
const payload = {
|
|
177
|
+
searchInput: 'Transfer from Sydney Harbor to Hilton Hotel',
|
|
178
|
+
};
|
|
179
|
+
const { products } = await doApiPost({
|
|
180
|
+
url: `/products/${appKey}/${userId}/testingToken/search`,
|
|
181
|
+
token: userToken,
|
|
182
|
+
payload,
|
|
183
|
+
});
|
|
184
|
+
expect(plugins[0].searchProducts).not.toHaveBeenCalled();
|
|
185
|
+
expect(Array.isArray(products)).toBeTruthy();
|
|
186
|
+
expect(products.length).toBe(1);
|
|
187
|
+
expect(products[0].productName).toBe('Davids');
|
|
188
|
+
expect(products[0].options.length).toBe(1);
|
|
189
|
+
expect(products[0].options[0].optionName).toBe('Transfer from Sydney Harbor Bridge to Hilton Hotel');
|
|
190
|
+
});
|
|
191
|
+
it('should be able to process doNotCallPluginForProducts in token', async () => {
|
|
192
|
+
const { userAppKeys } = await doApiGet({
|
|
193
|
+
url: `/user/${userId}/apps`,
|
|
194
|
+
token: userToken,
|
|
195
|
+
});
|
|
196
|
+
let newnewIntegration = userAppKeys.find(e => e.hint === 'hint_for_doNotCallPluginForProducts'
|
|
197
|
+
&& e.integrationId === newApp.name);
|
|
198
|
+
if (!newnewIntegration) {
|
|
199
|
+
const newIntegrationContent = {
|
|
200
|
+
endpoint: 'https://api.travelgatex.com',
|
|
201
|
+
apiKey: chance.guid(),
|
|
202
|
+
client: 'tourconnect',
|
|
203
|
+
doNotCallPluginForProducts: true,
|
|
204
|
+
};
|
|
205
|
+
// create a new user token with the new content
|
|
206
|
+
newnewIntegration = await doApiPost({
|
|
207
|
+
url: `/travelgate/${userId}`,
|
|
208
|
+
token: adminKey,
|
|
209
|
+
payload: {
|
|
210
|
+
token: newIntegrationContent,
|
|
211
|
+
tokenHint: 'hint_for_doNotCallPluginForProducts',
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
expect(newnewIntegration).toBeTruthy();
|
|
216
|
+
// first time call, no cache expect no plugin call and empty products
|
|
217
|
+
let products;
|
|
218
|
+
await doApiPost({
|
|
219
|
+
url: `/products/${appKey}/${userId}/hint_for_doNotCallPluginForProducts/search`,
|
|
220
|
+
token: userToken,
|
|
221
|
+
payload: {},
|
|
222
|
+
}).then(({ products: p }) => {
|
|
223
|
+
products = p;
|
|
224
|
+
});
|
|
225
|
+
expect(plugins[0].searchProducts).not.toHaveBeenCalled();
|
|
226
|
+
expect(Array.isArray(products)).toBeTruthy();
|
|
227
|
+
expect(products.length).toBe(0);
|
|
228
|
+
// second time call, forceRefresh and still expect plugin call
|
|
229
|
+
await doApiPost({
|
|
230
|
+
url: `/products/${appKey}/${userId}/hint_for_doNotCallPluginForProducts/search`,
|
|
231
|
+
token: userToken,
|
|
232
|
+
payload: { forceRefresh: true },
|
|
233
|
+
}).then(({ products: p }) => {
|
|
234
|
+
products = p;
|
|
235
|
+
});
|
|
236
|
+
expect(plugins[0].searchProducts).toHaveBeenCalled();
|
|
237
|
+
expect(Array.isArray(products)).toBeTruthy();
|
|
238
|
+
expect(products.length).toBe(2);
|
|
114
239
|
});
|
|
115
|
-
expect(plugins[0].searchProducts).toHaveBeenCalled();
|
|
116
|
-
expect(Array.isArray(products)).toBeTruthy();
|
|
117
|
-
expect(plugins[0].searchProducts.mock.calls[0][0].payload).toEqual(payload);
|
|
118
|
-
expect(plugins[0].searchProducts.mock.calls[0][0].token).toEqual(token);
|
|
119
|
-
|
|
120
|
-
// expect(Array.isArray(retVal.bookings)).toBeTruthy();
|
|
121
|
-
// expect(retVal.bookings.length > 0).toBeTruthy();
|
|
122
240
|
});
|
|
241
|
+
|
|
123
242
|
it('should be able to search for availabiility', async () => {
|
|
124
243
|
const payload = {
|
|
125
244
|
travelDateStart: '12/30/2025',
|
|
@@ -132,7 +251,7 @@ describe('user: booking search', () => {
|
|
|
132
251
|
nationality: 'ES',
|
|
133
252
|
};
|
|
134
253
|
const { availability } = await doApiPost({
|
|
135
|
-
url: `/bookings/${appKey}/${userId}/availability`,
|
|
254
|
+
url: `/bookings/${appKey}/${userId}/testingToken/availability`,
|
|
136
255
|
token: userToken,
|
|
137
256
|
payload,
|
|
138
257
|
});
|
|
@@ -154,7 +273,7 @@ describe('user: booking search', () => {
|
|
|
154
273
|
nationality: 'ES',
|
|
155
274
|
};
|
|
156
275
|
const { quote } = await doApiPost({
|
|
157
|
-
url: `/bookings/${appKey}/${userId}/quote`,
|
|
276
|
+
url: `/bookings/${appKey}/${userId}/testingToken/quote`,
|
|
158
277
|
token: userToken,
|
|
159
278
|
payload,
|
|
160
279
|
});
|
|
@@ -168,7 +287,7 @@ describe('user: booking search', () => {
|
|
|
168
287
|
id: chance.guid(),
|
|
169
288
|
};
|
|
170
289
|
await doApiPost({
|
|
171
|
-
url: `/bookings/${appKey}/${userId}/booking`,
|
|
290
|
+
url: `/bookings/${appKey}/${userId}/testingToken/booking`,
|
|
172
291
|
token: userToken,
|
|
173
292
|
payload,
|
|
174
293
|
});
|
package/controllers/bookings.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const assert = require('assert');
|
|
2
|
-
|
|
2
|
+
const hash = require('object-hash');
|
|
3
|
+
const cache = require('../cache');
|
|
4
|
+
const R = require('ramda');
|
|
3
5
|
const { UserAppKey } = require('../models/index');
|
|
4
6
|
const { typeDefs: productTypeDefs, query: productQuery } = require('./graphql-schemas/product');
|
|
5
7
|
const { typeDefs: availTypeDefs, query: availQuery } = require('./graphql-schemas/availability');
|
|
@@ -89,12 +91,48 @@ const bookingsCancel = plugins => async (req, res, next) => {
|
|
|
89
91
|
}
|
|
90
92
|
};
|
|
91
93
|
|
|
94
|
+
const $searchProductList = (products, searchInput = '', optionId = '') => {
|
|
95
|
+
// NOTE: optionId could be a string or an array of strings
|
|
96
|
+
// NOTE: searchInput should not appear at the same time as optionId
|
|
97
|
+
if (!(searchInput && searchInput.trim()) && !(optionId && optionId.length)) {
|
|
98
|
+
return products;
|
|
99
|
+
}
|
|
100
|
+
const getFullSearchStr = (product, option) => `${
|
|
101
|
+
R.path(['productName'], product) || ''
|
|
102
|
+
} ${R.path(['optionName'], option) || ''
|
|
103
|
+
} ${R.path(['optionId'], option) || ''
|
|
104
|
+
} ${R.path(['supplierId'], product) || ''}`;
|
|
105
|
+
const inputValueLower = (searchInput || '').trim().toLowerCase();
|
|
106
|
+
const parts = inputValueLower.split(' ').filter(Boolean); // Filter out any empty strings just in case
|
|
107
|
+
const pwFilteredOptions = products.map(product => {
|
|
108
|
+
const filteredOptions = R.pathOr([], ['options'], product).filter(option => {
|
|
109
|
+
if (optionId && optionId.length) {
|
|
110
|
+
const optionIdArr = R.is(Array, optionId) ? optionId : [optionId];
|
|
111
|
+
return optionIdArr.includes(R.path(['optionId'], option));
|
|
112
|
+
}
|
|
113
|
+
const fullSearchStr = getFullSearchStr(product, option).toLowerCase();
|
|
114
|
+
return parts.every(part => fullSearchStr.includes(part));
|
|
115
|
+
});
|
|
116
|
+
return {
|
|
117
|
+
...product,
|
|
118
|
+
options: filteredOptions,
|
|
119
|
+
};
|
|
120
|
+
});
|
|
121
|
+
const filteredProducts = pwFilteredOptions.filter(product => product.options.length > 0);
|
|
122
|
+
return filteredProducts;
|
|
123
|
+
};
|
|
124
|
+
|
|
92
125
|
const $bookingsProductSearch = plugins => async ({
|
|
93
126
|
axios,
|
|
94
127
|
appKey,
|
|
95
128
|
userId,
|
|
96
129
|
hint,
|
|
97
|
-
payload
|
|
130
|
+
payload: {
|
|
131
|
+
searchInput,
|
|
132
|
+
optionId,
|
|
133
|
+
forceRefresh,
|
|
134
|
+
...restPayload
|
|
135
|
+
},
|
|
98
136
|
requestId,
|
|
99
137
|
}) => {
|
|
100
138
|
const app = plugins.find(({ name }) => name === appKey);
|
|
@@ -112,15 +150,68 @@ const $bookingsProductSearch = plugins => async ({
|
|
|
112
150
|
assert(userAppKeys, 'could not find the app key');
|
|
113
151
|
const token = await userAppKeys.token;
|
|
114
152
|
const func = (app.searchProducts || app.searchProductsForItinerary).bind(app);
|
|
115
|
-
|
|
153
|
+
// NOTE: this is intend to cache the entire product list
|
|
154
|
+
const cacheKey = hash({
|
|
155
|
+
appKey,
|
|
156
|
+
userId,
|
|
157
|
+
hint,
|
|
158
|
+
operationId: 'bookingsProductSearch',
|
|
159
|
+
});
|
|
160
|
+
if (forceRefresh) {
|
|
161
|
+
// remove the cache
|
|
162
|
+
await cache.drop({
|
|
163
|
+
pluginName: appKey,
|
|
164
|
+
key: cacheKey,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
const cacheValue = await cache.get({
|
|
168
|
+
pluginName: appKey,
|
|
169
|
+
key: cacheKey,
|
|
170
|
+
});
|
|
171
|
+
if (cacheValue && cacheValue.products) {
|
|
172
|
+
const searchResults = $searchProductList(cacheValue.products, searchInput, optionId);
|
|
173
|
+
console.log(`${appKey}/${userId}/${hint}: found cache and returning cached products: ${searchResults.length}`);
|
|
174
|
+
return {
|
|
175
|
+
...cacheValue,
|
|
176
|
+
products: searchResults,
|
|
177
|
+
// this is for sending the product filters specifically being used by pyfilematch
|
|
178
|
+
...(token.configuration || {}),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
const doNotCallPluginForProducts = token.doNotCallPluginForProducts
|
|
182
|
+
|| R.path(['cacheSettings', 'bookingsProductSearch', 'doNotCall'], app);
|
|
183
|
+
if (doNotCallPluginForProducts && !forceRefresh) {
|
|
184
|
+
console.log(`${appKey}/${userId}/${hint}: no cache found but not calling the plugin because doNotCallPluginForProducts is true and forceRefresh is false`);
|
|
185
|
+
return { products: [] };
|
|
186
|
+
}
|
|
187
|
+
console.log(`${appKey}/${userId}/${hint}: no cache found(forceRefresh: ${forceRefresh}) and calling func`);
|
|
188
|
+
const funcResults = await func({
|
|
116
189
|
axios,
|
|
117
190
|
token,
|
|
118
|
-
payload,
|
|
191
|
+
payload: restPayload,
|
|
119
192
|
typeDefsAndQueries,
|
|
120
193
|
requestId,
|
|
121
194
|
userId,
|
|
122
195
|
});
|
|
123
|
-
|
|
196
|
+
// save cache if products are found
|
|
197
|
+
if (funcResults && funcResults.products && funcResults.products.length > 0) {
|
|
198
|
+
// 25 hours, just to have some buffer
|
|
199
|
+
const ttl = token.ttlForProducts || R.path(['cacheSettings', 'bookingsProductSearch', 'ttl'], app) || 60 * 60 * 25;
|
|
200
|
+
console.log(`${appKey}/${userId}/${hint}: saving cache of ${funcResults.products.length} products for (ttl:${ttl})`);
|
|
201
|
+
await cache.save({
|
|
202
|
+
pluginName: appKey,
|
|
203
|
+
key: cacheKey,
|
|
204
|
+
value: funcResults,
|
|
205
|
+
ttl,
|
|
206
|
+
skipTTL: Boolean(doNotCallPluginForProducts),
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
const searchResults = $searchProductList(R.pathOr([], ['products'], funcResults), searchInput, optionId);
|
|
210
|
+
return {
|
|
211
|
+
...funcResults,
|
|
212
|
+
products: searchResults,
|
|
213
|
+
...(token.configuration || {}),
|
|
214
|
+
};
|
|
124
215
|
};
|
|
125
216
|
|
|
126
217
|
const bookingsProductSearch = plugins => async (req, res, next) => {
|
|
@@ -35,6 +35,7 @@ const typeDefs = `
|
|
|
35
35
|
bookingStatus: String!
|
|
36
36
|
ref: String!
|
|
37
37
|
agentRef: String
|
|
38
|
+
currency: String!
|
|
38
39
|
totalPrice: String!
|
|
39
40
|
currency: String!
|
|
40
41
|
travelDate: String!
|
|
@@ -50,6 +51,7 @@ const query = `{
|
|
|
50
51
|
bookingStatus
|
|
51
52
|
ref
|
|
52
53
|
agentRef
|
|
54
|
+
currency
|
|
53
55
|
totalPrice
|
|
54
56
|
currency
|
|
55
57
|
travelDate
|
package/index.js
CHANGED
|
@@ -20,7 +20,7 @@ const cacheSettings = {
|
|
|
20
20
|
'getAffiliateAgents',
|
|
21
21
|
'getAffiliateDesks',
|
|
22
22
|
'getPickupPoints',
|
|
23
|
-
'bookingsProductSearch',
|
|
23
|
+
// 'bookingsProductSearch',
|
|
24
24
|
'getCreateBookingFields',
|
|
25
25
|
],
|
|
26
26
|
};
|
|
@@ -263,10 +263,29 @@ module.exports = async ({
|
|
|
263
263
|
const currentPlugin = req.pathParams
|
|
264
264
|
? plugins.find(p => p.name === req.pathParams.appKey)
|
|
265
265
|
: null;
|
|
266
|
+
/*
|
|
267
|
+
currentPlugin = {
|
|
268
|
+
cacheSettings: {
|
|
269
|
+
getAffiliateDesks: {
|
|
270
|
+
ttl: 60 * 60 * 24, // one day
|
|
271
|
+
},
|
|
272
|
+
getPickupPoints: {
|
|
273
|
+
ttl: 60 * 60 * 24, // one day
|
|
274
|
+
// we will do middleware caching for getPickupPoints
|
|
275
|
+
cacheInMiddleware: true,
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
}
|
|
279
|
+
*/
|
|
266
280
|
const pluginCacheSettings = R.pathOr({}, ['cacheSettings'], currentPlugin);
|
|
281
|
+
// Filter plugin cache settings to only include those with cacheInMiddleware: true
|
|
282
|
+
const filteredPluginCacheSettings = R.pickBy(
|
|
283
|
+
value => R.pathOr(false, ['cacheInMiddleware'], value),
|
|
284
|
+
pluginCacheSettings,
|
|
285
|
+
);
|
|
267
286
|
const cachingOperations = [
|
|
268
287
|
...cacheSettings['*'],
|
|
269
|
-
...(currentPlugin ? R.keys(
|
|
288
|
+
...(currentPlugin ? R.keys(filteredPluginCacheSettings) : []),
|
|
270
289
|
];
|
|
271
290
|
const body = req.customBody;
|
|
272
291
|
if (cachingOperations.indexOf(body.operationId) > -1) {
|
|
@@ -288,7 +307,7 @@ module.exports = async ({
|
|
|
288
307
|
pluginName: req.pathParams.appKey,
|
|
289
308
|
key: cacheKey,
|
|
290
309
|
value: newData,
|
|
291
|
-
skipTTL: R.path([body.operationId, 'skipTTL'],
|
|
310
|
+
skipTTL: R.path([body.operationId, 'skipTTL'], filteredPluginCacheSettings),
|
|
292
311
|
ttl: 60 * 60 * 24, // one day
|
|
293
312
|
});
|
|
294
313
|
}
|
package/package.json
CHANGED
package/test/plugin.js
CHANGED
|
@@ -35,7 +35,28 @@ class Plugin {
|
|
|
35
35
|
this.createLocation = jestPlugin.fn(() => ({ locationId: chance.guid() }));
|
|
36
36
|
this.updateLocation = jestPlugin.fn(() => true);
|
|
37
37
|
this.searchBooking = jestPlugin.fn(() => ({ bookings: [] }));
|
|
38
|
-
this.searchProducts = jestPlugin.fn(() =>
|
|
38
|
+
this.searchProducts = jestPlugin.fn(() => {
|
|
39
|
+
return {
|
|
40
|
+
products: [{
|
|
41
|
+
productId: '123',
|
|
42
|
+
productName: 'Bonza Bike Tours',
|
|
43
|
+
options: [{
|
|
44
|
+
optionId: '123',
|
|
45
|
+
optionName: 'Sydney Harbour Bridge Climb',
|
|
46
|
+
}],
|
|
47
|
+
}, {
|
|
48
|
+
productId: '234',
|
|
49
|
+
productName: 'Davids',
|
|
50
|
+
options: [{
|
|
51
|
+
optionId: '2346',
|
|
52
|
+
optionName: 'Transfer from Sydney Airport to Hilton Hotel',
|
|
53
|
+
}, {
|
|
54
|
+
optionId: '2345',
|
|
55
|
+
optionName: 'Transfer from Sydney Harbor Bridge to Hilton Hotel',
|
|
56
|
+
}],
|
|
57
|
+
}],
|
|
58
|
+
};
|
|
59
|
+
});
|
|
39
60
|
this.searchAvailability = jestPlugin.fn(({
|
|
40
61
|
token,
|
|
41
62
|
payload: {
|