ti2-ventrata 1.0.45 → 1.0.47
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 +9 -0
- package/package.json +1 -1
- package/resolvers/mapping.test.js +133 -0
package/index.js
CHANGED
|
@@ -96,6 +96,10 @@ class Plugin {
|
|
|
96
96
|
this.errorPathsAxiosAny = () => ([]); // 200's that should be errors
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
static settlementMethodRequiresResellerReference(settlementMethod) {
|
|
100
|
+
return ['DIRECT', 'VOUCHER'].includes(settlementMethod);
|
|
101
|
+
}
|
|
102
|
+
|
|
99
103
|
static getSettlementMethod(reference, availableSettlementMethods = []) {
|
|
100
104
|
// Determine settlement method from product's available methods
|
|
101
105
|
let settlementMethod = 'DEFERRED'; // default fallback
|
|
@@ -544,6 +548,11 @@ class Plugin {
|
|
|
544
548
|
settlementMethods,
|
|
545
549
|
);
|
|
546
550
|
|
|
551
|
+
assert(
|
|
552
|
+
!Plugin.settlementMethodRequiresResellerReference(settlementMethod) || !isNilOrEmpty(reference),
|
|
553
|
+
`Agent reference is required for ${settlementMethod} booking.`,
|
|
554
|
+
);
|
|
555
|
+
|
|
547
556
|
let booking;
|
|
548
557
|
try {
|
|
549
558
|
booking = R.path(['data'], await axios({
|
package/package.json
CHANGED
|
@@ -180,6 +180,139 @@ describe('ventrata mappings', () => {
|
|
|
180
180
|
);
|
|
181
181
|
});
|
|
182
182
|
|
|
183
|
+
const bookingResponse = {
|
|
184
|
+
id: 'booking-id',
|
|
185
|
+
uuid: 'booking-uuid',
|
|
186
|
+
orderId: 'order-id',
|
|
187
|
+
orderReference: 'order-ref',
|
|
188
|
+
supplierReference: 'supplier-ref',
|
|
189
|
+
status: 'CONFIRMED',
|
|
190
|
+
product: { id: 'product-1', internalName: 'Product' },
|
|
191
|
+
option: { id: 'DEFAULT', internalName: 'DEFAULT' },
|
|
192
|
+
availability: { localDateTimeStart: '2026-05-02T08:00:00', localDateTimeEnd: '2026-05-02T10:00:00' },
|
|
193
|
+
contact: { fullName: 'Test User' },
|
|
194
|
+
cancellable: true,
|
|
195
|
+
utcCreatedAt: '2026-05-01T00:00:00Z',
|
|
196
|
+
pricing: { retail: 1000 },
|
|
197
|
+
unitItems: [{ uuid: 'unit-item-1', unitId: 'adult-unit', internalName: 'Adult' }],
|
|
198
|
+
utcConfirmedAt: '2026-05-01T00:00:01Z',
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
it.each(['VOUCHER', 'DIRECT'])(
|
|
202
|
+
'requires agent reference when the selected settlement method is %s',
|
|
203
|
+
async settlementMethod => {
|
|
204
|
+
const plugin = new Plugin({
|
|
205
|
+
jwtKey: 'test-jwt-key',
|
|
206
|
+
endpoint: 'https://example.test/octo',
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
jest.spyOn(jwt, 'verify').mockReturnValue({
|
|
210
|
+
productId: 'product-1',
|
|
211
|
+
optionId: 'DEFAULT',
|
|
212
|
+
availabilityId: 'avail-1',
|
|
213
|
+
unitItems: [{ unitId: 'adult-unit' }],
|
|
214
|
+
settlementMethods: [settlementMethod],
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const axios = jest.fn().mockResolvedValue({ data: bookingResponse });
|
|
218
|
+
|
|
219
|
+
await expect(plugin.createBooking({
|
|
220
|
+
axios,
|
|
221
|
+
token: { apiKey: 'api-key' },
|
|
222
|
+
payload: {
|
|
223
|
+
availabilityKey: 'signed-key',
|
|
224
|
+
holder: { name: 'Test', surname: 'User', country: 'US' },
|
|
225
|
+
},
|
|
226
|
+
typeDefsAndQueries: {
|
|
227
|
+
bookingTypeDefs: ti2BookingTypeDefs,
|
|
228
|
+
bookingQuery: ti2BookingQuery,
|
|
229
|
+
},
|
|
230
|
+
})).rejects.toThrow(`Agent reference is required for ${settlementMethod} booking.`);
|
|
231
|
+
|
|
232
|
+
expect(axios).not.toHaveBeenCalled();
|
|
233
|
+
},
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
it.each(['VOUCHER', 'DIRECT'])(
|
|
237
|
+
'allows %s settlement when agent reference is provided',
|
|
238
|
+
async settlementMethod => {
|
|
239
|
+
const plugin = new Plugin({
|
|
240
|
+
jwtKey: 'test-jwt-key',
|
|
241
|
+
endpoint: 'https://example.test/octo',
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
jest.spyOn(jwt, 'verify').mockReturnValue({
|
|
245
|
+
productId: 'product-1',
|
|
246
|
+
optionId: 'DEFAULT',
|
|
247
|
+
availabilityId: 'avail-1',
|
|
248
|
+
unitItems: [{ unitId: 'adult-unit' }],
|
|
249
|
+
settlementMethods: [settlementMethod, 'DEFERRED'],
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
const axios = jest.fn().mockResolvedValue({ data: bookingResponse });
|
|
253
|
+
|
|
254
|
+
await plugin.createBooking({
|
|
255
|
+
axios,
|
|
256
|
+
token: { apiKey: 'api-key' },
|
|
257
|
+
payload: {
|
|
258
|
+
availabilityKey: 'signed-key',
|
|
259
|
+
holder: { name: 'Test', surname: 'User', country: 'US' },
|
|
260
|
+
reference: 'AGENT-REF-123',
|
|
261
|
+
},
|
|
262
|
+
typeDefsAndQueries: {
|
|
263
|
+
bookingTypeDefs: ti2BookingTypeDefs,
|
|
264
|
+
bookingQuery: ti2BookingQuery,
|
|
265
|
+
},
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
const createBookingCall = axios.mock.calls.find(call => call[0].url === 'https://example.test/octo/bookings');
|
|
269
|
+
expect(createBookingCall).toBeTruthy();
|
|
270
|
+
expect(createBookingCall[0].data).toEqual(
|
|
271
|
+
expect.objectContaining({
|
|
272
|
+
settlementMethod,
|
|
273
|
+
}),
|
|
274
|
+
);
|
|
275
|
+
},
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
it('falls back to DEFERRED without agent reference when DEFERRED is available', async () => {
|
|
279
|
+
const plugin = new Plugin({
|
|
280
|
+
jwtKey: 'test-jwt-key',
|
|
281
|
+
endpoint: 'https://example.test/octo',
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
jest.spyOn(jwt, 'verify').mockReturnValue({
|
|
285
|
+
productId: 'product-1',
|
|
286
|
+
optionId: 'DEFAULT',
|
|
287
|
+
availabilityId: 'avail-1',
|
|
288
|
+
unitItems: [{ unitId: 'adult-unit' }],
|
|
289
|
+
settlementMethods: ['VOUCHER', 'DIRECT', 'DEFERRED'],
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
const axios = jest.fn().mockResolvedValue({ data: bookingResponse });
|
|
293
|
+
|
|
294
|
+
await plugin.createBooking({
|
|
295
|
+
axios,
|
|
296
|
+
token: { apiKey: 'api-key' },
|
|
297
|
+
payload: {
|
|
298
|
+
availabilityKey: 'signed-key',
|
|
299
|
+
holder: { name: 'Test', surname: 'User', country: 'US' },
|
|
300
|
+
},
|
|
301
|
+
typeDefsAndQueries: {
|
|
302
|
+
bookingTypeDefs: ti2BookingTypeDefs,
|
|
303
|
+
bookingQuery: ti2BookingQuery,
|
|
304
|
+
},
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
const createBookingCall = axios.mock.calls.find(call => call[0].url === 'https://example.test/octo/bookings');
|
|
308
|
+
expect(createBookingCall).toBeTruthy();
|
|
309
|
+
expect(createBookingCall[0].data).toEqual(
|
|
310
|
+
expect.objectContaining({
|
|
311
|
+
settlementMethod: 'DEFERRED',
|
|
312
|
+
}),
|
|
313
|
+
);
|
|
314
|
+
});
|
|
315
|
+
|
|
183
316
|
it('maps participant-scoped custom fields from standard ti2 payload into unitItems questionAnswers', async () => {
|
|
184
317
|
const plugin = new Plugin({
|
|
185
318
|
jwtKey: 'test-jwt-key',
|