Browse files

Merge pull request #43 from jbrowning/better-status

Detailed shipment status information for UPS and FedEx
  • Loading branch information...
2 parents 89983d5 + 6f52e39 commit affddc84b289c1f4043e4f277cebf65fa4b6916f @csaunders csaunders committed May 31, 2012
View
65 lib/active_shipping/shipping/carriers/fedex.rb
@@ -85,6 +85,42 @@ class FedEx < Carrier
'express_mps_master' => 'EXPRESS_MPS_MASTER'
}
+ # FedEx tracking codes as described in the FedEx Tracking Service WSDL Guide
+ # All delays also have been marked as exceptions
+ TRACKING_STATUS_CODES = HashWithIndifferentAccess.new({
+ 'AA' => :at_airport,
+ 'AD' => :at_delivery,
+ 'AF' => :at_fedex_facility,
+ 'AR' => :at_fedex_facility,
+ 'AP' => :at_pickup,
+ 'CA' => :canceled,
+ 'CH' => :location_changed,
+ 'DE' => :exception,
+ 'DL' => :delivered,
+ 'DP' => :departed_fedex_location,
+ 'DR' => :vehicle_furnished_not_used,
+ 'DS' => :vehicle_dispatched,
+ 'DY' => :exception,
+ 'EA' => :exception,
+ 'ED' => :enroute_to_delivery,
+ 'EO' => :enroute_to_origin_airport,
+ 'EP' => :enroute_to_pickup,
+ 'FD' => :at_fedex_destination,
+ 'HL' => :held_at_location,
+ 'IT' => :in_transit,
+ 'LO' => :left_origin,
+ 'OC' => :order_created,
+ 'OD' => :out_for_delivery,
+ 'PF' => :plane_in_flight,
+ 'PL' => :plane_landed,
+ 'PU' => :picked_up,
+ 'RS' => :return_to_shipper,
+ 'SE' => :exception,
+ 'SF' => :at_sort_facility,
+ 'SP' => :split_status,
+ 'TR' => :transfer
+ })
+
def self.service_name_for_code(service_code)
ServiceTypes[service_code] || "FedEx #{service_code.titleize.sub(/Fedex /, '')}"
end
@@ -262,13 +298,32 @@ def parse_tracking_response(response, options)
message = response_message(xml)
if success
- tracking_number, origin, destination = nil
+ tracking_number, origin, destination, status, status_code, status_description = nil
shipment_events = []
-
+
tracking_details = root_node.elements['TrackDetails']
tracking_number = tracking_details.get_text('TrackingNumber').to_s
+ status_code = tracking_details.get_text('StatusCode').to_s
+ status_description = tracking_details.get_text('StatusDescription').to_s
+ status = TRACKING_STATUS_CODES[status_code]
+
+ origin_node = tracking_details.elements['OriginLocationAddress']
+
+ if origin_node
+ origin = Location.new(
+ :country => origin_node.get_text('CountryCode').to_s,
+ :province => origin_node.get_text('StateOrProvinceCode').to_s,
+ :city => origin_node.get_text('City').to_s
+ )
+ end
+
destination_node = tracking_details.elements['DestinationAddress']
+
+ if destination_node.nil?
+ destination_node = tracking_details.elements['ActualDeliveryAddress']
+ end
+
destination = Location.new(
:country => destination_node.get_text('CountryCode').to_s,
:province => destination_node.get_text('StateOrProvinceCode').to_s,
@@ -294,12 +349,18 @@ def parse_tracking_response(response, options)
shipment_events << ShipmentEvent.new(description, zoneless_time, location)
end
shipment_events = shipment_events.sort_by(&:time)
+
end
TrackingResponse.new(success, message, Hash.from_xml(response),
+ :carrier => @@name,
:xml => response,
:request => last_request,
+ :status => status,
+ :status_code => status_code,
+ :status_description => status_description,
:shipment_events => shipment_events,
+ :origin => origin,
:destination => destination,
:tracking_number => tracking_number
)
View
74 lib/active_shipping/shipping/carriers/ups.rb
@@ -26,13 +26,13 @@ class UPS < Carrier
:letter_center => "19",
:air_service_center => "20"
})
-
+
CUSTOMER_CLASSIFICATIONS = HashWithIndifferentAccess.new({
:wholesale => "01",
:occasional => "03",
:retail => "04"
})
-
+
# these are the defaults described in the UPS API docs,
# but they don't seem to apply them under all circumstances,
# so we need to take matters into our own hands
@@ -85,7 +85,15 @@ class UPS < Carrier
OTHER_NON_US_ORIGIN_SERVICES = {
"07" => "UPS Express"
}
-
+
+ TRACKING_STATUS_CODES = HashWithIndifferentAccess.new({
+ 'I' => :in_transit,
+ 'D' => :delivered,
+ 'X' => :exception,
+ 'P' => :pickup,
+ 'M' => :manifest_pickup
+ })
+
# From http://en.wikipedia.org/w/index.php?title=European_Union&oldid=174718707 (Current as of November 30, 2007)
EU_COUNTRY_CODES = ["GB", "AT", "BE", "BG", "CY", "CZ", "DK", "EE", "FI", "FR", "DE", "GR", "HU", "IE", "IT", "LV", "LT", "LU", "MT", "NL", "PL", "PT", "RO", "SK", "SI", "ES", "SE"]
@@ -296,17 +304,39 @@ def parse_tracking_response(response, options={})
message = response_message(xml)
if success
- tracking_number, origin, destination = nil
+ tracking_number, origin, destination, status_code, status_description = nil
+ delivered, exception = false
+ exception_event = nil
shipment_events = []
-
+ status = {}
+ scheduled_delivery_date = nil
+
first_shipment = xml.elements['/*/Shipment']
first_package = first_shipment.elements['Package']
tracking_number = first_shipment.get_text('ShipmentIdentificationNumber | Package/TrackingNumber').to_s
+ # Build status hash
+ status_node = first_package.elements['Activity/Status/StatusType']
+ status_code = status_node.get_text('Code').to_s
+ status_description = status_node.get_text('Description').to_s
+ status = TRACKING_STATUS_CODES[status_code]
+
+ if status_description =~ /out.*delivery/i
+ status = :out_for_delivery
+ end
+
origin, destination = %w{Shipper ShipTo}.map do |location|
location_from_address_node(first_shipment.elements["#{location}/Address"])
end
-
+
+ # Get scheduled delivery date
+ unless status == :delivered
+ scheduled_delivery_date = parse_ups_datetime({
+ :date => first_shipment.get_text('ScheduledDeliveryDate'),
+ :time => nil
+ })
+ end
+
activities = first_package.get_elements('Activity')
unless activities.empty?
shipment_events = activities.map do |activity|
@@ -324,7 +354,10 @@ def parse_tracking_response(response, options={})
shipment_events = shipment_events.sort_by(&:time)
- if origin
+ # UPS will sometimes archive a shipment, stripping all shipment activity except for the delivery
+ # event (see test/fixtures/xml/delivered_shipment_without_events_tracking_response.xml for an example).
+ # This adds an origin event to the shipment activity in such cases.
+ if origin && !(shipment_events.count == 1 && status == :delivered)
first_event = shipment_events[0]
same_country = origin.country_code(:alpha2) == first_event.location.country_code(:alpha2)
same_or_blank_city = first_event.location.city.blank? or first_event.location.city == origin.city
@@ -335,16 +368,29 @@ def parse_tracking_response(response, options={})
shipment_events.unshift(origin_event)
end
end
- if shipment_events.last.name.downcase == 'delivered'
+
+ # Has the shipment been delivered?
+ if status == :delivered
+ if !destination
+ destination = shipment_events[-1].location
+ end
shipment_events[-1] = ShipmentEvent.new(shipment_events.last.name, shipment_events.last.time, destination)
end
end
end
TrackingResponse.new(success, message, Hash.from_xml(response).values.first,
+ :carrier => @@name,
:xml => response,
:request => last_request,
+ :status => status,
+ :status_code => status_code,
+ :status_description => status_description,
+ :scheduled_delivery_date => scheduled_delivery_date,
:shipment_events => shipment_events,
+ :delivered => delivered,
+ :exception => exception,
+ :exception_event => exception_event,
:origin => origin,
:destination => destination,
:tracking_number => tracking_number)
@@ -363,6 +409,18 @@ def location_from_address_node(address)
)
end
+ def parse_ups_datetime(options = {})
+ time, date = options[:time].to_s, options[:date].to_s
+ if time.nil?
+ hour, minute, second = 0
+ else
+ hour, minute, second = time.scan(/\d{2}/)
+ end
+ year, month, day = date[0..3], date[4..5], date[6..7]
+
+ Time.utc(year, month, day, hour, minute, second)
+ end
+
def response_success?(xml)
xml.get_text('/*/Response/ResponseStatusCode').to_s == '1'
end
View
12 lib/active_shipping/shipping/location.rb
@@ -131,6 +131,18 @@ def inspect
string << "\nFax: #{@fax}" unless @fax.blank?
string
end
+
+ # Returns the postal code as a properly formatted Zip+4 code, e.g. "77095-2233"
+ def zip_plus_4
+ if /(?<zip>\d{5})(?<plus_4>\d{4})/ =~ @postal_code
+ return "#{zip}-#{plus_4}"
+ elsif /\d{5}-\d{4}/ =~ @postal_code
+ return @postal_code
+ else
+ nil
+ end
+ end
+
end
end
View
27 lib/active_shipping/shipping/tracking_response.rb
@@ -2,20 +2,45 @@ module ActiveMerchant #:nodoc:
module Shipping
class TrackingResponse < Response
+ attr_reader :carrier # symbol
+ attr_reader :carrier_name # string
+ attr_reader :status # symbol
+ attr_reader :status_code # string
+ attr_reader :status_description #string
+ attr_reader :scheduled_delivery_date # time
attr_reader :tracking_number # string
attr_reader :shipment_events # array of ShipmentEvents in chronological order
attr_reader :origin, :destination
def initialize(success, message, params = {}, options = {})
+ @carrier = options[:carrier].parameterize.to_sym
+ @carrier_name = options[:carrier]
+ @status = options[:status]
+ @status_code = options[:status_code]
+ @status_description = options[:status_description]
+ @scheduled_delivery_date = options[:scheduled_delivery_date]
@tracking_number = options[:tracking_number]
@shipment_events = Array(options[:shipment_events])
@origin, @destination = options[:origin], options[:destination]
super
end
-
+
def latest_event
@shipment_events.last
end
+
+ def is_delivered?
+ @status == :delivered
+ end
+
+ def has_exception?
+ @status == :exception
+ end
+
+ alias_method(:exception_event, :latest_event)
+ alias_method(:delivered?, :is_delivered?)
+ alias_method(:exception?, :has_exception?)
+
end
end
View
62 test/fixtures/xml/ups/delivered_shipment_without_events_tracking_response.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<TrackResponse>
+ <Response>
+ <ResponseStatusCode>1</ResponseStatusCode>
+ <ResponseStatusDescription>Success</ResponseStatusDescription>
+ </Response>
+ <Shipment>
+ <Shipper>
+ <ShipperNumber>A7226W</ShipperNumber>
+ <Address>
+ <AddressLine1>1 AMAZON WAY</AddressLine1>
+ <City>COFFEYVILLE</City>
+ <StateProvinceCode>KS</StateProvinceCode>
+ <PostalCode>67337</PostalCode>
+ <CountryCode>US</CountryCode>
+ </Address>
+ </Shipper>
+ <ShipmentWeight>
+ <UnitOfMeasurement>
+ <Code>LBS</Code>
+ </UnitOfMeasurement>
+ <Weight>0.00</Weight>
+ </ShipmentWeight>
+ <Service>
+ <Code>13</Code>
+ <Description>UPS NEXT DAY AIR SAVER</Description>
+ </Service>
+ <ShipmentIdentificationNumber>1ZA7226W1388491331</ShipmentIdentificationNumber>
+ <Package>
+ <TrackingNumber>1ZA7226W1388491331</TrackingNumber>
+ <Activity>
+ <ActivityLocation>
+ <Address>
+ <City>CYPRESS</City>
+ <StateProvinceCode>TX</StateProvinceCode>
+ <PostalCode>77433</PostalCode>
+ <CountryCode>US</CountryCode>
+ </Address>
+ <Code>MQ</Code>
+ <Description>PORCH</Description>
+ </ActivityLocation>
+ <Status>
+ <StatusType>
+ <Code>D</Code>
+ <Description>DELIVERED</Description>
+ </StatusType>
+ <StatusCode>
+ <Code>FS</Code>
+ </StatusCode>
+ </Status>
+ <Date>20110617</Date>
+ <Time>134500</Time>
+ </Activity>
+ <PackageWeight>
+ <UnitOfMeasurement>
+ <Code>LBS</Code>
+ </UnitOfMeasurement>
+ <Weight>0.00</Weight>
+ </PackageWeight>
+ </Package>
+ </Shipment>
+</TrackResponse>
View
183 test/fixtures/xml/ups/in_transit_shipment.xml
@@ -0,0 +1,183 @@
+<?xml version="1.0"?>
+<TrackResponse>
+ <Response>
+ <ResponseStatusCode>1</ResponseStatusCode>
+ <ResponseStatusDescription>Success</ResponseStatusDescription>
+ </Response>
+ <Shipment>
+ <Shipper>
+ <ShipperNumber>4F940A</ShipperNumber>
+ <Address>
+ <AddressLine1>1600 WORLDWIDE BLVD</AddressLine1>
+ <City>HEBRON</City>
+ <StateProvinceCode>KY</StateProvinceCode>
+ <PostalCode>41048 8640</PostalCode>
+ <CountryCode>US</CountryCode>
+ </Address>
+ </Shipper>
+ <ShipTo>
+ <Address>
+ <City>CYPRESS</City>
+ <StateProvinceCode>TX</StateProvinceCode>
+ <PostalCode>774332681</PostalCode>
+ <CountryCode>US</CountryCode>
+ </Address>
+ </ShipTo>
+ <ShipmentWeight>
+ <UnitOfMeasurement>
+ <Code>LBS</Code>
+ </UnitOfMeasurement>
+ <Weight>5.40</Weight>
+ </ShipmentWeight>
+ <Service>
+ <Code>002</Code>
+ <Description>2ND DAY AIR</Description>
+ </Service>
+ <ReferenceNumber>
+ <Code>01</Code>
+ <Value>62093047</Value>
+ </ReferenceNumber>
+ <ShipmentIdentificationNumber>1Z4F940A0266088694</ShipmentIdentificationNumber>
+ <PickupDate>20110822</PickupDate>
+ <ScheduledDeliveryDate>20110824</ScheduledDeliveryDate>
+ <Package>
+ <TrackingNumber>1Z4F940A0266088694</TrackingNumber>
+ <Activity>
+ <ActivityLocation>
+ <Address>
+ <City>LOUISVILLE</City>
+ <StateProvinceCode>KY</StateProvinceCode>
+ <CountryCode>US</CountryCode>
+ </Address>
+ </ActivityLocation>
+ <Status>
+ <StatusType>
+ <Code>I</Code>
+ <Description>ARRIVAL SCAN</Description>
+ </StatusType>
+ <StatusCode>
+ <Code>AR</Code>
+ </StatusCode>
+ </Status>
+ <Date>20110823</Date>
+ <Time>063800</Time>
+ </Activity>
+ <Activity>
+ <ActivityLocation>
+ <Address>
+ <City>SHARONVILLE</City>
+ <StateProvinceCode>OH</StateProvinceCode>
+ <CountryCode>US</CountryCode>
+ </Address>
+ </ActivityLocation>
+ <Status>
+ <StatusType>
+ <Code>I</Code>
+ <Description>DEPARTURE SCAN</Description>
+ </StatusType>
+ <StatusCode>
+ <Code>DP</Code>
+ </StatusCode>
+ </Status>
+ <Date>20110823</Date>
+ <Time>041500</Time>
+ </Activity>
+ <Activity>
+ <ActivityLocation>
+ <Address>
+ <City>SHARONVILLE</City>
+ <StateProvinceCode>OH</StateProvinceCode>
+ <CountryCode>US</CountryCode>
+ </Address>
+ </ActivityLocation>
+ <Status>
+ <StatusType>
+ <Code>I</Code>
+ <Description>ARRIVAL SCAN</Description>
+ </StatusType>
+ <StatusCode>
+ <Code>AR</Code>
+ </StatusCode>
+ </Status>
+ <Date>20110823</Date>
+ <Time>005700</Time>
+ </Activity>
+ <Activity>
+ <ActivityLocation>
+ <Address>
+ <City>CINCINNATI</City>
+ <StateProvinceCode>OH</StateProvinceCode>
+ <CountryCode>US</CountryCode>
+ </Address>
+ </ActivityLocation>
+ <Status>
+ <StatusType>
+ <Code>I</Code>
+ <Description>DEPARTURE SCAN</Description>
+ </StatusType>
+ <StatusCode>
+ <Code>DP</Code>
+ </StatusCode>
+ </Status>
+ <Date>20110823</Date>
+ <Time>003200</Time>
+ </Activity>
+ <Activity>
+ <ActivityLocation>
+ <Address>
+ <City>CINCINNATI</City>
+ <StateProvinceCode>OH</StateProvinceCode>
+ <CountryCode>US</CountryCode>
+ </Address>
+ </ActivityLocation>
+ <Status>
+ <StatusType>
+ <Code>I</Code>
+ <Description>ORIGIN SCAN</Description>
+ </StatusType>
+ <StatusCode>
+ <Code>OR</Code>
+ </StatusCode>
+ </Status>
+ <Date>20110822</Date>
+ <Time>190100</Time>
+ </Activity>
+ <Activity>
+ <ActivityLocation>
+ <Address>
+ <CountryCode>US</CountryCode>
+ </Address>
+ </ActivityLocation>
+ <Status>
+ <StatusType>
+ <Code>M</Code>
+ <Description>BILLING INFORMATION RECEIVED</Description>
+ </StatusType>
+ <StatusCode>
+ <Code>MP</Code>
+ </StatusCode>
+ </Status>
+ <Date>20110822</Date>
+ <Time>172303</Time>
+ </Activity>
+ <Message>
+ <Code>01</Code>
+ <Description>On Time</Description>
+ </Message>
+ <PackageWeight>
+ <UnitOfMeasurement>
+ <Code>LBS</Code>
+ </UnitOfMeasurement>
+ <Weight>5.40</Weight>
+ </PackageWeight>
+ <ReferenceNumber>
+ <Code>01</Code>
+ <Value>FN3-6732456-0526660</Value>
+ </ReferenceNumber>
+ <ReferenceNumber>
+ <Code>01</Code>
+ <Value>DZWHLCGPR</Value>
+ </ReferenceNumber>
+ </Package>
+ </Shipment>
+</TrackResponse>
View
165 test/fixtures/xml/ups/out_for_delivery_shipment.xml
@@ -0,0 +1,165 @@
+<?xml version="1.0"?>
+<TrackResponse>
+ <Response>
+ <ResponseStatusCode>1</ResponseStatusCode>
+ <ResponseStatusDescription>Success</ResponseStatusDescription>
+ </Response>
+ <Shipment>
+ <Shipper>
+ <ShipperNumber>W22A28</ShipperNumber>
+ <Address>
+ <AddressLine1>1050 S COLUMBIA AVE</AddressLine1>
+ <City>CAMPBELLSVILLE</City>
+ <StateProvinceCode>KY</StateProvinceCode>
+ <PostalCode>42718 2454</PostalCode>
+ <CountryCode>US</CountryCode>
+ </Address>
+ </Shipper>
+ <ShipTo>
+ <Address>
+ <City>CYPRESS</City>
+ <StateProvinceCode>TX</StateProvinceCode>
+ <PostalCode>774332681</PostalCode>
+ <CountryCode>US</CountryCode>
+ </Address>
+ </ShipTo>
+ <ShipmentWeight>
+ <UnitOfMeasurement>
+ <Code>LBS</Code>
+ </UnitOfMeasurement>
+ <Weight>1.20</Weight>
+ </ShipmentWeight>
+ <Service>
+ <Code>003</Code>
+ <Description>GROUND</Description>
+ </Service>
+ <ReferenceNumber>
+ <Code>01</Code>
+ <Value>643293013</Value>
+ </ReferenceNumber>
+ <ShipmentIdentificationNumber>
+ 1ZW22A280305086608</ShipmentIdentificationNumber>
+ <PickupDate>20120508</PickupDate>
+ <ScheduledDeliveryDate>20120511</ScheduledDeliveryDate>
+ <Package>
+ <TrackingNumber>1ZW22A280305086608</TrackingNumber>
+ <RescheduledDeliveryDate>20120510</RescheduledDeliveryDate>
+ <Activity>
+ <ActivityLocation>
+ <Address>
+ <City>STAFFORD</City>
+ <StateProvinceCode>TX</StateProvinceCode>
+ <CountryCode>US</CountryCode>
+ </Address>
+ </ActivityLocation>
+ <Status>
+ <StatusType>
+ <Code>I</Code>
+ <Description>OUT FOR DELIVERY</Description>
+ </StatusType>
+ <StatusCode>
+ <Code>DS</Code>
+ </StatusCode>
+ </Status>
+ <Date>20120510</Date>
+ <Time>043400</Time>
+ </Activity>
+ <Activity>
+ <ActivityLocation>
+ <Address>
+ <City>STAFFORD</City>
+ <StateProvinceCode>TX</StateProvinceCode>
+ <CountryCode>US</CountryCode>
+ </Address>
+ </ActivityLocation>
+ <Status>
+ <StatusType>
+ <Code>I</Code>
+ <Description>ARRIVAL SCAN</Description>
+ </StatusType>
+ <StatusCode>
+ <Code>AR</Code>
+ </StatusCode>
+ </Status>
+ <Date>20120510</Date>
+ <Time>000200</Time>
+ </Activity>
+ <Activity>
+ <ActivityLocation>
+ <Address>
+ <City>MESQUITE</City>
+ <StateProvinceCode>TX</StateProvinceCode>
+ <CountryCode>US</CountryCode>
+ </Address>
+ </ActivityLocation>
+ <Status>
+ <StatusType>
+ <Code>I</Code>
+ <Description>DEPARTURE SCAN</Description>
+ </StatusType>
+ <StatusCode>
+ <Code>DP</Code>
+ </StatusCode>
+ </Status>
+ <Date>20120509</Date>
+ <Time>200300</Time>
+ </Activity>
+ <Activity>
+ <ActivityLocation>
+ <Address>
+ <City>MESQUITE</City>
+ <StateProvinceCode>TX</StateProvinceCode>
+ <CountryCode>US</CountryCode>
+ </Address>
+ </ActivityLocation>
+ <Status>
+ <StatusType>
+ <Code>I</Code>
+ <Description>ORIGIN SCAN</Description>
+ </StatusType>
+ <StatusCode>
+ <Code>OR</Code>
+ </StatusCode>
+ </Status>
+ <Date>20120509</Date>
+ <Time>141800</Time>
+ </Activity>
+ <Activity>
+ <ActivityLocation>
+ <Address>
+ <CountryCode>US</CountryCode>
+ </Address>
+ </ActivityLocation>
+ <Status>
+ <StatusType>
+ <Code>M</Code>
+ <Description>BILLING INFORMATION RECEIVED</Description>
+ </StatusType>
+ <StatusCode>
+ <Code>MP</Code>
+ </StatusCode>
+ </Status>
+ <Date>20120508</Date>
+ <Time>230354</Time>
+ </Activity>
+ <Message>
+ <Code>02</Code>
+ <Description>Rescheduled</Description>
+ </Message>
+ <PackageWeight>
+ <UnitOfMeasurement>
+ <Code>LBS</Code>
+ </UnitOfMeasurement>
+ <Weight>1.20</Weight>
+ </PackageWeight>
+ <ReferenceNumber>
+ <Code>01</Code>
+ <Value>FN3-4603152-0261546</Value>
+ </ReferenceNumber>
+ <ReferenceNumber>
+ <Code>01</Code>
+ <Value>DTG4MDX2R</Value>
+ </ReferenceNumber>
+ </Package>
+ </Shipment>
+</TrackResponse>
View
6 test/remote/fedex_test.rb
@@ -132,6 +132,12 @@ def test_tracking
end
end
+ def test_tracking_with_bad_number
+ assert_raises ResponseError do
+ response = @carrier.find_tracking_info('12345')
+ end
+ end
+
def test_different_rates_for_commercial
residential_response = @carrier.find_rates(
@locations[:beverly_hills],
View
55 test/unit/carriers/fedex_test.rb
@@ -5,6 +5,7 @@ def setup
@packages = TestFixtures.packages
@locations = TestFixtures.locations
@carrier = FedEx.new(:key => '1111', :password => '2222', :account => '3333', :login => '4444')
+ @tracking_response = xml_fixture('fedex/tracking_response')
end
def test_initialize_options_requirements
@@ -26,24 +27,68 @@ def test_initialize_options_requirements
# end
def test_find_tracking_info_should_return_a_tracking_response
- @carrier.expects(:commit).returns(xml_fixture('fedex/tracking_response'))
+ @carrier.expects(:commit).returns(@tracking_response)
assert_instance_of ActiveMerchant::Shipping::TrackingResponse, @carrier.find_tracking_info('077973360403984', :test => true)
end
+ def test_find_tracking_info_should_mark_shipment_as_delivered
+ @carrier.expects(:commit).returns(@tracking_response)
+ assert_equal true, @carrier.find_tracking_info('077973360403984').delivered?
+ end
+
+ def test_find_tracking_info_should_return_correct_carrier
+ @carrier.expects(:commit).returns(@tracking_response)
+ assert_equal :fedex, @carrier.find_tracking_info('077973360403984').carrier
+ end
+
+ def test_find_tracking_info_should_return_correct_carrier_name
+ @carrier.expects(:commit).returns(@tracking_response)
+ assert_equal 'FedEx', @carrier.find_tracking_info('077973360403984').carrier_name
+ end
+
+ def test_find_tracking_info_should_return_correct_status
+ @carrier.expects(:commit).returns(@tracking_response)
+ assert_equal :delivered, @carrier.find_tracking_info('077973360403984').status
+ end
+
+ def test_find_tracking_info_should_return_correct_status_code
+ @carrier.expects(:commit).returns(@tracking_response)
+ assert_equal 'dl', @carrier.find_tracking_info('077973360403984').status_code.downcase
+ end
+
+ def test_find_tracking_info_should_return_correct_status_description
+ @carrier.expects(:commit).returns(@tracking_response)
+ assert_equal 'delivered', @carrier.find_tracking_info('1Z5FX0076803466397').status_description.downcase
+ end
+
+ def test_find_tracking_info_should_return_destination_address
+ @carrier.expects(:commit).returns(@tracking_response)
+ result = @carrier.find_tracking_info('077973360403984')
+ assert_equal 'sacramento', result.destination.city.downcase
+ assert_equal 'CA', result.destination.state
+ end
+
+ def test_find_tracking_info_should_return_origin_address
+ @carrier.expects(:commit).returns(@tracking_response)
+ result = @carrier.find_tracking_info('077973360403984')
+ assert_equal 'nashville', result.origin.city.downcase
+ assert_equal 'TN', result.origin.state
+ end
+
def test_find_tracking_info_should_parse_response_into_correct_number_of_shipment_events
- @carrier.expects(:commit).returns(xml_fixture('fedex/tracking_response'))
+ @carrier.expects(:commit).returns(@tracking_response)
response = @carrier.find_tracking_info('077973360403984', :test => true)
assert_equal 6, response.shipment_events.size
end
def test_find_tracking_info_should_return_shipment_events_in_ascending_chronological_order
- @carrier.expects(:commit).returns(xml_fixture('fedex/tracking_response'))
+ @carrier.expects(:commit).returns(@tracking_response)
response = @carrier.find_tracking_info('077973360403984', :test => true)
assert_equal response.shipment_events.map(&:time).sort, response.shipment_events.map(&:time)
end
-
+
def test_find_tracking_info_should_not_include_events_without_an_address
- @carrier.expects(:commit).returns(xml_fixture('fedex/tracking_response'))
+ @carrier.expects(:commit).returns(@tracking_response)
assert_nothing_raised do
response = @carrier.find_tracking_info('077973360403984', :test => true)
assert_nil response.shipment_events.find{|event| event.name == 'Shipment information sent to FedEx' }
View
62 test/unit/carriers/ups_test.rb
@@ -11,6 +11,7 @@ def setup
:password => 'password'
)
@tracking_response = xml_fixture('ups/shipment_from_tiger_direct')
+
end
def test_initialize_options_requirements
@@ -26,6 +27,64 @@ def test_find_tracking_info_should_return_a_tracking_response
assert_equal 'ActiveMerchant::Shipping::TrackingResponse', @carrier.find_tracking_info('1Z5FX0076803466397').class.name
end
+ def test_find_tracking_info_should_mark_shipment_as_delivered
+ @carrier.expects(:commit).returns(@tracking_response)
+ assert_equal true, @carrier.find_tracking_info('1Z5FX0076803466397').delivered?
+ end
+
+ def test_find_tracking_info_should_return_correct_carrier
+ @carrier.expects(:commit).returns(@tracking_response)
+ assert_equal :ups, @carrier.find_tracking_info('1Z5FX0076803466397').carrier
+ end
+
+ def test_find_tracking_info_should_return_correct_carrier_name
+ @carrier.expects(:commit).returns(@tracking_response)
+ assert_equal 'UPS', @carrier.find_tracking_info('1Z5FX0076803466397').carrier_name
+ end
+
+ def test_find_tracking_info_should_return_correct_status
+ @carrier.expects(:commit).returns(@tracking_response)
+ assert_equal :delivered, @carrier.find_tracking_info('1Z5FX0076803466397').status
+ end
+
+ def test_find_tracking_info_should_return_correct_status_code
+ @carrier.expects(:commit).returns(@tracking_response)
+ assert_equal 'd', @carrier.find_tracking_info('1Z5FX0076803466397').status_code.downcase
+ end
+
+ def test_find_tracking_info_should_return_correct_status_description
+ @carrier.expects(:commit).returns(@tracking_response)
+ assert_equal 'delivered', @carrier.find_tracking_info('1Z5FX0076803466397').status_description.downcase
+ end
+
+ def test_find_tracking_info_should_have_an_out_for_delivery_status
+ out_for_delivery_tracking_response = xml_fixture('ups/out_for_delivery_shipment')
+ @carrier.expects(:commit).returns(out_for_delivery_tracking_response)
+ assert_equal :out_for_delivery, @carrier.find_tracking_info('1Z5FX0076803466397').status
+ end
+
+ def test_find_tracking_info_should_return_destination_address
+ @carrier.expects(:commit).returns(@tracking_response)
+ result = @carrier.find_tracking_info('1Z5FX0076803466397')
+ assert_equal 'ottawa', result.destination.city.downcase
+ assert_equal 'ON', result.destination.state
+ end
+
+ def test_find_tracking_info_should_return_destination_address_for_abbreviated_response
+ tracking_response = xml_fixture('ups/delivered_shipment_without_events_tracking_response')
+ @carrier.expects(:commit).returns(tracking_response)
+ result = @carrier.find_tracking_info('1Z5FX0076803466397')
+ assert_equal 'cypress', result.destination.city.downcase
+ assert_equal 'TX', result.destination.state
+ end
+
+ def test_find_tracking_info_should_return_origin_address
+ @carrier.expects(:commit).returns(@tracking_response)
+ result = @carrier.find_tracking_info('1Z5FX0076803466397')
+ assert_equal 'naperville', result.origin.city.downcase
+ assert_equal 'IL', result.origin.state
+ end
+
def test_find_tracking_info_should_parse_response_into_correct_number_of_shipment_events
@carrier.expects(:commit).returns(@tracking_response)
response = @carrier.find_tracking_info('1Z5FX0076803466397')
@@ -50,7 +109,8 @@ def test_find_tracking_info_should_have_correct_names_for_shipment_events
"OUT FOR DELIVERY",
"DELIVERED" ], response.shipment_events.map(&:name)
end
-
+
+
def test_add_origin_and_destination_data_to_shipment_events_where_appropriate
@carrier.expects(:commit).returns(@tracking_response)
response = @carrier.find_tracking_info('1Z5FX0076803466397')
View
16 test/unit/location_test.rb
@@ -98,4 +98,20 @@ def test_custom_root_to_xml
location_xml = @locations[:ottawa].to_xml(:root => "destination")
assert_equal @locations[:ottawa].to_hash, Hash.from_xml(location_xml)["destination"].symbolize_keys
end
+
+ def test_zip_plus_4_with_no_dash
+ zip = "33333"
+ plus_4 = "1234"
+ zip_plus_4 = "#{zip}-#{plus_4}"
+ location = Location.from(:zip => "#{zip}#{plus_4}")
+ assert_equal zip_plus_4, location.zip_plus_4
+ end
+
+ def test_zip_plus_4_with_dash
+ zip = "33333"
+ plus_4 = "1234"
+ zip_plus_4 = "#{zip}-#{plus_4}"
+ location = Location.from(:zip => zip_plus_4)
+ assert_equal zip_plus_4, location.zip_plus_4
+ end
end

0 comments on commit affddc8

Please sign in to comment.