From 1d07bca22157517015c3973900f5d2cd5485fd9d Mon Sep 17 00:00:00 2001 From: Judy Ngai Date: Wed, 23 Mar 2016 11:23:50 -0400 Subject: [PATCH] checking in progress on flight agent --- app/models/agents/qpx_agent.rb | 82 ++++++++++++++++++++++++++-------- spec/models/agents/qpx_spec.rb | 76 ++++++++++++++++++++++++++----- 2 files changed, 129 insertions(+), 29 deletions(-) diff --git a/app/models/agents/qpx_agent.rb b/app/models/agents/qpx_agent.rb index e68ae49e..5d26f285 100644 --- a/app/models/agents/qpx_agent.rb +++ b/app/models/agents/qpx_agent.rb @@ -1,49 +1,93 @@ module Agents class QpxAgent < Agent - default_schedule "every_10m" + cannot_receive_events! + default_schedule "every_12h" + description <<-MD - The QpxExpressAgent will tell you the minimum airline prices between a pair of cities, and within a certain period of time. + The QpxExpressAgent will tell you 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. + + `Origin` and `Destination` requires `airport code`. + + 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`. + + 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"`. + MD + + event_description <<-MD + The event payload will have objects that contains valuable data like this + + "carrier": [ + { + "code": "B6", + "name": "Jetblue Airways Corporation" + } + ] + + "tripOption": [ + "saleTotal": "USD49.10" + "slice": [ + ... + ... + "flight": { + "carrier": "B6", + "number": "833" + } + ] + ] - Follow their introduction 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 chrome console and enabled qpx express api, you can choose `api key` credential to be created. - For round trips please provide a `return_date`. MD def default_options { - 'qpx_api_key' => 'AIzaSyCMwV5ackABmIPX9pUgEPELXB_FiNKmem0', - 'date' => "2016-03-18", - 'origin' => "origin", - 'destination' => "destination", - 'return_date' => "2016-03-25" + '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 } end def validate_options errors.add(:base, "You need a qpx api key") unless options['qpx_api_key'].present? - # errors.add(:base, "A origin must exist") unless options['origin'].present? - # errors.add(:base, "A destination must exist") unless options['destination'].present? - # errors.add(:base, "A date must exist") unless options['date'].present? + errors.add(:base, "Adult Count must exist") unless options['adultCount'].present? + errors.add(:base, "Origin must exist") unless options['origin'].present? + errors.add(:base, "Destination must exist") unless options['destination'].present? + errors.add(:base, "Date must exist") unless options['date'].present? + errors.add(:base, "Child Count") unless options['childCount'].present? + errors.add(:base, "Infant In Seat Count must exist") unless options['infantInSeatCount'].present? + 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? !recent_error_logs? end - HEADERS = {"Content-Type" => "application/json"} - def check - hash = {:request=>{:passengers=>{:adultCount=>1}, :slice=>[{:origin=>"BOS", :destination=>"LAX", :date=>"2016-03-20"}, {:origin=>"LAX", :destination=>"BOS", :date=>"2016-03-20"}]}} - body = JSON.generate(hash) - request = HTTParty.post(event_url, :body => @body, :headers => HEADERS) + 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"]}} + body = JSON.generate(post_params) + request = HTTParty.post(event_url, :body => body, :headers => {"Content-Type" => "application/json"}) events = JSON.parse request.body create_event :payload => events end def event_url - endpoint = 'https://www.googleapis.com/qpxExpress/v1/trips/search?key' + "#{URI.encode(interpolated[:qpx_api_key].to_s)}" + endpoint = 'https://www.googleapis.com/qpxExpress/v1/trips/search?key=' + "#{URI.encode(interpolated[:qpx_api_key].to_s)}" end end end diff --git a/spec/models/agents/qpx_spec.rb b/spec/models/agents/qpx_spec.rb index 22f7fa99..f3d42bca 100644 --- a/spec/models/agents/qpx_spec.rb +++ b/spec/models/agents/qpx_spec.rb @@ -1,30 +1,36 @@ require 'rails_helper' -describe Agents::QpxExpressAgent do +describe Agents::QpxAgent do before do stub_request(:get, "https://www.googleapis.com/qpxExpress/v1/trips/search").to_return( - :body => File.read(Rails.root.join("spec/data_fixtures/qpx_express.json")), + :body => File.read(Rails.root.join("spec/data_fixtures/qpx.json")), :status => 200, :headers => {"Content-Type" => "application/json"} ) @opts = { - "qpx_api_key" => '800deeaf-e285-9d62-bc90-j999c1973cc9' + 'qpx_api_key' => '800deeaf-e285-9d62-bc90-j999c1973cc9', + 'adultCount' => 1, + 'origin' => 'BOS', + 'destination' => 'SFO', + 'date' => '2016-04-11', + 'childCount' => 0, + 'infantInSeatCount' => 0, + 'infantInLapCount'=> 0, + 'seniorCount'=> 0, + 'refundable' => false, + 'solutions'=> 3 } - @checker = Agents::QpxExpressAgent.new(:name => "tectonic", :options => @opts) + @checker = Agents::QpxAgent.new(:name => "tectonic", :options => @opts) @checker.user = users(:bob) @checker.save! end describe '#helpers' do - it "should return the correct request header" do - expect(@checker.send(:request_options)).to eq({:headers => {"Content-Type"=>"application/json"}}) - end - it "should generate the correct events url" do - expect(@checker.send(:event_url)).to eq("https://www.googleapis.com/qpxExpress/v1/trips/search?key") + expect(@checker.send(:event_url)).to eq("https://www.googleapis.com/qpxExpress/v1/trips/search?key=800deeaf-e285-9d62-bc90-j999c1973cc9") end end @@ -37,11 +43,61 @@ describe Agents::QpxExpressAgent do @checker.options['qpx_api_key'] = nil expect(@checker).not_to be_valid end + + it "should require adultCount" do + @checker.options['adultCount'] = nil + expect(@checker).not_to be_valid + end + + it "should require Origin" do + @checker.options['origin'] = nil + expect(@checker).not_to be_valid + end + + it "should require Destination" do + @checker.options['destination'] = nil + expect(@checker).not_to be_valid + end + + it "should require Date" do + @checker.options['date'] = nil + expect(@checker).not_to be_valid + end + + it "should require childCount" do + @checker.options['childCount'] = nil + expect(@checker).not_to be_valid + end + + it "should require Infant In Seat Count" do + @checker.options['infantInSeatCount'] = nil + expect(@checker).not_to be_valid + end + + it "should require Infant In Lab Count" do + @checker.options['infantInLapCount'] = nil + expect(@checker).not_to be_valid + end + + it "should require Senior Count" do + @checker.options['seniorCount'] = nil + expect(@checker).not_to be_valid + end + + it "should require Solutions" 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[:last_updated_at] = '2016-03-15T14:01:05+00:00' + @checker.memory[:latestTicketingTime] = '2016-03-18T23:59-04:00' expect { @checker.check }.to change { Event.count }.by(1) end end