reactive_shipping 3.0.0
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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.travis.yml +33 -0
- data/.yardopts +13 -0
- data/CHANGELOG.md +225 -0
- data/CONTRIBUTING.md +23 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +21 -0
- data/README.md +158 -0
- data/Rakefile +35 -0
- data/dev.yml +17 -0
- data/gemfiles/activesupport42.gemfile +5 -0
- data/gemfiles/activesupport50.gemfile +6 -0
- data/gemfiles/activesupport51.gemfile +5 -0
- data/gemfiles/activesupport52.gemfile +5 -0
- data/gemfiles/activesupport_master.gemfile +5 -0
- data/lib/certs/eParcel.dtd +111 -0
- data/lib/reactive_shipping.rb +26 -0
- data/lib/reactive_shipping/address_validation_response.rb +30 -0
- data/lib/reactive_shipping/carrier.rb +184 -0
- data/lib/reactive_shipping/carriers.rb +35 -0
- data/lib/reactive_shipping/carriers/australia_post.rb +248 -0
- data/lib/reactive_shipping/carriers/benchmark_carrier.rb +31 -0
- data/lib/reactive_shipping/carriers/bogus_carrier.rb +12 -0
- data/lib/reactive_shipping/carriers/canada_post.rb +263 -0
- data/lib/reactive_shipping/carriers/canada_post_pws.rb +908 -0
- data/lib/reactive_shipping/carriers/fedex.rb +797 -0
- data/lib/reactive_shipping/carriers/kunaki.rb +155 -0
- data/lib/reactive_shipping/carriers/new_zealand_post.rb +260 -0
- data/lib/reactive_shipping/carriers/shipwire.rb +178 -0
- data/lib/reactive_shipping/carriers/stamps.rb +860 -0
- data/lib/reactive_shipping/carriers/ups.rb +1060 -0
- data/lib/reactive_shipping/carriers/usps.rb +708 -0
- data/lib/reactive_shipping/carriers/usps_returns.rb +86 -0
- data/lib/reactive_shipping/delivery_date_estimate.rb +20 -0
- data/lib/reactive_shipping/delivery_date_estimates_response.rb +11 -0
- data/lib/reactive_shipping/errors.rb +35 -0
- data/lib/reactive_shipping/external_return_label_request.rb +417 -0
- data/lib/reactive_shipping/external_return_label_response.rb +26 -0
- data/lib/reactive_shipping/label.rb +10 -0
- data/lib/reactive_shipping/label_response.rb +10 -0
- data/lib/reactive_shipping/location.rb +166 -0
- data/lib/reactive_shipping/package.rb +165 -0
- data/lib/reactive_shipping/package_item.rb +60 -0
- data/lib/reactive_shipping/rate_estimate.rb +197 -0
- data/lib/reactive_shipping/rate_response.rb +33 -0
- data/lib/reactive_shipping/response.rb +44 -0
- data/lib/reactive_shipping/shipment_event.rb +22 -0
- data/lib/reactive_shipping/shipment_packer.rb +108 -0
- data/lib/reactive_shipping/shipping_response.rb +34 -0
- data/lib/reactive_shipping/tracking_response.rb +120 -0
- data/lib/reactive_shipping/version.rb +3 -0
- data/reactive_shipping.gemspec +38 -0
- data/shipit.rubygems.yml +1 -0
- data/test/console.rb +39 -0
- data/test/credentials.yml +76 -0
- data/test/fixtures/files/label1.pdf +0 -0
- data/test/fixtures/files/ups-shipping-label.gif +0 -0
- data/test/fixtures/json/australia_post/calculate_domestic.json +13 -0
- data/test/fixtures/json/australia_post/calculate_domestic_2.json +19 -0
- data/test/fixtures/json/australia_post/calculate_international.json +12 -0
- data/test/fixtures/json/australia_post/calculate_international_2.json +15 -0
- data/test/fixtures/json/australia_post/error_message.json +5 -0
- data/test/fixtures/json/australia_post/service_domestic.json +117 -0
- data/test/fixtures/json/australia_post/service_domestic_2.json +117 -0
- data/test/fixtures/json/australia_post/service_international.json +76 -0
- data/test/fixtures/json/australia_post/service_international_2.json +59 -0
- data/test/fixtures/json/newzealandpost/domestic_book.json +1 -0
- data/test/fixtures/json/newzealandpost/domestic_default.json +1 -0
- data/test/fixtures/json/newzealandpost/domestic_error.json +1 -0
- data/test/fixtures/json/newzealandpost/domestic_poster.json +1 -0
- data/test/fixtures/json/newzealandpost/domestic_small_half_pound.json +1 -0
- data/test/fixtures/json/newzealandpost/international_book.json +1 -0
- data/test/fixtures/json/newzealandpost/international_new_zealand_wii.json +1 -0
- data/test/fixtures/json/newzealandpost/international_small_half_pound.json +1 -0
- data/test/fixtures/json/newzealandpost/international_wii.json +1 -0
- data/test/fixtures/xml/canadapost/example_request.xml +25 -0
- data/test/fixtures/xml/canadapost/example_response.xml +130 -0
- data/test/fixtures/xml/canadapost/example_response_error.xml +16 -0
- data/test/fixtures/xml/canadapost/example_response_french.xml +122 -0
- data/test/fixtures/xml/canadapost/example_response_with_nil_value.xml +164 -0
- data/test/fixtures/xml/canadapost/example_response_with_postal_outlet.xml +155 -0
- data/test/fixtures/xml/canadapost/example_response_with_postal_outlet_french.xml +274 -0
- data/test/fixtures/xml/canadapost/example_response_with_strange_delivery_date.xml +130 -0
- data/test/fixtures/xml/canadapost_pws/dnc_tracking_details_en.xml +112 -0
- data/test/fixtures/xml/canadapost_pws/merchant_details_error.xml +7 -0
- data/test/fixtures/xml/canadapost_pws/merchant_details_response.xml +7 -0
- data/test/fixtures/xml/canadapost_pws/option_response.xml +13 -0
- data/test/fixtures/xml/canadapost_pws/option_response_no_conflicts.xml +7 -0
- data/test/fixtures/xml/canadapost_pws/rates_info.xml +190 -0
- data/test/fixtures/xml/canadapost_pws/rates_info_error.xml +7 -0
- data/test/fixtures/xml/canadapost_pws/receipt_response.xml +42 -0
- data/test/fixtures/xml/canadapost_pws/receipt_response_no_priced_options.xml +36 -0
- data/test/fixtures/xml/canadapost_pws/register_token_error.xml +7 -0
- data/test/fixtures/xml/canadapost_pws/register_token_response.xml +3 -0
- data/test/fixtures/xml/canadapost_pws/service_options_response.xml +42 -0
- data/test/fixtures/xml/canadapost_pws/services_error.xml +6 -0
- data/test/fixtures/xml/canadapost_pws/services_response.xml +32 -0
- data/test/fixtures/xml/canadapost_pws/shipment_domestic.xml +69 -0
- data/test/fixtures/xml/canadapost_pws/shipment_response.xml +20 -0
- data/test/fixtures/xml/canadapost_pws/shipment_us.xml +69 -0
- data/test/fixtures/xml/canadapost_pws/tracking_details_en.xml +152 -0
- data/test/fixtures/xml/canadapost_pws/tracking_details_en_error.xml +7 -0
- data/test/fixtures/xml/canadapost_pws/tracking_details_en_undelivered.xml +116 -0
- data/test/fixtures/xml/canadapost_pws/tracking_details_fr.xml +156 -0
- data/test/fixtures/xml/canadapost_pws/tracking_details_no_expected_delivery_date.xml +40 -0
- data/test/fixtures/xml/fedex/create_shipment_response.xml +2 -0
- data/test/fixtures/xml/fedex/freight_rate_request.xml +82 -0
- data/test/fixtures/xml/fedex/freight_rate_response.xml +506 -0
- data/test/fixtures/xml/fedex/invalid_fedex_reply.xml +27 -0
- data/test/fixtures/xml/fedex/ottawa_to_beverly_hills_commercial_rate_request.xml +79 -0
- data/test/fixtures/xml/fedex/ottawa_to_beverly_hills_no_saturday_rate_request.xml +79 -0
- data/test/fixtures/xml/fedex/ottawa_to_beverly_hills_rate_request.xml +80 -0
- data/test/fixtures/xml/fedex/ottawa_to_beverly_hills_rate_response.xml +214 -0
- data/test/fixtures/xml/fedex/raterequest_reply.xml +213 -0
- data/test/fixtures/xml/fedex/raterequest_response_with_ground_home_delivery.xml +206 -0
- data/test/fixtures/xml/fedex/reply_without_notifications.xml +185 -0
- data/test/fixtures/xml/fedex/tracking_request.xml +29 -0
- data/test/fixtures/xml/fedex/tracking_response_bad_tracking_number.xml +20 -0
- data/test/fixtures/xml/fedex/tracking_response_delivered_at_door.xml +254 -0
- data/test/fixtures/xml/fedex/tracking_response_delivered_at_facility.xml +403 -0
- data/test/fixtures/xml/fedex/tracking_response_delivered_with_signature.xml +269 -0
- data/test/fixtures/xml/fedex/tracking_response_empty_status_detail.xml +84 -0
- data/test/fixtures/xml/fedex/tracking_response_failure_code_9045.xml +52 -0
- data/test/fixtures/xml/fedex/tracking_response_failure_code_9080.xml +51 -0
- data/test/fixtures/xml/fedex/tracking_response_in_transit.xml +127 -0
- data/test/fixtures/xml/fedex/tracking_response_invalid_tracking_number.xml +52 -0
- data/test/fixtures/xml/fedex/tracking_response_missing_status_code.xml +89 -0
- data/test/fixtures/xml/fedex/tracking_response_multiple_results.xml +100 -0
- data/test/fixtures/xml/fedex/tracking_response_not_found.xml +52 -0
- data/test/fixtures/xml/fedex/tracking_response_shipment_exception.xml +209 -0
- data/test/fixtures/xml/fedex/tracking_response_unable_to_process.xml +32 -0
- data/test/fixtures/xml/fedex/tracking_response_with_blank_state.xml +107 -0
- data/test/fixtures/xml/fedex/unknown_fedex_document_reply.xml +3 -0
- data/test/fixtures/xml/kunaki/invalid_state_response.xml +3 -0
- data/test/fixtures/xml/kunaki/no_valid_items_response.xml +3 -0
- data/test/fixtures/xml/kunaki/successful_rates_response.xml +3 -0
- data/test/fixtures/xml/kunaki/unsuccessful_rates_response.xml +9 -0
- data/test/fixtures/xml/shipwire/international_rates_response.xml +17 -0
- data/test/fixtures/xml/shipwire/new_carrier_rate_response.xml +18 -0
- data/test/fixtures/xml/shipwire/no_rates_response.xml +7 -0
- data/test/fixtures/xml/shipwire/rates_response.xml +36 -0
- data/test/fixtures/xml/shipwire/rates_response_no_estimate.xml +14 -0
- data/test/fixtures/xml/stamps/authenticate_user_request.xml +15 -0
- data/test/fixtures/xml/stamps/authenticate_user_response.xml +10 -0
- data/test/fixtures/xml/stamps/cleanse_address_request.xml +19 -0
- data/test/fixtures/xml/stamps/cleanse_address_response.xml +27 -0
- data/test/fixtures/xml/stamps/create_indicium_request.xml +69 -0
- data/test/fixtures/xml/stamps/create_indicium_response.xml +40 -0
- data/test/fixtures/xml/stamps/expired_authenticator_response.xml +15 -0
- data/test/fixtures/xml/stamps/get_account_info_request.xml +11 -0
- data/test/fixtures/xml/stamps/get_account_info_response.xml +36 -0
- data/test/fixtures/xml/stamps/get_purchase_status_request.xml +12 -0
- data/test/fixtures/xml/stamps/get_purchase_status_response.xml +16 -0
- data/test/fixtures/xml/stamps/get_rates_request.xml +19 -0
- data/test/fixtures/xml/stamps/get_rates_response.xml +351 -0
- data/test/fixtures/xml/stamps/purchase_postage_request.xml +13 -0
- data/test/fixtures/xml/stamps/purchase_postage_response.xml +17 -0
- data/test/fixtures/xml/stamps/track_shipment_request.xml +12 -0
- data/test/fixtures/xml/stamps/track_shipment_response.xml +45 -0
- data/test/fixtures/xml/ups/access_request.xml +6 -0
- data/test/fixtures/xml/ups/delivered_shipment_with_refund.xml +290 -0
- data/test/fixtures/xml/ups/delivered_shipment_without_events_tracking_response.xml +62 -0
- data/test/fixtures/xml/ups/delivery_dates_response.xml +140 -0
- data/test/fixtures/xml/ups/example_tracking_response.xml +53 -0
- data/test/fixtures/xml/ups/in_transit_shipment.xml +183 -0
- data/test/fixtures/xml/ups/out_for_delivery_shipment.xml +165 -0
- data/test/fixtures/xml/ups/package_exceeds_maximum_length.xml +12 -0
- data/test/fixtures/xml/ups/rate_single_service.xml +54 -0
- data/test/fixtures/xml/ups/rescheduled_shipment.xml +204 -0
- data/test/fixtures/xml/ups/shipment_accept_response.xml +42 -0
- data/test/fixtures/xml/ups/shipment_confirm_response.xml +33 -0
- data/test/fixtures/xml/ups/shipment_from_tiger_direct.xml +222 -0
- data/test/fixtures/xml/ups/test_real_home_as_residential_destination_response.xml +290 -0
- data/test/fixtures/xml/ups/test_real_home_as_residential_destination_response_with_insured.xml +289 -0
- data/test/fixtures/xml/ups/test_real_home_as_residential_destination_with_origin_account_response.xml +311 -0
- data/test/fixtures/xml/ups/tracking_request.xml +9 -0
- data/test/fixtures/xml/ups/triple_accept_response.xml +72 -0
- data/test/fixtures/xml/ups/triple_confirm_response.xml +32 -0
- data/test/fixtures/xml/ups/void_shipment_response.xml +11 -0
- data/test/fixtures/xml/usps/api_error_rate_response.xml +53 -0
- data/test/fixtures/xml/usps/beverly_hills_to_new_york_book_commercial_base_rate_response.xml +2 -0
- data/test/fixtures/xml/usps/beverly_hills_to_new_york_book_commercial_plus_rate_response.xml +258 -0
- data/test/fixtures/xml/usps/beverly_hills_to_new_york_book_rate_response.xml +108 -0
- data/test/fixtures/xml/usps/beverly_hills_to_ottawa_american_wii_commercial_base_rate_response.xml +84 -0
- data/test/fixtures/xml/usps/beverly_hills_to_ottawa_american_wii_commercial_plus_rate_response.xml +212 -0
- data/test/fixtures/xml/usps/beverly_hills_to_ottawa_american_wii_rate_response.xml +230 -0
- data/test/fixtures/xml/usps/first_class_packages_with_invalid_mail_type_response.xml +12 -0
- data/test/fixtures/xml/usps/first_class_packages_with_mail_type_response.xml +16 -0
- data/test/fixtures/xml/usps/first_class_packages_without_mail_type_response.xml +12 -0
- data/test/fixtures/xml/usps/invalid_xml_response.xml +10 -0
- data/test/fixtures/xml/usps/invalid_xml_tracking_response_error.xml +2 -0
- data/test/fixtures/xml/usps/tracking_request.xml +10 -0
- data/test/fixtures/xml/usps/tracking_request_batch.xml +12 -0
- data/test/fixtures/xml/usps/tracking_response.xml +162 -0
- data/test/fixtures/xml/usps/tracking_response_alt.xml +53 -0
- data/test/fixtures/xml/usps/tracking_response_batch.xml +231 -0
- data/test/fixtures/xml/usps/tracking_response_failure.xml +11 -0
- data/test/fixtures/xml/usps/tracking_response_not_available.xml +12 -0
- data/test/fixtures/xml/usps/tracking_response_test_error.xml +8 -0
- data/test/fixtures/xml/usps/us_rate_request.xml +18 -0
- data/test/fixtures/xml/usps/us_rate_request_large.xml +18 -0
- data/test/fixtures/xml/usps/world_rate_request_only_country.xml +22 -0
- data/test/fixtures/xml/usps/world_rate_request_with_value.xml +24 -0
- data/test/fixtures/xml/usps/world_rate_request_without_value.xml +24 -0
- data/test/fixtures/xml/usps_returns/external_return_label_response.xml +2 -0
- data/test/fixtures/xml/usps_returns/external_return_label_response_failure.xml +10 -0
- data/test/remote/australia_post_test.rb +140 -0
- data/test/remote/canada_post_pws_platform_test.rb +259 -0
- data/test/remote/canada_post_pws_test.rb +169 -0
- data/test/remote/canada_post_test.rb +55 -0
- data/test/remote/fedex_test.rb +400 -0
- data/test/remote/kunaki_test.rb +37 -0
- data/test/remote/new_zealand_post_test.rb +149 -0
- data/test/remote/shipwire_test.rb +84 -0
- data/test/remote/stamps_test.rb +396 -0
- data/test/remote/usps_returns_test.rb +72 -0
- data/test/remote/usps_test.rb +243 -0
- data/test/test_helper.rb +296 -0
- data/test/unit/carrier_test.rb +130 -0
- data/test/unit/carriers/australia_post_test.rb +181 -0
- data/test/unit/carriers/benchmark_test.rb +18 -0
- data/test/unit/carriers/canada_post_pws_rating_test.rb +379 -0
- data/test/unit/carriers/canada_post_pws_register_test.rb +76 -0
- data/test/unit/carriers/canada_post_pws_shipping_test.rb +258 -0
- data/test/unit/carriers/canada_post_pws_test.rb +59 -0
- data/test/unit/carriers/canada_post_pws_tracking_test.rb +154 -0
- data/test/unit/carriers/canada_post_test.rb +148 -0
- data/test/unit/carriers/fedex_test.rb +693 -0
- data/test/unit/carriers/kunaki_test.rb +56 -0
- data/test/unit/carriers/new_zealand_post_test.rb +177 -0
- data/test/unit/carriers/shipwire_test.rb +188 -0
- data/test/unit/carriers/stamps_test.rb +245 -0
- data/test/unit/carriers/ups_test.rb +580 -0
- data/test/unit/carriers/usps_returns_test.rb +45 -0
- data/test/unit/carriers/usps_test.rb +633 -0
- data/test/unit/carriers_test.rb +16 -0
- data/test/unit/external_return_label_request_test.rb +258 -0
- data/test/unit/location_test.rb +234 -0
- data/test/unit/package_item_test.rb +232 -0
- data/test/unit/package_test.rb +404 -0
- data/test/unit/rate_estimate_test.rb +93 -0
- data/test/unit/response_test.rb +38 -0
- data/test/unit/shipment_event_test.rb +20 -0
- data/test/unit/shipment_packer_test.rb +212 -0
- data/test/unit/tracking_response_test.rb +41 -0
- metadata +684 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class CanadaPostTest < ActiveSupport::TestCase
|
|
4
|
+
include ReactiveShipping::Test::Fixtures
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
login = { login: 'CPC_DEMO_XML' }
|
|
8
|
+
|
|
9
|
+
@carrier = CanadaPost.new(login)
|
|
10
|
+
@french_carrier = CanadaPost.new(login.merge(french: true))
|
|
11
|
+
|
|
12
|
+
@request = xml_fixture('canadapost/example_request')
|
|
13
|
+
@response = xml_fixture('canadapost/example_response')
|
|
14
|
+
@response_french = xml_fixture('canadapost/example_response_french')
|
|
15
|
+
@bad_response = xml_fixture('canadapost/example_response_error')
|
|
16
|
+
|
|
17
|
+
@origin = {:address1 => "61A York St", :city => "Ottawa", :province => "ON", :country => "Canada", :postal_code => "K1N 5T2"}
|
|
18
|
+
@destination = {:city => "Beverly Hills", :state => "CA", :country => "United States", :postal_code => "90210"}
|
|
19
|
+
@line_items = [Package.new(500, [2, 3, 4], :description => "a box full of stuff", :value => 2500)]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_parse_rate_response_french
|
|
23
|
+
@french_carrier.expects(:ssl_post).returns(@response_french)
|
|
24
|
+
rate_estimates = @french_carrier.find_rates(@origin, @destination, @line_items)
|
|
25
|
+
|
|
26
|
+
rate_estimates.rates.each do |rate|
|
|
27
|
+
assert_instance_of RateEstimate, rate
|
|
28
|
+
assert_instance_of Date, rate.delivery_date
|
|
29
|
+
assert_instance_of Date, rate.shipping_date
|
|
30
|
+
assert_instance_of String, rate.service_name
|
|
31
|
+
assert_kind_of Integer, rate.total_price
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
rate_estimates.boxes.each do |box|
|
|
35
|
+
assert_instance_of CanadaPost::Box, box
|
|
36
|
+
assert_instance_of String, box.name
|
|
37
|
+
assert_instance_of Float, box.weight
|
|
38
|
+
assert_instance_of Float, box.expediter_weight
|
|
39
|
+
assert_instance_of Float, box.length
|
|
40
|
+
assert_instance_of Float, box.height
|
|
41
|
+
assert_instance_of Float, box.width
|
|
42
|
+
|
|
43
|
+
box.packedItems.each do |p|
|
|
44
|
+
assert_kind_of Integer, p.quantity
|
|
45
|
+
assert_instance_of String, p.description
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def test_build_rate_request
|
|
51
|
+
@carrier.expects(:commit).with(@request, @origin, @destination, {})
|
|
52
|
+
@carrier.find_rates(@origin, @destination, @line_items)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def test_parse_rate_response
|
|
56
|
+
@carrier.expects(:ssl_post).returns(@response)
|
|
57
|
+
rate_estimates = @carrier.find_rates(@origin, @destination, @line_items)
|
|
58
|
+
|
|
59
|
+
rate_estimates.rates.each do |rate|
|
|
60
|
+
assert_instance_of RateEstimate, rate
|
|
61
|
+
assert_instance_of Date, rate.delivery_date
|
|
62
|
+
assert_instance_of Date, rate.shipping_date
|
|
63
|
+
assert_instance_of String, rate.service_name
|
|
64
|
+
assert_kind_of Integer, rate.total_price
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
rate_estimates.boxes.each do |box|
|
|
68
|
+
assert_instance_of CanadaPost::Box, box
|
|
69
|
+
assert_instance_of String, box.name
|
|
70
|
+
assert_instance_of Float, box.weight
|
|
71
|
+
assert_instance_of Float, box.expediter_weight
|
|
72
|
+
assert_instance_of Float, box.length
|
|
73
|
+
assert_instance_of Float, box.height
|
|
74
|
+
assert_instance_of Float, box.width
|
|
75
|
+
|
|
76
|
+
box.packedItems.each do |p|
|
|
77
|
+
assert_kind_of Integer, p.quantity
|
|
78
|
+
assert_instance_of String, p.description
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def test_non_success_parse_rate_response
|
|
84
|
+
@carrier.expects(:ssl_post).returns(@bad_response)
|
|
85
|
+
|
|
86
|
+
error = assert_raises(ReactiveShipping::ResponseError) do
|
|
87
|
+
@carrier.find_rates(@origin, @destination, @line_items)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
assert_equal 'Parcel too heavy to be shipped with CPC.', error.message
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def test_turn_around_time
|
|
94
|
+
@carrier.expects(:commit).with do |request, _options|
|
|
95
|
+
parsed_request = Hash.from_xml(request)
|
|
96
|
+
parsed_request['eparcel']['ratesAndServicesRequest']['turnAroundTime'] == "0"
|
|
97
|
+
end
|
|
98
|
+
@carrier.find_rates(@origin, @destination, @line_items, :turn_around_time => 0)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def test_build_line_items
|
|
102
|
+
line_items_xml = Nokogiri::XML::Builder.new do |xml|
|
|
103
|
+
@carrier.send(:build_line_items, xml, @line_items)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
assert_instance_of Nokogiri::XML::Builder, line_items_xml
|
|
107
|
+
assert_equal "a box full of stuff", line_items_xml.doc.at_xpath('//description').text
|
|
108
|
+
assert_equal "0.5", line_items_xml.doc.at_xpath('//weight').text
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def test_non_iso_country_names
|
|
112
|
+
@destination[:country] = 'RU'
|
|
113
|
+
@carrier.expects(:ssl_post).with(anything, regexp_matches(%r{<country>Russia</country>})).returns(@response)
|
|
114
|
+
@carrier.find_rates(@origin, @destination, @line_items)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def test_delivery_range_based_on_delivery_date
|
|
118
|
+
@carrier.expects(:ssl_post).returns(@response)
|
|
119
|
+
rate_estimates = @carrier.find_rates(@origin, @destination, @line_items)
|
|
120
|
+
|
|
121
|
+
delivery_date = Date.new(2010, 8, 4)
|
|
122
|
+
assert_equal [delivery_date] * 2, rate_estimates.rates[0].delivery_range
|
|
123
|
+
assert_equal [delivery_date] * 2, rate_estimates.rates[1].delivery_range
|
|
124
|
+
assert_equal [delivery_date + 2.days] * 2, rate_estimates.rates[2].delivery_range
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def test_delivery_range_with_invalid_date
|
|
128
|
+
@response = xml_fixture('canadapost/example_response_with_strange_delivery_date')
|
|
129
|
+
@carrier.expects(:ssl_post).returns(@response)
|
|
130
|
+
rate_estimates = @carrier.find_rates(@origin, @destination, @line_items)
|
|
131
|
+
|
|
132
|
+
assert_equal [], rate_estimates.rates[0].delivery_range
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def test_line_items_with_nil_values
|
|
136
|
+
@response = xml_fixture('canadapost/example_response_with_nil_value')
|
|
137
|
+
@carrier.expects(:ssl_post).returns(@response)
|
|
138
|
+
|
|
139
|
+
@line_items << Package.new(500, [2, 3, 4], :description => "another box full of stuff", :value => nil)
|
|
140
|
+
rate_response = @carrier.find_rates(@origin, @destination, @line_items)
|
|
141
|
+
|
|
142
|
+
assert rate_response.rates.length > 0, "Expecting rateestimates even without a value specified."
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def test_maximum_address_field_length
|
|
146
|
+
assert_equal 44, @carrier.maximum_address_field_length
|
|
147
|
+
end
|
|
148
|
+
end
|
|
@@ -0,0 +1,693 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class FedExTest < ActiveSupport::TestCase
|
|
4
|
+
include ReactiveShipping::Test::Fixtures
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
@carrier = FedEx.new(:key => '1111', :password => '2222', :account => '3333', :login => '4444')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def test_initialize_options_requirements
|
|
11
|
+
assert_raises(ArgumentError) { FedEx.new }
|
|
12
|
+
assert_raises(ArgumentError) { FedEx.new(:login => '999999999') }
|
|
13
|
+
assert_raises(ArgumentError) { FedEx.new(:password => '7777777') }
|
|
14
|
+
FedEx.new(:key => '999999999', :password => '7777777', :account => '123', :login => '123')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_business_days
|
|
18
|
+
today = DateTime.parse("Tue 12 Mar 2013 00:00:00-0400")
|
|
19
|
+
|
|
20
|
+
Timecop.freeze(today) do
|
|
21
|
+
assert_equal DateTime.parse("Wed 13 Mar 2013 00:00:00-0400"), @carrier.send(:business_days_from, today, 1)
|
|
22
|
+
assert_equal DateTime.parse("Fri 15 Mar 2013 00:00:00-0400"), @carrier.send(:business_days_from, today, 3)
|
|
23
|
+
assert_equal DateTime.parse("Mon 18 Mar 2013 00:00:00-0400"), @carrier.send(:business_days_from, today, 4)
|
|
24
|
+
assert_equal DateTime.parse("Tue 19 Mar 2013 00:00:00-0400"), @carrier.send(:business_days_from, today, 5)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_home_delivery_business_days
|
|
29
|
+
today = DateTime.parse("Tue 12 Mar 2013 00:00:00-0400")
|
|
30
|
+
|
|
31
|
+
Timecop.freeze(today) do
|
|
32
|
+
assert_equal DateTime.parse("Wed 13 Mar 2013 00:00:00-0400"), @carrier.send(:business_days_from, today, 1, true)
|
|
33
|
+
assert_equal DateTime.parse("Fri 15 Mar 2013 00:00:00-0400"), @carrier.send(:business_days_from, today, 3, true)
|
|
34
|
+
assert_equal DateTime.parse("Sat 16 Mar 2013 00:00:00-0400"), @carrier.send(:business_days_from, today, 4, true)
|
|
35
|
+
assert_equal DateTime.parse("Tue 19 Mar 2013 00:00:00-0400"), @carrier.send(:business_days_from, today, 5, true)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_turn_around_time_default
|
|
40
|
+
mock_response = xml_fixture('fedex/ottawa_to_beverly_hills_rate_response').gsub('<v6:DeliveryTimestamp>2011-07-29</v6:DeliveryTimestamp>', '')
|
|
41
|
+
|
|
42
|
+
today = Date.parse("Mon 11 Mar 2013")
|
|
43
|
+
|
|
44
|
+
Timecop.freeze(today) do
|
|
45
|
+
delivery_date = Date.today + 7.days # FIVE_DAYS in fixture response, plus weekend
|
|
46
|
+
timestamp = Time.now.iso8601
|
|
47
|
+
@carrier.expects(:commit).with do |request, _options|
|
|
48
|
+
parsed_response = Hash.from_xml(request)
|
|
49
|
+
parsed_response['RateRequest']['RequestedShipment']['ShipTimestamp'] == timestamp
|
|
50
|
+
end.returns(mock_response)
|
|
51
|
+
|
|
52
|
+
destination = ReactiveShipping::Location.from(location_fixtures[:beverly_hills].to_hash, :address_type => :commercial)
|
|
53
|
+
response = @carrier.find_rates location_fixtures[:ottawa], destination, package_fixtures[:book], :test => true
|
|
54
|
+
assert_equal [delivery_date, delivery_date], response.rates.first.delivery_range
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def test_turn_around_time
|
|
59
|
+
mock_response = xml_fixture('fedex/ottawa_to_beverly_hills_rate_response').gsub('<v6:DeliveryTimestamp>2011-07-29</v6:DeliveryTimestamp>', '')
|
|
60
|
+
Timecop.freeze(DateTime.new(2013, 3, 11)) do
|
|
61
|
+
delivery_date = Date.today + 8.days # FIVE_DAYS in fixture response, plus turn_around_time, plus weekend
|
|
62
|
+
timestamp = (Time.now + 1.day).iso8601
|
|
63
|
+
@carrier.expects(:commit).with do |request, _options|
|
|
64
|
+
parsed_response = Hash.from_xml(request)
|
|
65
|
+
parsed_response['RateRequest']['RequestedShipment']['ShipTimestamp'] == timestamp
|
|
66
|
+
end.returns(mock_response)
|
|
67
|
+
|
|
68
|
+
destination = ReactiveShipping::Location.from(location_fixtures[:beverly_hills].to_hash, :address_type => :commercial)
|
|
69
|
+
response = @carrier.find_rates location_fixtures[:ottawa], destination, package_fixtures[:book], :turn_around_time => 24, :test => true
|
|
70
|
+
|
|
71
|
+
assert_equal [delivery_date, delivery_date], response.rates.first.delivery_range
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def test_transaction_id_sent_as_customer_transaction_id
|
|
76
|
+
transaction_id = '9999-test'
|
|
77
|
+
@carrier = FedEx.new(:key => '1111', :password => '2222', :account => '3333', :login => '4444', :transaction_id => transaction_id)
|
|
78
|
+
@carrier.expects(:commit).with do |request, _options|
|
|
79
|
+
parsed_request = Hash.from_xml(request)
|
|
80
|
+
parsed_request['RateRequest']['TransactionDetail']['CustomerTransactionId'] == transaction_id
|
|
81
|
+
end.returns(xml_fixture('fedex/ottawa_to_beverly_hills_rate_response'))
|
|
82
|
+
|
|
83
|
+
destination = ReactiveShipping::Location.from(location_fixtures[:beverly_hills].to_hash, :address_type => :commercial)
|
|
84
|
+
@carrier.find_rates location_fixtures[:ottawa], destination, package_fixtures[:book], :test => true
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def test_building_request_with_address_type_commercial_should_not_include_residential
|
|
88
|
+
mock_response = xml_fixture('fedex/ottawa_to_beverly_hills_rate_response')
|
|
89
|
+
expected_request = xml_fixture('fedex/ottawa_to_beverly_hills_commercial_rate_request')
|
|
90
|
+
|
|
91
|
+
@carrier.expects(:ship_timestamp).returns(Time.parse("2009-07-20T12:01:55-04:00").in_time_zone('US/Eastern'))
|
|
92
|
+
@carrier.expects(:commit).with { |request, test_mode| Hash.from_xml(request) == Hash.from_xml(expected_request) && test_mode }.returns(mock_response)
|
|
93
|
+
destination = ReactiveShipping::Location.from(location_fixtures[:beverly_hills].to_hash, :address_type => :commercial)
|
|
94
|
+
@carrier.find_rates( location_fixtures[:ottawa],
|
|
95
|
+
destination,
|
|
96
|
+
package_fixtures.values_at(:book, :wii), test: true, saturday_delivery: true)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def test_building_request_with_no_saturday_delivery_should_not_have_saturday_option_set
|
|
100
|
+
mock_response = xml_fixture('fedex/ottawa_to_beverly_hills_rate_response')
|
|
101
|
+
expected_request = xml_fixture('fedex/ottawa_to_beverly_hills_no_saturday_rate_request')
|
|
102
|
+
|
|
103
|
+
@carrier.expects(:ship_timestamp).returns(Time.parse("2009-07-20T12:01:55-04:00").in_time_zone('US/Eastern'))
|
|
104
|
+
@carrier.expects(:commit).with { |request, test_mode| Hash.from_xml(request) == Hash.from_xml(expected_request) && test_mode }.returns(mock_response)
|
|
105
|
+
destination = ReactiveShipping::Location.from(location_fixtures[:beverly_hills].to_hash)
|
|
106
|
+
@carrier.find_rates( location_fixtures[:ottawa],
|
|
107
|
+
destination,
|
|
108
|
+
package_fixtures.values_at(:book, :wii), test: true)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def test_building_freight_request_and_parsing_response
|
|
112
|
+
expected_request = xml_fixture('fedex/freight_rate_request')
|
|
113
|
+
mock_response = xml_fixture('fedex/freight_rate_response')
|
|
114
|
+
|
|
115
|
+
@carrier.expects(:ship_timestamp).returns(Time.parse("2013-11-01T14:04:01-07:00").in_time_zone('US/Pacific'))
|
|
116
|
+
@carrier.expects(:commit).with { |request, test_mode| Hash.from_xml(request) == Hash.from_xml(expected_request) && test_mode }.returns(mock_response)
|
|
117
|
+
|
|
118
|
+
# shipping and billing addresses below are provided by fedex test credentials
|
|
119
|
+
|
|
120
|
+
shipping_location = Location.new( address1: '1202 Chalet Ln',
|
|
121
|
+
address2: 'Do Not Delete - Test Account',
|
|
122
|
+
city: 'Harrison',
|
|
123
|
+
state: 'AR',
|
|
124
|
+
postal_code: '72601',
|
|
125
|
+
country: 'US')
|
|
126
|
+
|
|
127
|
+
billing_location = Location.new( address1: '2000 Freight LTL Testing',
|
|
128
|
+
address2: 'Do Not Delete - Test Account',
|
|
129
|
+
city: 'Harrison',
|
|
130
|
+
state: 'AR',
|
|
131
|
+
postal_code: '72601',
|
|
132
|
+
country: 'US')
|
|
133
|
+
|
|
134
|
+
freight_options = {
|
|
135
|
+
account: '5555',
|
|
136
|
+
billing_location: billing_location,
|
|
137
|
+
payment_type: 'SENDER',
|
|
138
|
+
freight_class: 'CLASS_050',
|
|
139
|
+
packaging: 'PALLET',
|
|
140
|
+
role: 'SHIPPER'
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
response = @carrier.find_rates( shipping_location,
|
|
144
|
+
location_fixtures[:ottawa],
|
|
145
|
+
[package_fixtures[:wii]], freight: freight_options, test: true, saturday_delivery: true )
|
|
146
|
+
|
|
147
|
+
assert_equal ["FedEx Freight Economy", "FedEx Freight Priority"], response.rates.map(&:service_name)
|
|
148
|
+
assert_equal [66263, 68513], response.rates.map(&:price)
|
|
149
|
+
|
|
150
|
+
assert response.success?, response.message
|
|
151
|
+
assert_instance_of Hash, response.params
|
|
152
|
+
assert_instance_of String, response.xml
|
|
153
|
+
assert_instance_of Array, response.rates
|
|
154
|
+
assert response.rates.length > 0, "There should've been more than 0 rates returned"
|
|
155
|
+
|
|
156
|
+
rate = response.rates.first
|
|
157
|
+
assert_equal 'FedEx', rate.carrier
|
|
158
|
+
assert_equal 'USD', rate.currency
|
|
159
|
+
assert_kind_of Integer, rate.total_price
|
|
160
|
+
assert_kind_of Integer, rate.price
|
|
161
|
+
assert_instance_of String, rate.service_name
|
|
162
|
+
assert_instance_of String, rate.service_code
|
|
163
|
+
assert_instance_of Array, rate.package_rates
|
|
164
|
+
assert_equal [package_fixtures[:wii]], rate.packages
|
|
165
|
+
|
|
166
|
+
package_rate = rate.package_rates.first
|
|
167
|
+
assert_instance_of Hash, package_rate
|
|
168
|
+
assert_instance_of Package, package_rate[:package]
|
|
169
|
+
assert_nil package_rate[:rate]
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def test_building_request_and_parsing_response
|
|
173
|
+
expected_request = xml_fixture('fedex/ottawa_to_beverly_hills_rate_request')
|
|
174
|
+
mock_response = xml_fixture('fedex/ottawa_to_beverly_hills_rate_response')
|
|
175
|
+
@carrier.expects(:ship_timestamp).returns(Time.parse("2009-07-20T12:01:55-04:00").in_time_zone('US/Eastern'))
|
|
176
|
+
@carrier.expects(:commit).with { |request, test_mode| Hash.from_xml(request) == Hash.from_xml(expected_request) && test_mode }.returns(mock_response)
|
|
177
|
+
response = @carrier.find_rates( location_fixtures[:ottawa],
|
|
178
|
+
location_fixtures[:beverly_hills],
|
|
179
|
+
package_fixtures.values_at(:book, :wii), test: true, saturday_delivery: true)
|
|
180
|
+
assert_equal ["FedEx Ground"], response.rates.map(&:service_name)
|
|
181
|
+
assert_equal [3836], response.rates.map(&:price)
|
|
182
|
+
|
|
183
|
+
assert response.success?, response.message
|
|
184
|
+
assert_instance_of Hash, response.params
|
|
185
|
+
assert_instance_of String, response.xml
|
|
186
|
+
assert_instance_of Array, response.rates
|
|
187
|
+
assert response.rates.length > 0, "There should've been more than 0 rates returned"
|
|
188
|
+
|
|
189
|
+
rate = response.rates.first
|
|
190
|
+
assert_equal 'FedEx', rate.carrier
|
|
191
|
+
assert_equal 'CAD', rate.currency
|
|
192
|
+
assert_kind_of Integer, rate.total_price
|
|
193
|
+
assert_kind_of Integer, rate.price
|
|
194
|
+
assert_instance_of String, rate.service_name
|
|
195
|
+
assert_instance_of String, rate.service_code
|
|
196
|
+
assert_instance_of Array, rate.package_rates
|
|
197
|
+
assert_equal package_fixtures.values_at(:book, :wii), rate.packages
|
|
198
|
+
|
|
199
|
+
package_rate = rate.package_rates.first
|
|
200
|
+
assert_instance_of Hash, package_rate
|
|
201
|
+
assert_instance_of Package, package_rate[:package]
|
|
202
|
+
assert_nil package_rate[:rate]
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def test_parsing_response_with_no_rate_reply
|
|
206
|
+
expected_request = xml_fixture('fedex/ottawa_to_beverly_hills_rate_request')
|
|
207
|
+
mock_response = xml_fixture('fedex/unknown_fedex_document_reply')
|
|
208
|
+
|
|
209
|
+
@carrier.expects(:ship_timestamp).returns(Time.parse("2009-07-20T12:01:55-04:00").in_time_zone('US/Eastern'))
|
|
210
|
+
@carrier.expects(:commit).with { |request, test_mode| Hash.from_xml(request) == Hash.from_xml(expected_request) && test_mode }.returns(mock_response)
|
|
211
|
+
exception = assert_raises(ReactiveShipping::ResponseContentError) do
|
|
212
|
+
@carrier.find_rates( location_fixtures[:ottawa],
|
|
213
|
+
location_fixtures[:beverly_hills],
|
|
214
|
+
package_fixtures.values_at(:book, :wii), test: true, saturday_delivery: true)
|
|
215
|
+
end
|
|
216
|
+
message = "Invalid document \n\n#{mock_response}"
|
|
217
|
+
assert_equal message, exception.message
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def test_parsing_response_with_no_system_code_for_one_rate_does_not_crash
|
|
221
|
+
mock_response = xml_fixture('fedex/freight_rate_response').gsub('<v13:ServiceType>FEDEX_FREIGHT_ECONOMY</v13:ServiceType>','')
|
|
222
|
+
|
|
223
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
224
|
+
@carrier.logger = Logger.new(StringIO.new)
|
|
225
|
+
@carrier.logger.expects(:warn).once.with("[FedexParseRateError] Some fields where missing in the response: #{mock_response}")
|
|
226
|
+
|
|
227
|
+
rates = @carrier.find_rates( location_fixtures[:ottawa], location_fixtures[:beverly_hills], package_fixtures.values_at(:book, :wii), :test => true)
|
|
228
|
+
assert rates.rates.length == 1
|
|
229
|
+
assert_equal rates.rates[0].service_code, 'FEDEX_FREIGHT_PRIORITY'
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def test_parsing_response_with_no_system_code_on_any_shipping_rate
|
|
233
|
+
mock_response = xml_fixture('fedex/freight_rate_response').gsub('<v13:ServiceType>FEDEX_FREIGHT_ECONOMY</v13:ServiceType>','').gsub('<v13:ServiceType>FEDEX_FREIGHT_PRIORITY</v13:ServiceType>','')
|
|
234
|
+
|
|
235
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
236
|
+
@carrier.logger = Logger.new(StringIO.new)
|
|
237
|
+
@carrier.logger.expects(:warn).once.with("[FedexParseRateError] Some fields where missing in the response: #{mock_response}")
|
|
238
|
+
|
|
239
|
+
exception = assert_raises(ReactiveShipping::ResponseError) do
|
|
240
|
+
@carrier.find_rates( location_fixtures[:ottawa], location_fixtures[:beverly_hills], package_fixtures.values_at(:book, :wii), :test => true)
|
|
241
|
+
end
|
|
242
|
+
message = "The response from the carrier contained errors and could not be treated"
|
|
243
|
+
assert_equal exception.message, message
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def test_service_name_for_code
|
|
247
|
+
FedEx::SERVICE_TYPES.each do |capitalized_name, readable_name|
|
|
248
|
+
assert_equal readable_name, FedEx.service_name_for_code(capitalized_name)
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def test_service_name_for_code_handles_yet_unknown_codes
|
|
253
|
+
assert_equal "FedEx Express Saver Saturday Delivery", FedEx.service_name_for_code('FEDEX_EXPRESS_SAVER_SATURDAY_DELIVERY')
|
|
254
|
+
assert_equal "FedEx Some Weird Rate", FedEx.service_name_for_code('SOME_WEIRD_RATE')
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def test_delivery_range_based_on_delivery_date
|
|
258
|
+
mock_response = xml_fixture('fedex/ottawa_to_beverly_hills_rate_response').gsub('CAD', 'UKL')
|
|
259
|
+
|
|
260
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
261
|
+
rate_estimates = @carrier.find_rates( location_fixtures[:ottawa],
|
|
262
|
+
location_fixtures[:beverly_hills],
|
|
263
|
+
package_fixtures.values_at(:book, :wii), :test => true)
|
|
264
|
+
|
|
265
|
+
delivery_date = Date.new(2011, 7, 29)
|
|
266
|
+
assert_equal delivery_date, rate_estimates.rates[0].delivery_date
|
|
267
|
+
assert_equal [delivery_date] * 2, rate_estimates.rates[0].delivery_range
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def test_delivery_date_from_transit_time
|
|
271
|
+
mock_response = xml_fixture('fedex/raterequest_reply').gsub('CAD', 'UKL')
|
|
272
|
+
|
|
273
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
274
|
+
|
|
275
|
+
today = Date.parse("Fri 15 Mar 2013")
|
|
276
|
+
|
|
277
|
+
Timecop.freeze(today) do
|
|
278
|
+
rate_estimates = @carrier.find_rates( location_fixtures[:ottawa],
|
|
279
|
+
location_fixtures[:beverly_hills],
|
|
280
|
+
package_fixtures.values_at(:book, :wii), :test => true)
|
|
281
|
+
|
|
282
|
+
# the above fixture will specify a transit time of 5 days, with 2 weekend days accounted for
|
|
283
|
+
delivery_date = Date.today + 5 + 2
|
|
284
|
+
assert_equal delivery_date, rate_estimates.rates[0].delivery_date
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def test_delivery_date_from_ground_home_transit_time
|
|
289
|
+
mock_response = xml_fixture('fedex/raterequest_response_with_ground_home_delivery')
|
|
290
|
+
|
|
291
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
292
|
+
|
|
293
|
+
today = Date.parse("Thursday 04 Jun 2015")
|
|
294
|
+
|
|
295
|
+
Timecop.freeze(today) do
|
|
296
|
+
rate_estimates = @carrier.find_rates( location_fixtures[:ottawa],
|
|
297
|
+
location_fixtures[:beverly_hills],
|
|
298
|
+
package_fixtures.values_at(:book, :wii), :test => true)
|
|
299
|
+
|
|
300
|
+
# the above fixture will specify a transit time of 3 days
|
|
301
|
+
# for ground home, sunday and monday are non-biz days
|
|
302
|
+
# so it is delivered on Tuesday
|
|
303
|
+
delivery_date = Date.today + 3 + 2
|
|
304
|
+
assert_equal delivery_date, rate_estimates.rates.first.delivery_date
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
def test_delivery_date_from_ground_home_transit_time_on_saturday
|
|
309
|
+
mock_response = xml_fixture('fedex/raterequest_response_with_ground_home_delivery')
|
|
310
|
+
|
|
311
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
312
|
+
|
|
313
|
+
today = Date.parse("Wed 03 Jun 2015") #Wednesday
|
|
314
|
+
|
|
315
|
+
Timecop.freeze(today) do
|
|
316
|
+
rate_estimates = @carrier.find_rates( location_fixtures[:ottawa],
|
|
317
|
+
location_fixtures[:beverly_hills],
|
|
318
|
+
package_fixtures.values_at(:book, :wii), :test => true)
|
|
319
|
+
|
|
320
|
+
# the above fixture will specify a transit time of 3 days
|
|
321
|
+
# since ground home delivers on Saturday, there is no delay
|
|
322
|
+
delivery_date = Date.today + 3
|
|
323
|
+
assert_equal delivery_date, rate_estimates.rates.first.delivery_date
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
def test_failure_to_parse_invalid_xml_results_in_a_useful_error
|
|
328
|
+
mock_response = xml_fixture('fedex/invalid_fedex_reply')
|
|
329
|
+
|
|
330
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
331
|
+
|
|
332
|
+
assert_raises ReactiveShipping::ResponseContentError do
|
|
333
|
+
@carrier.find_rates(
|
|
334
|
+
location_fixtures[:ottawa],
|
|
335
|
+
location_fixtures[:beverly_hills],
|
|
336
|
+
package_fixtures.values_at(:book, :wii),
|
|
337
|
+
test: true
|
|
338
|
+
)
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
def test_parsing_response_without_notifications
|
|
343
|
+
mock_response = xml_fixture('fedex/reply_without_notifications')
|
|
344
|
+
|
|
345
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
346
|
+
|
|
347
|
+
response = @carrier.find_rates(
|
|
348
|
+
location_fixtures[:ottawa],
|
|
349
|
+
location_fixtures[:beverly_hills],
|
|
350
|
+
package_fixtures.values_at(:book, :wii),
|
|
351
|
+
test: true
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
assert_predicate response, :success?
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
### find_tracking_info
|
|
358
|
+
|
|
359
|
+
def test_response_transient_failure
|
|
360
|
+
mock_response = xml_fixture('fedex/tracking_response_failure_code_9045')
|
|
361
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
362
|
+
|
|
363
|
+
error = assert_raises(ReactiveShipping::ShipmentNotFound) do
|
|
364
|
+
@carrier.find_tracking_info('123456789013')
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
msg = 'Sorry, we are unable to process your tracking request. Please retry later, or contact Customer Service at 1.800.Go.FedEx(R) 800.463.3339.'
|
|
368
|
+
assert_equal msg, error.message
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
def test_response_with_failure_nested_in_track_details
|
|
372
|
+
mock_response = xml_fixture('fedex/tracking_response_failure_code_9080')
|
|
373
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
374
|
+
|
|
375
|
+
error = assert_raises(ReactiveShipping::ResponseContentError) do
|
|
376
|
+
@carrier.find_tracking_info('123456789013')
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
msg = 'Sorry, we are unable to process your tracking request. Please contact Customer Service at 1.800.Go.FedEx(R) 800.463.3339.'
|
|
380
|
+
assert_equal msg, error.message
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
def test_response_with_failure_nested_in_completed_track_details
|
|
384
|
+
mock_response = xml_fixture('fedex/tracking_response_unable_to_process')
|
|
385
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
386
|
+
|
|
387
|
+
error = assert_raises(ReactiveShipping::ResponseError) do
|
|
388
|
+
@carrier.find_tracking_info('123456789013')
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
msg = 'FAILURE - 6330: Sorry, we are unable to process your tracking request. Please retry later, or contact Customer Service at 1.800.Go.FedEx(R) 800.463.3339.'
|
|
392
|
+
assert_equal msg, error.message
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
def test_tracking_info_for_delivered_with_signature
|
|
396
|
+
mock_response = xml_fixture('fedex/tracking_response_delivered_with_signature')
|
|
397
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
398
|
+
|
|
399
|
+
response = @carrier.find_tracking_info('449044304137821')
|
|
400
|
+
assert_equal '449044304137821', response.tracking_number
|
|
401
|
+
assert_equal 'AVILLALON', response.delivery_signature
|
|
402
|
+
assert response.delivered?
|
|
403
|
+
refute response.exception?
|
|
404
|
+
|
|
405
|
+
assert_equal Date.parse('2013-12-30'), response.ship_time
|
|
406
|
+
assert_nil response.scheduled_delivery_date
|
|
407
|
+
assert_equal Time.parse('2014-01-02T18:23:29Z'), response.actual_delivery_date
|
|
408
|
+
|
|
409
|
+
origin_address = ReactiveShipping::Location.new(
|
|
410
|
+
city: 'JEFFERSONVILLE',
|
|
411
|
+
country: 'US',
|
|
412
|
+
state: 'IN'
|
|
413
|
+
)
|
|
414
|
+
assert_equal origin_address.to_hash, response.origin.to_hash
|
|
415
|
+
|
|
416
|
+
destination_address = ReactiveShipping::Location.new(
|
|
417
|
+
city: 'Miami',
|
|
418
|
+
country: 'US',
|
|
419
|
+
state: 'FL'
|
|
420
|
+
)
|
|
421
|
+
assert_equal destination_address.to_hash, response.destination.to_hash
|
|
422
|
+
|
|
423
|
+
assert_equal 11, response.shipment_events.length
|
|
424
|
+
assert_equal 'Delivered', response.latest_event.name
|
|
425
|
+
assert_equal 'PU', response.shipment_events.first.type_code
|
|
426
|
+
assert_equal 'OC', response.shipment_events.second.type_code
|
|
427
|
+
assert_equal 'AR', response.shipment_events.third.type_code
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
def test_tracking_info_for_delivered_at_door
|
|
431
|
+
mock_response = xml_fixture('fedex/tracking_response_delivered_at_door')
|
|
432
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
433
|
+
|
|
434
|
+
response = @carrier.find_tracking_info('403934084723025')
|
|
435
|
+
assert_equal '403934084723025', response.tracking_number
|
|
436
|
+
assert response.delivered?
|
|
437
|
+
refute response.exception?
|
|
438
|
+
assert_equal 10, response.shipment_events.length
|
|
439
|
+
assert_equal 'PU', response.shipment_events.first.type_code
|
|
440
|
+
assert_equal 'OC', response.shipment_events.second.type_code
|
|
441
|
+
assert_equal 'AR', response.shipment_events.third.type_code
|
|
442
|
+
assert_equal 'Delivered', response.latest_event.name
|
|
443
|
+
assert_equal 'DL', response.latest_event.type_code
|
|
444
|
+
assert_nil response.delivery_signature
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
def test_state_degrades_to_unknown
|
|
448
|
+
mock_response = xml_fixture('fedex/tracking_response_with_blank_state')
|
|
449
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
450
|
+
|
|
451
|
+
response = @carrier.find_tracking_info('798701052354')
|
|
452
|
+
|
|
453
|
+
destination_address = ReactiveShipping::Location.new(
|
|
454
|
+
city: 'SAITAMA',
|
|
455
|
+
country: 'Japan',
|
|
456
|
+
state: 'unknown'
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
assert_equal destination_address.to_hash, response.destination.to_hash
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
def test_tracking_info_for_in_transit
|
|
463
|
+
mock_response = xml_fixture('fedex/tracking_response_in_transit')
|
|
464
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
465
|
+
|
|
466
|
+
response = @carrier.find_tracking_info('123456789012')
|
|
467
|
+
refute response.delivered?
|
|
468
|
+
refute response.exception?
|
|
469
|
+
|
|
470
|
+
assert_equal '123456789012', response.tracking_number
|
|
471
|
+
assert_equal :fedex, response.carrier
|
|
472
|
+
assert_equal 'FedEx', response.carrier_name
|
|
473
|
+
assert_equal :in_transit, response.status
|
|
474
|
+
assert_equal 'IT', response.status_code
|
|
475
|
+
assert_equal "Package available for clearance", response.status_description
|
|
476
|
+
assert_nil response.delivery_signature
|
|
477
|
+
|
|
478
|
+
assert_equal Time.parse('2014-11-17T22:39:00+11:00'), response.ship_time
|
|
479
|
+
assert_nil response.scheduled_delivery_date
|
|
480
|
+
assert_nil response.actual_delivery_date
|
|
481
|
+
|
|
482
|
+
assert_nil response.origin
|
|
483
|
+
|
|
484
|
+
destination_address = ReactiveShipping::Location.new(
|
|
485
|
+
city: 'GRAFTON',
|
|
486
|
+
country: 'AU',
|
|
487
|
+
state: 'ON'
|
|
488
|
+
)
|
|
489
|
+
assert_equal destination_address.to_hash, response.destination.to_hash
|
|
490
|
+
|
|
491
|
+
assert_equal 1, response.shipment_events.length
|
|
492
|
+
assert_equal 'In transit', response.latest_event.name
|
|
493
|
+
assert_equal 'IT', response.latest_event.type_code
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
def test_tracking_info_for_shipment_exception
|
|
497
|
+
mock_response = xml_fixture('fedex/tracking_response_shipment_exception')
|
|
498
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
499
|
+
|
|
500
|
+
response = @carrier.find_tracking_info('957794015041323')
|
|
501
|
+
assert_equal '957794015041323', response.tracking_number
|
|
502
|
+
refute response.delivered?
|
|
503
|
+
assert response.exception?
|
|
504
|
+
assert_equal :exception, response.status
|
|
505
|
+
assert_equal "Unable to deliver", response.status_description
|
|
506
|
+
|
|
507
|
+
assert_equal Date.parse('2014-01-27'), response.ship_time
|
|
508
|
+
assert_nil response.scheduled_delivery_date
|
|
509
|
+
assert_nil response.actual_delivery_date
|
|
510
|
+
|
|
511
|
+
origin_address = ReactiveShipping::Location.new(
|
|
512
|
+
city: 'AUSTIN',
|
|
513
|
+
country: 'US',
|
|
514
|
+
state: 'TX'
|
|
515
|
+
)
|
|
516
|
+
assert_equal origin_address.to_hash, response.origin.to_hash
|
|
517
|
+
|
|
518
|
+
destination_address = ReactiveShipping::Location.new(
|
|
519
|
+
city: 'GOOSE CREEK',
|
|
520
|
+
country: 'US',
|
|
521
|
+
state: 'SC'
|
|
522
|
+
)
|
|
523
|
+
assert_equal destination_address.to_hash, response.destination.to_hash
|
|
524
|
+
|
|
525
|
+
assert_equal 8, response.shipment_events.length
|
|
526
|
+
assert_equal "Shipment exception", response.latest_event.name
|
|
527
|
+
assert_equal "SE", response.latest_event.type_code
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
def test_tracking_info_without_status
|
|
531
|
+
mock_response = xml_fixture('fedex/tracking_response_multiple_results')
|
|
532
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
533
|
+
|
|
534
|
+
error = assert_raises(ReactiveShipping::ResponseError) do
|
|
535
|
+
@carrier.find_tracking_info('123456789012')
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
msg = 'Multiple matches were found. Specify a unqiue identifier: 2456987000~123456789012~FX, 2456979001~123456789012~FX, 2456979000~123456789012~FX'
|
|
539
|
+
assert_equal msg, error.message
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
def test_tracking_info_with_unknown_tracking_number
|
|
543
|
+
mock_response = xml_fixture('fedex/tracking_response_not_found')
|
|
544
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
545
|
+
|
|
546
|
+
error = assert_raises(ReactiveShipping::ShipmentNotFound) do
|
|
547
|
+
@carrier.find_tracking_info('123456789013')
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
msg = 'This tracking number cannot be found. Please check the number or contact the sender.'
|
|
551
|
+
assert_equal msg, error.message
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
def test_tracking_info_with_bad_tracking_number
|
|
555
|
+
mock_response = xml_fixture('fedex/tracking_response_bad_tracking_number')
|
|
556
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
557
|
+
|
|
558
|
+
assert_raises(ReactiveShipping::ResponseError) do
|
|
559
|
+
@carrier.find_tracking_info('abc')
|
|
560
|
+
end
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
def test_tracking_info_with_uncovered_error
|
|
564
|
+
mock_response = xml_fixture('fedex/tracking_response_invalid_tracking_number')
|
|
565
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
566
|
+
|
|
567
|
+
error = assert_raises(ReactiveShipping::ResponseContentError) do
|
|
568
|
+
@carrier.find_tracking_info('123456789013')
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
msg = 'Invalid tracking numbers. Please check the following numbers and resubmit.'
|
|
572
|
+
assert_equal msg, error.message
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
def test_tracking_info_with_empty_status_detail
|
|
576
|
+
mock_response = xml_fixture('fedex/tracking_response_empty_status_detail')
|
|
577
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
578
|
+
response = @carrier.find_tracking_info('123456789012')
|
|
579
|
+
|
|
580
|
+
assert_equal '123456789012', response.tracking_number
|
|
581
|
+
assert_nil response.status_code
|
|
582
|
+
assert_nil response.status
|
|
583
|
+
assert_nil response.status_description
|
|
584
|
+
assert_nil response.delivery_signature
|
|
585
|
+
assert_empty response.shipment_events
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
def test_tracking_info_with_missing_status_code
|
|
589
|
+
mock_response = xml_fixture('fedex/tracking_response_missing_status_code')
|
|
590
|
+
@carrier.expects(:commit).returns(mock_response)
|
|
591
|
+
|
|
592
|
+
response = @carrier.find_tracking_info('123456789012')
|
|
593
|
+
assert_equal '123456789012', response.tracking_number
|
|
594
|
+
assert_nil response.status_code
|
|
595
|
+
assert_nil response.status
|
|
596
|
+
assert_nil response.status_description
|
|
597
|
+
assert_nil response.delivery_signature
|
|
598
|
+
assert_empty response.shipment_events
|
|
599
|
+
end
|
|
600
|
+
|
|
601
|
+
### create_shipment
|
|
602
|
+
|
|
603
|
+
def test_create_shipment
|
|
604
|
+
confirm_response = xml_fixture('fedex/create_shipment_response')
|
|
605
|
+
@carrier.stubs(:commit).returns(confirm_response)
|
|
606
|
+
|
|
607
|
+
response = @carrier.create_shipment(
|
|
608
|
+
location_fixtures[:beverly_hills],
|
|
609
|
+
location_fixtures[:new_york],
|
|
610
|
+
package_fixtures.values_at(:chocolate_stuff),
|
|
611
|
+
:test => true
|
|
612
|
+
)
|
|
613
|
+
|
|
614
|
+
# These assertions are to check that the xml fixture is extracted properly.
|
|
615
|
+
assert_equal 1, response.labels.count
|
|
616
|
+
assert_equal response.labels.first.tracking_number, "794637052920"
|
|
617
|
+
assert_equal response.labels.first.img_data.size, 8286
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
def test_create_shipment_signature_option
|
|
621
|
+
packages = package_fixtures.values_at(:chocolate_stuff)
|
|
622
|
+
packages.each {|p| p.options[:signature_option] = :indirect }
|
|
623
|
+
result = Nokogiri::XML(@carrier.send(:build_shipment_request,
|
|
624
|
+
location_fixtures[:beverly_hills],
|
|
625
|
+
location_fixtures[:annapolis],
|
|
626
|
+
packages,
|
|
627
|
+
:test => true))
|
|
628
|
+
assert_equal result.search('SpecialServicesRequested/SpecialServiceTypes').text, "SIGNATURE_OPTION"
|
|
629
|
+
assert_equal result.search('SpecialServicesRequested/SignatureOptionDetail').text.strip, "INDIRECT"
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
def test_create_shipment_reference
|
|
633
|
+
packages = package_fixtures.values_at(:wii)
|
|
634
|
+
packages.each do |p|
|
|
635
|
+
p.options[:reference_numbers] = [
|
|
636
|
+
{ :value => "FOO-123"},
|
|
637
|
+
{ :type => "INVOICE_NUMBER", :value => "BAR-456" }
|
|
638
|
+
]
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
result = Nokogiri::XML(@carrier.send(:build_shipment_request,
|
|
642
|
+
location_fixtures[:beverly_hills],
|
|
643
|
+
location_fixtures[:annapolis],
|
|
644
|
+
packages,
|
|
645
|
+
:test => true))
|
|
646
|
+
|
|
647
|
+
assert_equal result.search('RequestedPackageLineItems/CustomerReferences[first()]/Value').text, "FOO-123"
|
|
648
|
+
assert_equal result.search('RequestedPackageLineItems/CustomerReferences[first()]/CustomerReferenceType').text, "CUSTOMER_REFERENCE"
|
|
649
|
+
assert_equal result.search('RequestedPackageLineItems/CustomerReferences[last()]/Value').text, "BAR-456"
|
|
650
|
+
assert_equal result.search('RequestedPackageLineItems/CustomerReferences[last()]/CustomerReferenceType').text, "INVOICE_NUMBER"
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
def test_create_shipment_label_format_option
|
|
654
|
+
packages = package_fixtures.values_at(:chocolate_stuff)
|
|
655
|
+
result = Nokogiri::XML(@carrier.send(:build_shipment_request,
|
|
656
|
+
location_fixtures[:beverly_hills],
|
|
657
|
+
location_fixtures[:annapolis],
|
|
658
|
+
packages,
|
|
659
|
+
:label_format => 'ZPLII',
|
|
660
|
+
:test => true))
|
|
661
|
+
assert_equal result.search('RequestedShipment/LabelSpecification/ImageType').text, "ZPLII"
|
|
662
|
+
end
|
|
663
|
+
|
|
664
|
+
def test_create_shipment_default_label_stock_type
|
|
665
|
+
packages = package_fixtures.values_at(:wii)
|
|
666
|
+
|
|
667
|
+
result = Nokogiri::XML(@carrier.send(:build_shipment_request,
|
|
668
|
+
location_fixtures[:beverly_hills],
|
|
669
|
+
location_fixtures[:annapolis],
|
|
670
|
+
packages,
|
|
671
|
+
:test => true))
|
|
672
|
+
|
|
673
|
+
assert_equal result.search('RequestedShipment/LabelSpecification/LabelStockType').text, FedEx::DEFAULT_LABEL_STOCK_TYPE
|
|
674
|
+
end
|
|
675
|
+
|
|
676
|
+
def test_create_shipment_label_stock_type
|
|
677
|
+
label_stock_type = 'PAPER_4X6'
|
|
678
|
+
packages = package_fixtures.values_at(:wii)
|
|
679
|
+
|
|
680
|
+
result = Nokogiri::XML(@carrier.send(:build_shipment_request,
|
|
681
|
+
location_fixtures[:beverly_hills],
|
|
682
|
+
location_fixtures[:annapolis],
|
|
683
|
+
packages,
|
|
684
|
+
:test => true,
|
|
685
|
+
:label_stock_type => label_stock_type))
|
|
686
|
+
|
|
687
|
+
assert_equal result.search('RequestedShipment/LabelSpecification/LabelStockType').text, label_stock_type
|
|
688
|
+
end
|
|
689
|
+
|
|
690
|
+
def test_maximum_address_field_length
|
|
691
|
+
assert_equal 35, @carrier.maximum_address_field_length
|
|
692
|
+
end
|
|
693
|
+
end
|