From c02f32207ef05313d75130485efe726081d71fe9 Mon Sep 17 00:00:00 2001 From: Judy Ngai Date: Wed, 23 Mar 2016 17:34:03 -0400 Subject: [PATCH] qpx agent --- app/models/agents/qpx_agent.rb | 30 +++--- spec/data_fixtures/qpx.json | 184 +++++++++++++++++++++++++++++++++ spec/models/agents/qpx_spec.rb | 12 +-- 3 files changed, 201 insertions(+), 25 deletions(-) create mode 100644 spec/data_fixtures/qpx.json diff --git a/app/models/agents/qpx_agent.rb b/app/models/agents/qpx_agent.rb index 5d26f285..18be49b8 100644 --- a/app/models/agents/qpx_agent.rb +++ b/app/models/agents/qpx_agent.rb @@ -6,7 +6,7 @@ module Agents description <<-MD - The QpxExpressAgent will tell you airline prices between a pair of cities. The api limit is 50 requests/day. + The QpxExpressAgent will tell you the minimum airline prices between a pair of cities. The api limit is 50 requests/day. Follow their documentation here (https://developers.google.com/qpx-express/v1/prereqs#get-a-google-account) to retrieve an api key. After you get to the google developer console, created a project, enabled qpx express api then you can choose `api key` credential to be created. @@ -15,9 +15,9 @@ module Agents All the default options must exist. For `infantInSeatCount`, `infantInLapCount`, `seniorCount`, and `childCount`, leave them to the default value of `0` if its not necessary. - Set `refundable` to `true` if you want ticket to be refundable. Make sure `date` is in this type of date format `YYYY-MO-DAY`. + Make sure `date` is in this type of date format `YYYY-MO-DAY`. - You can limit the number of `solutions` returned back. The first solution is the lowest priced ticket. Every detailed trip option details starts at `"slice"`. + You can limit the number of `solutions` returned back. The first solution is the lowest priced ticket. MD event_description <<-MD @@ -46,17 +46,16 @@ module Agents def default_options { - 'qpx_api_key': '', - 'adultCount': 1, - 'origin': 'BOS', - 'destination': 'SFO', - 'date': '2016-04-11', - 'childCount': 0, - 'infantInSeatCount': 0, - 'infantInLapCount': 0, - 'seniorCount': 0, - 'solutions': 3, - 'refundable': false + 'qpx_api_key' => '', + 'adultCount'=> 1, + 'origin' => 'BOS', + 'destination' => 'SFO', + 'date' => '2016-04-11', + 'childCount' => 0, + 'infantInSeatCount' => 0, + 'infantInLapCount'=> 0, + 'seniorCount'=> 0, + 'solutions'=> 3 } end @@ -71,7 +70,6 @@ module Agents errors.add(:base, "Infant In Lap Count") unless options['infantInLapCount'].present? errors.add(:base, "Senior Count must exist") unless options['seniorCount'].present? errors.add(:base, "Solutions must exist") unless options['solutions'].present? - errors.add(:base, "Refundable must exist") unless options['refundable'].present? end def working? @@ -79,7 +77,7 @@ module Agents end def check - post_params = {:request=>{:passengers=>{:kind=>"qpxexpress#passengerCounts", :adultCount=> interpolated["adultCount"], :childCount=> interpolated["childCount"], :infantInLapCount=>interpolated["infantInLapCount"], :infantInSeatCount=>interpolated['infantInSeatCount'], :seniorCount=>interpolated["seniorCount"]}, :slice=>[{:kind=>"qpxexpress#sliceInput", :origin=> interpolated["origin"].to_s , :destination=> interpolated["destination"].to_s , :date=> interpolated["date"].to_s }], :refundable=> interpolated["refundable"], :solutions=> interpolated["solutions"]}} + post_params = {:request=>{:passengers=>{:kind=>"qpxexpress#passengerCounts", :adultCount=> interpolated["adultCount"], :childCount=> interpolated["childCount"], :infantInLapCount=>interpolated["infantInLapCount"], :infantInSeatCount=>interpolated['infantInSeatCount'], :seniorCount=>interpolated["seniorCount"]}, :slice=>[{:kind=>"qpxexpress#sliceInput", :origin=> interpolated["origin"].to_s , :destination=> interpolated["destination"].to_s , :date=> interpolated["date"].to_s }], :solutions=> interpolated["solutions"]}} body = JSON.generate(post_params) request = HTTParty.post(event_url, :body => body, :headers => {"Content-Type" => "application/json"}) events = JSON.parse request.body diff --git a/spec/data_fixtures/qpx.json b/spec/data_fixtures/qpx.json new file mode 100644 index 00000000..4a4a625b --- /dev/null +++ b/spec/data_fixtures/qpx.json @@ -0,0 +1,184 @@ +{ + "kind": "qpxExpress#tripsSearch", + "trips": { + "kind": "qpxexpress#tripOptions", + "requestId": "a5KWNgUILMQXl0QjZ0O1Kj", + "data": { + "kind": "qpxexpress#data", + "airport": [ + { + "kind": "qpxexpress#airportData", + "code": "BOS", + "city": "BOS", + "name": "Boston Logan International" + }, + { + "kind": "qpxexpress#airportData", + "code": "SFO", + "city": "SFO", + "name": "San Francisco International" + } + ], + "city": [ + { + "kind": "qpxexpress#cityData", + "code": "BOS", + "name": "Boston" + }, + { + "kind": "qpxexpress#cityData", + "code": "SFO", + "name": "San Francisco" + } + ], + "aircraft": [ + { + "kind": "qpxexpress#aircraftData", + "code": "320", + "name": "Airbus A320" + } + ], + "tax": [ + { + "kind": "qpxexpress#taxData", + "id": "ZP", + "name": "US Flight Segment Tax" + }, + { + "kind": "qpxexpress#taxData", + "id": "AY_001", + "name": "US September 11th Security Fee" + }, + { + "kind": "qpxexpress#taxData", + "id": "US_001", + "name": "US Transportation Tax" + }, + { + "kind": "qpxexpress#taxData", + "id": "XF", + "name": "US Passenger Facility Charge" + } + ], + "carrier": [ + { + "kind": "qpxexpress#carrierData", + "code": "B6", + "name": "Jetblue Airways Corporation" + } + ] + }, + "tripOption": [ + { + "kind": "qpxexpress#tripOption", + "saleTotal": "USD244.10", + "id": "SD5atWDaIWFUAOehDmedl8001", + "slice": [ + { + "kind": "qpxexpress#sliceInfo", + "duration": 404, + "segment": [ + { + "kind": "qpxexpress#segmentInfo", + "duration": 404, + "flight": { + "carrier": "B6", + "number": "833" + }, + "id": "Gv+0Syg7VaA8NyWp", + "cabin": "COACH", + "bookingCode": "Z", + "bookingCodeCount": 7, + "marriedSegmentGroup": "0", + "leg": [ + { + "kind": "qpxexpress#legInfo", + "id": "LXRlPXVU35MvdfE-", + "aircraft": "320", + "arrivalTime": "2016-04-11T23:10-07:00", + "departureTime": "2016-04-11T19:26-04:00", + "origin": "BOS", + "destination": "SFO", + "originTerminal": "C", + "destinationTerminal": "I", + "duration": 404, + "onTimePerformance": 60, + "mileage": 2697, + "secure": true + } + ] + } + ] + } + ], + "pricing": [ + { + "kind": "qpxexpress#pricingInfo", + "fare": [ + { + "kind": "qpxexpress#fareInfo", + "id": "Aw9SUGx6XiV/Eeby73yJz5cu1avySnHVCBCW01QV6wk2", + "carrier": "B6", + "origin": "BOS", + "destination": "SFO", + "basisCode": "ZH4AUEN" + } + ], + "segmentPricing": [ + { + "kind": "qpxexpress#segmentPricing", + "fareId": "Aw9SUGx6XiV/Eeby73yJz5cu1avySnHVCBCW01QV6wk2", + "segmentId": "Gv+0Syg7VaA8NyWp" + } + ], + "baseFareTotal": "USD213.95", + "saleFareTotal": "USD213.95", + "saleTaxTotal": "USD30.15", + "saleTotal": "USD244.10", + "passengers": { + "kind": "qpxexpress#passengerCounts", + "adultCount": 1 + }, + "tax": [ + { + "kind": "qpxexpress#taxInfo", + "id": "US_001", + "chargeType": "GOVERNMENT", + "code": "US", + "country": "US", + "salePrice": "USD16.05" + }, + { + "kind": "qpxexpress#taxInfo", + "id": "AY_001", + "chargeType": "GOVERNMENT", + "code": "AY", + "country": "US", + "salePrice": "USD5.60" + }, + { + "kind": "qpxexpress#taxInfo", + "id": "XF", + "chargeType": "GOVERNMENT", + "code": "XF", + "country": "US", + "salePrice": "USD4.50" + }, + { + "kind": "qpxexpress#taxInfo", + "id": "ZP", + "chargeType": "GOVERNMENT", + "code": "ZP", + "country": "US", + "salePrice": "USD4.00" + } + ], + "fareCalculation": "BOS B6 SFO 213.95ZH4AUEN USD 213.95 END ZP BOS XT 16.05US 4.00ZP 5.60AY 4.50XF BOS4.50", + "latestTicketingTime": "2016-03-24T23:59-04:00", + "ptc": "ADT" + } + ] + } + ] + } +} diff --git a/spec/models/agents/qpx_spec.rb b/spec/models/agents/qpx_spec.rb index f3d42bca..d6bb2a28 100644 --- a/spec/models/agents/qpx_spec.rb +++ b/spec/models/agents/qpx_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' describe Agents::QpxAgent do before do - stub_request(:get, "https://www.googleapis.com/qpxExpress/v1/trips/search").to_return( + stub_request(:post, "https://www.googleapis.com/qpxExpress/v1/trips/search?key=800deeaf-e285-9d62-bc90-j999c1973cc9").to_return( :body => File.read(Rails.root.join("spec/data_fixtures/qpx.json")), :status => 200, :headers => {"Content-Type" => "application/json"} @@ -19,7 +19,6 @@ describe Agents::QpxAgent do 'infantInSeatCount' => 0, 'infantInLapCount'=> 0, 'seniorCount'=> 0, - 'refundable' => false, 'solutions'=> 3 } @@ -35,7 +34,7 @@ describe Agents::QpxAgent do end describe "#that checker should be valid" do - it "should check that the aftership object is valid" do + it "should check that the object is valid" do expect(@checker).to be_valid end @@ -88,16 +87,11 @@ describe Agents::QpxAgent do @checker.options['solutions'] = nil expect(@checker).not_to be_valid end - - it "should require Refundable" do - @checker.options['refundable'] = nil - expect(@checker).not_to be_valid - end end describe '#check' do it "should check that initial run creates an event" do - @checker.memory[:latestTicketingTime] = '2016-03-18T23:59-04:00' + @checker.memory[:latestTicketingTime] = '2016-03-24T23:59-04:00' expect { @checker.check }.to change { Event.count }.by(1) end end