From cddbe3ffc60d8f726ea2d126a3f4981ed39bc969 Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 20 Jul 2016 21:21:09 +0300 Subject: [PATCH] Feature: added ticketing request to AirServiceInternal with parser. --- lib/Air/AirParser.js | 31 +++++++++++++++++++++-- lib/errors.js | 2 ++ test/Air/AirParser.test.js | 15 +++++++++++ test/FakeResponses/Air/ticketing.rsp.json | 1 + 4 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 test/Air/AirParser.test.js create mode 100644 test/FakeResponses/Air/ticketing.rsp.json diff --git a/lib/Air/AirParser.js b/lib/Air/AirParser.js index 5a684f82..de8137d3 100644 --- a/lib/Air/AirParser.js +++ b/lib/Air/AirParser.js @@ -32,9 +32,36 @@ var lowFaresSearchRequest = function(obj) { var ticketParse = function(obj) { if (!obj['air:AirTicketingRsp']) throw new uError('PARSING_AIR_TICKET_NO_REPLY', obj); + var rsp = obj["air:AirTicketingRsp"]["0"]; - //FIXME STUB - return obj; + var checkResponseMessage = false; + var checkTickets = false; + + if (obj["air:AirTicketingRsp"]["0"]["common_v33_0:ResponseMessage"]) { + var responseMessage = obj["air:AirTicketingRsp"]["0"]["common_v33_0:ResponseMessage"]; + responseMessage.forEach(msg => { + if (msg._ === 'OK:Ticket issued') { + checkResponseMessage = true; + } + }); + } + + if (checkResponseMessage === false ) { + throw new uError('PARSING_AIR_TICKET_NO_RESPONSE_MESSAGE', obj); + } + + if (rsp['air:ETR']) { + try { + checkTickets = rsp['air:ETR'].reduce((acc, x) => { + var ticketNumber = x['air:Ticket'][0]['$']['TicketNumber']; + return !!(acc && ticketNumber.length); + }, true); + } catch (e) { + throw new uError('PARSING_AIR_TICKET_NO_TICKETS', rsp); + } + } + + return checkResponseMessage && checkTickets; }; var ticketRequest = function(obj) { diff --git a/lib/errors.js b/lib/errors.js index 6bb94f7c..526386e6 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -77,6 +77,8 @@ var allErrors = { PARSING_AIR_NO_REPLY: {errno: 1200, msg: "No air:LowFareSearchRsp object in parsed XML for #Air.searchLowFares()"}, PARSING_AIR_KEYING_ERROR: {errno: 1201, msg: "Exception at mapping keys in air:LowFareSearchRsp"}, PARSING_AIR_WRONG_TYPE: {errno: 1202, msg: "One of main data arrays is missing in parsed XML response for #Air.searchLowFares()"}, + PARSING_AIR_TICKET_NO_RESPONSE_MESSAGE: {errno: 1203, msg: "Response message text doesn't contain OK:Ticket issued"}, + PARSING_AIR_TICKET_NO_TICKETS: {errno: 1204, msg: "Tickets not found in ticketing response."}, PARSING_AIR_IMPORT_NO_REPLY: {errno: 1400, msg: "No universal:UniversalRecordImportRsp object in parsed XML for #Air.import()"}, GDS_PLACE_QUEUE_ERROR: {errno: 1500, msg: 'Error during place queue request'}, diff --git a/test/Air/AirParser.test.js b/test/Air/AirParser.test.js new file mode 100644 index 00000000..502429cd --- /dev/null +++ b/test/Air/AirParser.test.js @@ -0,0 +1,15 @@ +var proxy = require('proxyquire'); +var sinon = require('sinon'); +var assert = require('assert'); + +var Parser = require('../../lib/Air/AirParser'); +var ticketingJson = require('../FakeResponses/Air/ticketing.rsp.json'); + +describe('#AirParser', function () { + describe('AIR_TICKET_REQUEST()', function () { + it('should test air ticket response parser.', function () { + var parsedResponse = Parser.AIR_TICKET_REQUEST(ticketingJson); + assert(parsedResponse === true, 'Incorrect parsing of ticketing response.'); + }); + }); +}); diff --git a/test/FakeResponses/Air/ticketing.rsp.json b/test/FakeResponses/Air/ticketing.rsp.json new file mode 100644 index 00000000..dadcf024 --- /dev/null +++ b/test/FakeResponses/Air/ticketing.rsp.json @@ -0,0 +1 @@ +{"air:AirTicketingRsp":[{"$":{"TraceId":"","TransactionId":"FD9280E70A07425CC17136550D6BCEBD","ResponseTime":"1366","xmlns:air":"http://www.travelport.com/schema/air_v33_0","xmlns:common_v33_0":"http://www.travelport.com/schema/common_v33_0"},"common_v33_0:ResponseMessage":[{"_":"PNR A3TGVW Fare 1 - ELECTRONIC TKT GENERATED TTL FARE EUR 28.62 SUPPORTING DOCUMENTS GENERATED MIR GENERATED - TTL FARE EUR 28.62 ------------------------------------- ITINERARY/INVOICE GENERATED","$":{"Code":"0","Type":"Info","ProviderCode":"1G"}},{"_":"OK:Ticket issued","$":{"Code":"0","Type":"Info","ProviderCode":"1G"}}],"air:ETR":[{"$":{"Key":"p5e20A9hSi2IsV0soVpafQ==","BasePrice":"USD10.00","Taxes":"EUR19.62","EquivalentBasePrice":"EUR9.00","Refundable":"false","Exchangeable":"false","IssuedDate":"2016-07-18T00:00:00.000+03:00","ProviderCode":"1G","ProviderLocatorCode":"A3TGVW","IATANumber":"67320772","PseudoCityCode":"36D5","PlatingCarrier":"PS","ElStat":"A"},"air:AirReservationLocatorCode":["P3HRG7"],"common_v33_0:AgencyInfo":[{"common_v33_0:AgentAction":[{"$":{"ActionType":"Created","AgentCode":"UAPI3210545979-0A952404","BranchCode":"P2660143","AgencyCode":"S1828245","EventTime":"2016-07-18T00:00:00.000+03:00"}}]}],"common_v33_0:BookingTraveler":[{"$":{"Key":"twrE9aJPQCGAcvl5OoLeUA=="},"common_v33_0:BookingTravelerName":[{"$":{"First":"PHILIPMR","Last":"VOLOV"}}],"common_v33_0:SSR":[{"$":{"Key":"bNS0mDItQFCKhaqXE7ZSrg==","SegmentRef":"d+tvaOHHQkizGd9s0FzDsQ==","Status":"HK","Type":"TKNE","FreeText":"5665267479857C1","Carrier":"PS","ProviderReservationInfoRef":"zpUWcG+5TXCBo7Kr6keVJA==","ElStat":"A"}}]}],"common_v33_0:FormOfPayment":[{"$":{"Key":"oZHmtQtkRECiI6CACn6Gyg==","Type":"Cash","Reusable":"false","ProfileKey":"3DCx0/RTQba0fmzwGx3YDQ=="}}],"common_v33_0:Payment":[{"$":{"Key":"7bcZJR4rQP+53jnf4RDXkQ==","Type":"Itinerary","Amount":"EUR28.62","FormOfPaymentRef":"oZHmtQtkRECiI6CACn6Gyg=="}}],"common_v33_0:SupplierLocator":[{"$":{"SupplierCode":"PS","SupplierLocatorCode":"R21HC"}}],"air:FareCalc":["IEV PS LWO Q5.00 5.00 USD10.00END XT 2.52HF13.50YR"],"air:Ticket":[{"$":{"Key":"q3/flx2/RGykiZeFBd7Epg==","TicketNumber":"5665267479857","TicketStatus":"N","ElStat":"A"},"air:Coupon":[{"$":{"Key":"N+lxZ31LTvust/6W0J0mVA==","CouponNumber":"1","MarketingCarrier":"PS","MarketingFlightNumber":"35","Origin":"KBP","Destination":"LWO","DepartureTime":"2016-08-10T15:30:00.000+03:00","StopoverCode":"true","BookingClass":"B","FareBasis":"B01PROU1","NotValidBefore":"2016-08-10","NotValidAfter":"2016-08-10","Status":"O","SegmentGroup":"0","MarriageGroup":"0","ElStat":"A"}}]}],"air:AirPricingInfo":[{"$":{"Key":"jcGF2wxlTVqHVG+pKXZClQ==","TotalPrice":"EUR28.62","BasePrice":"USD10.00","ApproximateTotalPrice":"EUR28.62","ApproximateBasePrice":"EUR9.00","EquivalentBasePrice":"EUR9.00","Taxes":"EUR19.62","LatestTicketingTime":"2016-07-18T23:59:00.000+03:00","TrueLastDateToTicket":"2016-07-28T23:59:00.000+03:00","PricingMethod":"Guaranteed","ETicketability":"Yes","ProviderReservationInfoRef":"zpUWcG+5TXCBo7Kr6keVJA==","AirPricingInfoGroup":"1","Ticketed":"true","PricingType":"StoredFare","FareCalculationInd":"G"},"air:FareInfo":[{"$":{"Key":"7p5LVRLnRMqe6lXU3GI0UQ==","FareBasis":"B01PROU1","PassengerTypeCode":"ADT","Origin":"KBP","Destination":"LWO","EffectiveDate":"2016-07-18T00:00:00.000+03:00","NotValidBefore":"2016-08-10","NotValidAfter":"2016-08-10"},"common_v33_0:Endorsement":[{"$":{"Value":"NON END/NO REF/CHNG REST"}}],"air:BaggageAllowance":[{"air:NumberOfPieces":["1"]}]}],"air:BookingInfo":[{"$":{"BookingCode":"B","CabinClass":"Economy","FareInfoRef":"7p5LVRLnRMqe6lXU3GI0UQ=="}}],"air:TaxInfo":[{"$":{"Category":"UA","Amount":"EUR1.35","Key":"KJZQRoC2QAuDzKzkxSy52Q=="}},{"$":{"Category":"YK","Amount":"EUR2.25","Key":"M2vMg5pZRg+hPvF4X46wfw=="}},{"$":{"Category":"HF","Amount":"EUR2.52","Key":"RBDZBOCuSeW1pEaGhuvIhg=="}},{"$":{"Category":"YR","Amount":"EUR13.50","Key":"vV1KTFepT8qJ8859IGFUmQ=="}}],"air:FareCalc":["IEV PS LWO Q5.00 5.00B01PROU1 USD10.00END"],"air:PassengerType":[{"$":{"Code":"ADT","BookingTravelerRef":"twrE9aJPQCGAcvl5OoLeUA=="},"air:FareGuaranteeInfo":[{"$":{"GuaranteeType":"Guaranteed"}}]}],"common_v33_0:BookingTravelerRef":[{"$":{"Key":"twrE9aJPQCGAcvl5OoLeUA=="}}],"air:ChangePenalty":[{"air:Amount":["USD0.00"]}],"air:CancelPenalty":[{"air:Amount":["USD0.00"]}]}],"air:BaggageAllowances":[{"air:BaggageAllowanceInfo":[{"$":{"TravelerType":"ADT","Origin":"IEV","Destination":"LWO","Carrier":"PS"},"air:URLInfo":[{"air:URL":["MYTRIPANDMORE.COM/BAGGAGEDETAILSPS.BAGG"]}],"air:TextInfo":[{"air:Text":["1P","BAGGAGE DISCOUNTS MAY APPLY BASED ON FREQUENT FLYER STATUS/ ONLINE CHECKIN/FORM OF PAYMENT/MILITARY/ETC."]}],"air:BagDetails":[{"$":{"ApplicableBags":"1stChecked"},"air:BaggageRestriction":[{"air:TextInfo":[{"air:Text":["BAGGAGE CHARGES DATA NOT AVAILABLE"]}]}]},{"$":{"ApplicableBags":"2ndChecked"},"air:BaggageRestriction":[{"air:TextInfo":[{"air:Text":["BAGGAGE CHARGES DATA NOT AVAILABLE"]}]}]}]}],"air:CarryOnAllowanceInfo":[{"$":{"Origin":"IEV","Destination":"LWO","Carrier":"PS"},"air:TextInfo":[{"air:Text":["BAGGAGE ALLOWANCE DATA NOT AVAILABLE"]}]}]}]}]}]} \ No newline at end of file