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.
Files changed (247) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.travis.yml +33 -0
  4. data/.yardopts +13 -0
  5. data/CHANGELOG.md +225 -0
  6. data/CONTRIBUTING.md +23 -0
  7. data/Gemfile +3 -0
  8. data/MIT-LICENSE +21 -0
  9. data/README.md +158 -0
  10. data/Rakefile +35 -0
  11. data/dev.yml +17 -0
  12. data/gemfiles/activesupport42.gemfile +5 -0
  13. data/gemfiles/activesupport50.gemfile +6 -0
  14. data/gemfiles/activesupport51.gemfile +5 -0
  15. data/gemfiles/activesupport52.gemfile +5 -0
  16. data/gemfiles/activesupport_master.gemfile +5 -0
  17. data/lib/certs/eParcel.dtd +111 -0
  18. data/lib/reactive_shipping.rb +26 -0
  19. data/lib/reactive_shipping/address_validation_response.rb +30 -0
  20. data/lib/reactive_shipping/carrier.rb +184 -0
  21. data/lib/reactive_shipping/carriers.rb +35 -0
  22. data/lib/reactive_shipping/carriers/australia_post.rb +248 -0
  23. data/lib/reactive_shipping/carriers/benchmark_carrier.rb +31 -0
  24. data/lib/reactive_shipping/carriers/bogus_carrier.rb +12 -0
  25. data/lib/reactive_shipping/carriers/canada_post.rb +263 -0
  26. data/lib/reactive_shipping/carriers/canada_post_pws.rb +908 -0
  27. data/lib/reactive_shipping/carriers/fedex.rb +797 -0
  28. data/lib/reactive_shipping/carriers/kunaki.rb +155 -0
  29. data/lib/reactive_shipping/carriers/new_zealand_post.rb +260 -0
  30. data/lib/reactive_shipping/carriers/shipwire.rb +178 -0
  31. data/lib/reactive_shipping/carriers/stamps.rb +860 -0
  32. data/lib/reactive_shipping/carriers/ups.rb +1060 -0
  33. data/lib/reactive_shipping/carriers/usps.rb +708 -0
  34. data/lib/reactive_shipping/carriers/usps_returns.rb +86 -0
  35. data/lib/reactive_shipping/delivery_date_estimate.rb +20 -0
  36. data/lib/reactive_shipping/delivery_date_estimates_response.rb +11 -0
  37. data/lib/reactive_shipping/errors.rb +35 -0
  38. data/lib/reactive_shipping/external_return_label_request.rb +417 -0
  39. data/lib/reactive_shipping/external_return_label_response.rb +26 -0
  40. data/lib/reactive_shipping/label.rb +10 -0
  41. data/lib/reactive_shipping/label_response.rb +10 -0
  42. data/lib/reactive_shipping/location.rb +166 -0
  43. data/lib/reactive_shipping/package.rb +165 -0
  44. data/lib/reactive_shipping/package_item.rb +60 -0
  45. data/lib/reactive_shipping/rate_estimate.rb +197 -0
  46. data/lib/reactive_shipping/rate_response.rb +33 -0
  47. data/lib/reactive_shipping/response.rb +44 -0
  48. data/lib/reactive_shipping/shipment_event.rb +22 -0
  49. data/lib/reactive_shipping/shipment_packer.rb +108 -0
  50. data/lib/reactive_shipping/shipping_response.rb +34 -0
  51. data/lib/reactive_shipping/tracking_response.rb +120 -0
  52. data/lib/reactive_shipping/version.rb +3 -0
  53. data/reactive_shipping.gemspec +38 -0
  54. data/shipit.rubygems.yml +1 -0
  55. data/test/console.rb +39 -0
  56. data/test/credentials.yml +76 -0
  57. data/test/fixtures/files/label1.pdf +0 -0
  58. data/test/fixtures/files/ups-shipping-label.gif +0 -0
  59. data/test/fixtures/json/australia_post/calculate_domestic.json +13 -0
  60. data/test/fixtures/json/australia_post/calculate_domestic_2.json +19 -0
  61. data/test/fixtures/json/australia_post/calculate_international.json +12 -0
  62. data/test/fixtures/json/australia_post/calculate_international_2.json +15 -0
  63. data/test/fixtures/json/australia_post/error_message.json +5 -0
  64. data/test/fixtures/json/australia_post/service_domestic.json +117 -0
  65. data/test/fixtures/json/australia_post/service_domestic_2.json +117 -0
  66. data/test/fixtures/json/australia_post/service_international.json +76 -0
  67. data/test/fixtures/json/australia_post/service_international_2.json +59 -0
  68. data/test/fixtures/json/newzealandpost/domestic_book.json +1 -0
  69. data/test/fixtures/json/newzealandpost/domestic_default.json +1 -0
  70. data/test/fixtures/json/newzealandpost/domestic_error.json +1 -0
  71. data/test/fixtures/json/newzealandpost/domestic_poster.json +1 -0
  72. data/test/fixtures/json/newzealandpost/domestic_small_half_pound.json +1 -0
  73. data/test/fixtures/json/newzealandpost/international_book.json +1 -0
  74. data/test/fixtures/json/newzealandpost/international_new_zealand_wii.json +1 -0
  75. data/test/fixtures/json/newzealandpost/international_small_half_pound.json +1 -0
  76. data/test/fixtures/json/newzealandpost/international_wii.json +1 -0
  77. data/test/fixtures/xml/canadapost/example_request.xml +25 -0
  78. data/test/fixtures/xml/canadapost/example_response.xml +130 -0
  79. data/test/fixtures/xml/canadapost/example_response_error.xml +16 -0
  80. data/test/fixtures/xml/canadapost/example_response_french.xml +122 -0
  81. data/test/fixtures/xml/canadapost/example_response_with_nil_value.xml +164 -0
  82. data/test/fixtures/xml/canadapost/example_response_with_postal_outlet.xml +155 -0
  83. data/test/fixtures/xml/canadapost/example_response_with_postal_outlet_french.xml +274 -0
  84. data/test/fixtures/xml/canadapost/example_response_with_strange_delivery_date.xml +130 -0
  85. data/test/fixtures/xml/canadapost_pws/dnc_tracking_details_en.xml +112 -0
  86. data/test/fixtures/xml/canadapost_pws/merchant_details_error.xml +7 -0
  87. data/test/fixtures/xml/canadapost_pws/merchant_details_response.xml +7 -0
  88. data/test/fixtures/xml/canadapost_pws/option_response.xml +13 -0
  89. data/test/fixtures/xml/canadapost_pws/option_response_no_conflicts.xml +7 -0
  90. data/test/fixtures/xml/canadapost_pws/rates_info.xml +190 -0
  91. data/test/fixtures/xml/canadapost_pws/rates_info_error.xml +7 -0
  92. data/test/fixtures/xml/canadapost_pws/receipt_response.xml +42 -0
  93. data/test/fixtures/xml/canadapost_pws/receipt_response_no_priced_options.xml +36 -0
  94. data/test/fixtures/xml/canadapost_pws/register_token_error.xml +7 -0
  95. data/test/fixtures/xml/canadapost_pws/register_token_response.xml +3 -0
  96. data/test/fixtures/xml/canadapost_pws/service_options_response.xml +42 -0
  97. data/test/fixtures/xml/canadapost_pws/services_error.xml +6 -0
  98. data/test/fixtures/xml/canadapost_pws/services_response.xml +32 -0
  99. data/test/fixtures/xml/canadapost_pws/shipment_domestic.xml +69 -0
  100. data/test/fixtures/xml/canadapost_pws/shipment_response.xml +20 -0
  101. data/test/fixtures/xml/canadapost_pws/shipment_us.xml +69 -0
  102. data/test/fixtures/xml/canadapost_pws/tracking_details_en.xml +152 -0
  103. data/test/fixtures/xml/canadapost_pws/tracking_details_en_error.xml +7 -0
  104. data/test/fixtures/xml/canadapost_pws/tracking_details_en_undelivered.xml +116 -0
  105. data/test/fixtures/xml/canadapost_pws/tracking_details_fr.xml +156 -0
  106. data/test/fixtures/xml/canadapost_pws/tracking_details_no_expected_delivery_date.xml +40 -0
  107. data/test/fixtures/xml/fedex/create_shipment_response.xml +2 -0
  108. data/test/fixtures/xml/fedex/freight_rate_request.xml +82 -0
  109. data/test/fixtures/xml/fedex/freight_rate_response.xml +506 -0
  110. data/test/fixtures/xml/fedex/invalid_fedex_reply.xml +27 -0
  111. data/test/fixtures/xml/fedex/ottawa_to_beverly_hills_commercial_rate_request.xml +79 -0
  112. data/test/fixtures/xml/fedex/ottawa_to_beverly_hills_no_saturday_rate_request.xml +79 -0
  113. data/test/fixtures/xml/fedex/ottawa_to_beverly_hills_rate_request.xml +80 -0
  114. data/test/fixtures/xml/fedex/ottawa_to_beverly_hills_rate_response.xml +214 -0
  115. data/test/fixtures/xml/fedex/raterequest_reply.xml +213 -0
  116. data/test/fixtures/xml/fedex/raterequest_response_with_ground_home_delivery.xml +206 -0
  117. data/test/fixtures/xml/fedex/reply_without_notifications.xml +185 -0
  118. data/test/fixtures/xml/fedex/tracking_request.xml +29 -0
  119. data/test/fixtures/xml/fedex/tracking_response_bad_tracking_number.xml +20 -0
  120. data/test/fixtures/xml/fedex/tracking_response_delivered_at_door.xml +254 -0
  121. data/test/fixtures/xml/fedex/tracking_response_delivered_at_facility.xml +403 -0
  122. data/test/fixtures/xml/fedex/tracking_response_delivered_with_signature.xml +269 -0
  123. data/test/fixtures/xml/fedex/tracking_response_empty_status_detail.xml +84 -0
  124. data/test/fixtures/xml/fedex/tracking_response_failure_code_9045.xml +52 -0
  125. data/test/fixtures/xml/fedex/tracking_response_failure_code_9080.xml +51 -0
  126. data/test/fixtures/xml/fedex/tracking_response_in_transit.xml +127 -0
  127. data/test/fixtures/xml/fedex/tracking_response_invalid_tracking_number.xml +52 -0
  128. data/test/fixtures/xml/fedex/tracking_response_missing_status_code.xml +89 -0
  129. data/test/fixtures/xml/fedex/tracking_response_multiple_results.xml +100 -0
  130. data/test/fixtures/xml/fedex/tracking_response_not_found.xml +52 -0
  131. data/test/fixtures/xml/fedex/tracking_response_shipment_exception.xml +209 -0
  132. data/test/fixtures/xml/fedex/tracking_response_unable_to_process.xml +32 -0
  133. data/test/fixtures/xml/fedex/tracking_response_with_blank_state.xml +107 -0
  134. data/test/fixtures/xml/fedex/unknown_fedex_document_reply.xml +3 -0
  135. data/test/fixtures/xml/kunaki/invalid_state_response.xml +3 -0
  136. data/test/fixtures/xml/kunaki/no_valid_items_response.xml +3 -0
  137. data/test/fixtures/xml/kunaki/successful_rates_response.xml +3 -0
  138. data/test/fixtures/xml/kunaki/unsuccessful_rates_response.xml +9 -0
  139. data/test/fixtures/xml/shipwire/international_rates_response.xml +17 -0
  140. data/test/fixtures/xml/shipwire/new_carrier_rate_response.xml +18 -0
  141. data/test/fixtures/xml/shipwire/no_rates_response.xml +7 -0
  142. data/test/fixtures/xml/shipwire/rates_response.xml +36 -0
  143. data/test/fixtures/xml/shipwire/rates_response_no_estimate.xml +14 -0
  144. data/test/fixtures/xml/stamps/authenticate_user_request.xml +15 -0
  145. data/test/fixtures/xml/stamps/authenticate_user_response.xml +10 -0
  146. data/test/fixtures/xml/stamps/cleanse_address_request.xml +19 -0
  147. data/test/fixtures/xml/stamps/cleanse_address_response.xml +27 -0
  148. data/test/fixtures/xml/stamps/create_indicium_request.xml +69 -0
  149. data/test/fixtures/xml/stamps/create_indicium_response.xml +40 -0
  150. data/test/fixtures/xml/stamps/expired_authenticator_response.xml +15 -0
  151. data/test/fixtures/xml/stamps/get_account_info_request.xml +11 -0
  152. data/test/fixtures/xml/stamps/get_account_info_response.xml +36 -0
  153. data/test/fixtures/xml/stamps/get_purchase_status_request.xml +12 -0
  154. data/test/fixtures/xml/stamps/get_purchase_status_response.xml +16 -0
  155. data/test/fixtures/xml/stamps/get_rates_request.xml +19 -0
  156. data/test/fixtures/xml/stamps/get_rates_response.xml +351 -0
  157. data/test/fixtures/xml/stamps/purchase_postage_request.xml +13 -0
  158. data/test/fixtures/xml/stamps/purchase_postage_response.xml +17 -0
  159. data/test/fixtures/xml/stamps/track_shipment_request.xml +12 -0
  160. data/test/fixtures/xml/stamps/track_shipment_response.xml +45 -0
  161. data/test/fixtures/xml/ups/access_request.xml +6 -0
  162. data/test/fixtures/xml/ups/delivered_shipment_with_refund.xml +290 -0
  163. data/test/fixtures/xml/ups/delivered_shipment_without_events_tracking_response.xml +62 -0
  164. data/test/fixtures/xml/ups/delivery_dates_response.xml +140 -0
  165. data/test/fixtures/xml/ups/example_tracking_response.xml +53 -0
  166. data/test/fixtures/xml/ups/in_transit_shipment.xml +183 -0
  167. data/test/fixtures/xml/ups/out_for_delivery_shipment.xml +165 -0
  168. data/test/fixtures/xml/ups/package_exceeds_maximum_length.xml +12 -0
  169. data/test/fixtures/xml/ups/rate_single_service.xml +54 -0
  170. data/test/fixtures/xml/ups/rescheduled_shipment.xml +204 -0
  171. data/test/fixtures/xml/ups/shipment_accept_response.xml +42 -0
  172. data/test/fixtures/xml/ups/shipment_confirm_response.xml +33 -0
  173. data/test/fixtures/xml/ups/shipment_from_tiger_direct.xml +222 -0
  174. data/test/fixtures/xml/ups/test_real_home_as_residential_destination_response.xml +290 -0
  175. data/test/fixtures/xml/ups/test_real_home_as_residential_destination_response_with_insured.xml +289 -0
  176. data/test/fixtures/xml/ups/test_real_home_as_residential_destination_with_origin_account_response.xml +311 -0
  177. data/test/fixtures/xml/ups/tracking_request.xml +9 -0
  178. data/test/fixtures/xml/ups/triple_accept_response.xml +72 -0
  179. data/test/fixtures/xml/ups/triple_confirm_response.xml +32 -0
  180. data/test/fixtures/xml/ups/void_shipment_response.xml +11 -0
  181. data/test/fixtures/xml/usps/api_error_rate_response.xml +53 -0
  182. data/test/fixtures/xml/usps/beverly_hills_to_new_york_book_commercial_base_rate_response.xml +2 -0
  183. data/test/fixtures/xml/usps/beverly_hills_to_new_york_book_commercial_plus_rate_response.xml +258 -0
  184. data/test/fixtures/xml/usps/beverly_hills_to_new_york_book_rate_response.xml +108 -0
  185. data/test/fixtures/xml/usps/beverly_hills_to_ottawa_american_wii_commercial_base_rate_response.xml +84 -0
  186. data/test/fixtures/xml/usps/beverly_hills_to_ottawa_american_wii_commercial_plus_rate_response.xml +212 -0
  187. data/test/fixtures/xml/usps/beverly_hills_to_ottawa_american_wii_rate_response.xml +230 -0
  188. data/test/fixtures/xml/usps/first_class_packages_with_invalid_mail_type_response.xml +12 -0
  189. data/test/fixtures/xml/usps/first_class_packages_with_mail_type_response.xml +16 -0
  190. data/test/fixtures/xml/usps/first_class_packages_without_mail_type_response.xml +12 -0
  191. data/test/fixtures/xml/usps/invalid_xml_response.xml +10 -0
  192. data/test/fixtures/xml/usps/invalid_xml_tracking_response_error.xml +2 -0
  193. data/test/fixtures/xml/usps/tracking_request.xml +10 -0
  194. data/test/fixtures/xml/usps/tracking_request_batch.xml +12 -0
  195. data/test/fixtures/xml/usps/tracking_response.xml +162 -0
  196. data/test/fixtures/xml/usps/tracking_response_alt.xml +53 -0
  197. data/test/fixtures/xml/usps/tracking_response_batch.xml +231 -0
  198. data/test/fixtures/xml/usps/tracking_response_failure.xml +11 -0
  199. data/test/fixtures/xml/usps/tracking_response_not_available.xml +12 -0
  200. data/test/fixtures/xml/usps/tracking_response_test_error.xml +8 -0
  201. data/test/fixtures/xml/usps/us_rate_request.xml +18 -0
  202. data/test/fixtures/xml/usps/us_rate_request_large.xml +18 -0
  203. data/test/fixtures/xml/usps/world_rate_request_only_country.xml +22 -0
  204. data/test/fixtures/xml/usps/world_rate_request_with_value.xml +24 -0
  205. data/test/fixtures/xml/usps/world_rate_request_without_value.xml +24 -0
  206. data/test/fixtures/xml/usps_returns/external_return_label_response.xml +2 -0
  207. data/test/fixtures/xml/usps_returns/external_return_label_response_failure.xml +10 -0
  208. data/test/remote/australia_post_test.rb +140 -0
  209. data/test/remote/canada_post_pws_platform_test.rb +259 -0
  210. data/test/remote/canada_post_pws_test.rb +169 -0
  211. data/test/remote/canada_post_test.rb +55 -0
  212. data/test/remote/fedex_test.rb +400 -0
  213. data/test/remote/kunaki_test.rb +37 -0
  214. data/test/remote/new_zealand_post_test.rb +149 -0
  215. data/test/remote/shipwire_test.rb +84 -0
  216. data/test/remote/stamps_test.rb +396 -0
  217. data/test/remote/usps_returns_test.rb +72 -0
  218. data/test/remote/usps_test.rb +243 -0
  219. data/test/test_helper.rb +296 -0
  220. data/test/unit/carrier_test.rb +130 -0
  221. data/test/unit/carriers/australia_post_test.rb +181 -0
  222. data/test/unit/carriers/benchmark_test.rb +18 -0
  223. data/test/unit/carriers/canada_post_pws_rating_test.rb +379 -0
  224. data/test/unit/carriers/canada_post_pws_register_test.rb +76 -0
  225. data/test/unit/carriers/canada_post_pws_shipping_test.rb +258 -0
  226. data/test/unit/carriers/canada_post_pws_test.rb +59 -0
  227. data/test/unit/carriers/canada_post_pws_tracking_test.rb +154 -0
  228. data/test/unit/carriers/canada_post_test.rb +148 -0
  229. data/test/unit/carriers/fedex_test.rb +693 -0
  230. data/test/unit/carriers/kunaki_test.rb +56 -0
  231. data/test/unit/carriers/new_zealand_post_test.rb +177 -0
  232. data/test/unit/carriers/shipwire_test.rb +188 -0
  233. data/test/unit/carriers/stamps_test.rb +245 -0
  234. data/test/unit/carriers/ups_test.rb +580 -0
  235. data/test/unit/carriers/usps_returns_test.rb +45 -0
  236. data/test/unit/carriers/usps_test.rb +633 -0
  237. data/test/unit/carriers_test.rb +16 -0
  238. data/test/unit/external_return_label_request_test.rb +258 -0
  239. data/test/unit/location_test.rb +234 -0
  240. data/test/unit/package_item_test.rb +232 -0
  241. data/test/unit/package_test.rb +404 -0
  242. data/test/unit/rate_estimate_test.rb +93 -0
  243. data/test/unit/response_test.rb +38 -0
  244. data/test/unit/shipment_event_test.rb +20 -0
  245. data/test/unit/shipment_packer_test.rb +212 -0
  246. data/test/unit/tracking_response_test.rb +41 -0
  247. metadata +684 -0
@@ -0,0 +1,130 @@
1
+ require 'test_helper'
2
+
3
+ class CarrierTest < ActiveSupport::TestCase
4
+ class ExampleCarrier < Carrier
5
+ cattr_reader :name
6
+ @@name = "Example Carrier"
7
+ end
8
+
9
+ setup do
10
+ @carrier = ExampleCarrier.new
11
+ end
12
+
13
+ test "#find_rates is not implemented" do
14
+ assert_raises NotImplementedError do
15
+ @carrier.find_rates(nil, nil, nil)
16
+ end
17
+ end
18
+
19
+ test "#create_shipment is not implemented" do
20
+ assert_raises NotImplementedError do
21
+ @carrier.create_shipment(nil, nil, nil)
22
+ end
23
+ end
24
+
25
+ test "#cancel_shipment is not implemented" do
26
+ assert_raises NotImplementedError do
27
+ @carrier.cancel_shipment(nil)
28
+ end
29
+ end
30
+
31
+ test "#find_tracking_info is not implemented" do
32
+ assert_raises NotImplementedError do
33
+ @carrier.find_tracking_info(nil)
34
+ end
35
+ end
36
+
37
+ test "#available_services is not implemented" do
38
+ assert_raises NotImplementedError do
39
+ @carrier.available_services(nil, nil)
40
+ end
41
+ end
42
+
43
+ test "#maximum_weight returns a Measured::Weight" do
44
+ assert_equal Measured::Weight.new(150, :pounds), @carrier.maximum_weight
45
+ end
46
+
47
+ test "#maximum_address_field_length default value" do
48
+ assert_equal 255, @carrier.maximum_address_field_length
49
+ end
50
+
51
+ test "#requirements is an empty array" do
52
+ assert_equal [], @carrier.send(:requirements)
53
+ end
54
+
55
+ test "#timestamp_from_business_day returns nil without a day" do
56
+ assert_nil @carrier.send(:timestamp_from_business_day, nil)
57
+ end
58
+
59
+ test "#save_request caches the last request on the object" do
60
+ request = Object.new
61
+ assert_nil @carrier.last_request
62
+ @carrier.send(:save_request, request)
63
+ assert_equal request, @carrier.last_request
64
+ end
65
+
66
+ test "#timestamp_from_business_day returns two days in the future" do
67
+ current = DateTime.parse("Tue 19 Jul 2016")
68
+ expected = DateTime.parse("Thu 21 Jul 2016")
69
+
70
+ Timecop.freeze(current) do
71
+ assert_equal expected, @carrier.send(:timestamp_from_business_day, 2)
72
+ end
73
+ end
74
+
75
+ test "#timestamp_from_business_day returns two days in the future over a weekend" do
76
+ current = DateTime.parse("Fri 22 Jul 2016")
77
+ expected = DateTime.parse("Tue 26 Jul 2016")
78
+
79
+ Timecop.freeze(current) do
80
+ assert_equal expected, @carrier.send(:timestamp_from_business_day, 2)
81
+ end
82
+ end
83
+
84
+ test "#timestamp_from_business_day returns fifteen days in the future" do
85
+ current = DateTime.parse("Wed 06 Jul 2016")
86
+ expected = DateTime.parse("Wed 27 Jul 2016") # includes 3 weekends
87
+
88
+ Timecop.freeze(current) do
89
+ assert_equal expected, @carrier.send(:timestamp_from_business_day, 15)
90
+ end
91
+ end
92
+
93
+ test "#timestamp_from_business_day handles saturday" do
94
+ current = DateTime.parse("Sat 09 Jul 2016")
95
+ expected = DateTime.parse("Mon 11 Jul 2016")
96
+
97
+ Timecop.freeze(current) do
98
+ assert_equal expected, @carrier.send(:timestamp_from_business_day, 1)
99
+ end
100
+ end
101
+
102
+ test "#timestamp_from_business_day handles sunday" do
103
+ current = DateTime.parse("Sun 10 Jul 2016")
104
+ expected = DateTime.parse("Mon 11 Jul 2016")
105
+
106
+ Timecop.freeze(current) do
107
+ assert_equal expected, @carrier.send(:timestamp_from_business_day, 1)
108
+ end
109
+ end
110
+
111
+ test "#timestamp_from_business_day returns a DateTime" do
112
+ Timecop.freeze(DateTime.parse("Tue 19 Jul 2016")) do
113
+ assert_equal DateTime, @carrier.send(:timestamp_from_business_day, 1).class
114
+ end
115
+ end
116
+
117
+ test ".default_location is a valid address with defaults" do
118
+ result = Carrier.default_location
119
+
120
+ assert_equal Location, result.class
121
+ assert_equal ActiveUtils::Country.find("US"), result.country
122
+ assert_equal "CA", result.state
123
+ assert_equal "Beverly Hills", result.city
124
+ assert_equal "455 N. Rexford Dr.", result.address1
125
+ assert_equal "3rd Floor", result.address2
126
+ assert_equal "90210", result.zip
127
+ assert_equal "1-310-285-1013", result.phone
128
+ assert_equal "1-310-275-8159", result.fax
129
+ end
130
+ end
@@ -0,0 +1,181 @@
1
+ require 'test_helper'
2
+
3
+ class AustraliaPostTest < ActiveSupport::TestCase
4
+ include ReactiveShipping::Test::Fixtures
5
+
6
+ def setup
7
+ @carrier = AustraliaPost.new(api_key: '4d9dc0f0-dda0-012e-066f-000c29b44ac0')
8
+ @sydney = location_fixtures[:sydney]
9
+ @melbourne = location_fixtures[:melbourne]
10
+ @ottawa = location_fixtures[:ottawa]
11
+ end
12
+
13
+ def test_service_domestic_simple_request
14
+ url = 'https://digitalapi.auspost.com.au/postage/parcel/domestic/service.json?from_postcode=2000&height=2.0&length=19.0&to_postcode=3108&weight=0.25&width=14.0'
15
+ @carrier.expects(:commit).with(url).returns(json_fixture('australia_post/service_domestic'))
16
+ @carrier.find_rates(@sydney, @melbourne, package_fixtures[:book])
17
+ end
18
+
19
+ def test_service_domestic_combined_request
20
+ url_1 = 'https://digitalapi.auspost.com.au/postage/parcel/domestic/service.json?from_postcode=2000&height=2.0&length=19.0&to_postcode=3108&weight=0.25&width=14.0'
21
+ url_2 = 'https://digitalapi.auspost.com.au/postage/parcel/domestic/service.json?from_postcode=2000&height=2.54&length=2.54&to_postcode=3108&weight=0.23&width=2.54'
22
+ @carrier.expects(:commit).with(url_1).returns(json_fixture('australia_post/service_domestic'))
23
+ @carrier.expects(:commit).with(url_2).returns(json_fixture('australia_post/service_domestic_2'))
24
+ @carrier.find_rates(@sydney, @melbourne, package_fixtures.values_at(:book, :small_half_pound))
25
+ end
26
+
27
+ def test_service_domestic_simple_response
28
+ @carrier.expects(:commit).returns(json_fixture('australia_post/service_domestic'))
29
+ response = @carrier.find_rates(@sydney, @melbourne, package_fixtures[:book])
30
+ prices = [2855, 1480, 1615, 1340]
31
+ assert_equal prices, response.rates.map(&:price)
32
+ service_codes = ['AUS_PARCEL_EXPRESS', 'AUS_PARCEL_EXPRESS_SATCHEL_3KG', 'AUS_PARCEL_REGULAR', 'AUS_PARCEL_REGULAR_SATCHEL_3KG']
33
+ assert_equal service_codes, response.rates.map(&:service_code)
34
+ service_names = ['Express Post', 'Express Post Medium (3Kg) Satchel', 'Parcel Post', 'Parcel Post Medium Satchel']
35
+ assert_equal service_names, response.rates.map(&:service_name)
36
+ end
37
+
38
+ def test_service_domestic_combined_response
39
+ @carrier.expects(:commit).returns(json_fixture('australia_post/service_domestic'))
40
+ @carrier.expects(:commit).returns(json_fixture('australia_post/service_domestic_2'))
41
+ response = @carrier.find_rates(@sydney, @melbourne, package_fixtures.values_at(:book, :small_half_pound))
42
+ prices = [3875, 2360]
43
+ assert_equal prices, response.rates.map(&:price)
44
+ service_codes = ['AUS_PARCEL_EXPRESS', 'AUS_PARCEL_REGULAR']
45
+ assert_equal service_codes, response.rates.map(&:service_code)
46
+ service_names = ['Express Post', 'Parcel Post']
47
+ assert_equal service_names, response.rates.map(&:service_name)
48
+ end
49
+
50
+ def test_service_international_simple_request
51
+ url = 'https://digitalapi.auspost.com.au/postage/parcel/international/service.json?country_code=CA&weight=0.25'
52
+ @carrier.expects(:commit).with(url).returns(json_fixture('australia_post/service_international'))
53
+ @carrier.find_rates(@sydney, @ottawa, package_fixtures[:book])
54
+ end
55
+
56
+ def test_service_international_combined_request
57
+ url_1 = 'https://digitalapi.auspost.com.au/postage/parcel/international/service.json?country_code=CA&weight=0.25'
58
+ url_2 = 'https://digitalapi.auspost.com.au/postage/parcel/international/service.json?country_code=CA&weight=0.23'
59
+ @carrier.expects(:commit).with(url_1).returns(json_fixture('australia_post/service_international'))
60
+ @carrier.expects(:commit).with(url_2).returns(json_fixture('australia_post/service_international_2'))
61
+ @carrier.find_rates(@sydney, @ottawa, package_fixtures.values_at(:book, :small_half_pound))
62
+ end
63
+
64
+ def test_service_international_simple_response
65
+ @carrier.expects(:commit).returns(json_fixture('australia_post/service_international'))
66
+ response = @carrier.find_rates(@sydney, @ottawa, package_fixtures[:book])
67
+ prices = [15417, 8917, 8417, 4680]
68
+ assert_equal prices, response.rates.map(&:price)
69
+ service_codes = ['INT_PARCEL_COR_OWN_PACKAGING', 'INT_PARCEL_EXP_OWN_PACKAGING', 'INT_PARCEL_STD_OWN_PACKAGING', 'INT_PARCEL_SEA_OWN_PACKAGING']
70
+ assert_equal service_codes, response.rates.map(&:service_code)
71
+ service_names = ['Courier', 'Express', 'Standard', 'Economy Sea']
72
+ assert_equal service_names, response.rates.map(&:service_name)
73
+ end
74
+
75
+ def test_service_international_combined_response
76
+ @carrier.expects(:commit).returns(json_fixture('australia_post/service_international'))
77
+ @carrier.expects(:commit).returns(json_fixture('australia_post/service_international_2'))
78
+ response = @carrier.find_rates(@sydney, @melbourne, package_fixtures.values_at(:book, :small_half_pound))
79
+ prices = [17204, 15537, 8834]
80
+ assert_equal prices, response.rates.map(&:price)
81
+ service_codes = ['INT_PARCEL_EXP_OWN_PACKAGING', 'INT_PARCEL_STD_OWN_PACKAGING', 'INT_PARCEL_SEA_OWN_PACKAGING']
82
+ assert_equal service_codes, response.rates.map(&:service_code)
83
+ service_names = ['Express', 'Standard', 'Economy Sea']
84
+ assert_equal service_names, response.rates.map(&:service_name)
85
+ end
86
+
87
+ def test_service_response_error
88
+ error = assert_raises(ReactiveShipping::ResponseError) do
89
+ raise_error = ReactiveShipping::ResponseError.new
90
+ raise_error.expects(:response).returns(OpenStruct.new(body: json_fixture('australia_post/error_message')))
91
+ @carrier.expects(:ssl_get).raises raise_error
92
+ @carrier.find_rates(@sydney, @melbourne, package_fixtures[:book])
93
+ end
94
+ assert_equal 'Please enter From postcode.', error.response.message
95
+ end
96
+
97
+ def test_calculate_domestic_simple_request
98
+ url = 'https://digitalapi.auspost.com.au/postage/parcel/domestic/calculate.json?from_postcode=2000&height=2.0&length=19.0&service_code=AUS_PARCEL_EXPRESS&to_postcode=3108&weight=0.25&width=14.0'
99
+ @carrier.expects(:commit).with(url).returns(json_fixture('australia_post/calculate_domestic'))
100
+ @carrier.calculate_rates(@sydney, @melbourne, package_fixtures[:book], 'AUS_PARCEL_EXPRESS')
101
+ end
102
+
103
+ def test_calculate_domestic_combined_request
104
+ url_1 = 'https://digitalapi.auspost.com.au/postage/parcel/domestic/calculate.json?from_postcode=2000&height=2.0&length=19.0&service_code=AUS_PARCEL_EXPRESS&to_postcode=3108&weight=0.25&width=14.0'
105
+ url_2 = 'https://digitalapi.auspost.com.au/postage/parcel/domestic/calculate.json?from_postcode=2000&height=2.54&length=2.54&service_code=AUS_PARCEL_EXPRESS&to_postcode=3108&weight=0.23&width=2.54'
106
+ @carrier.expects(:commit).with(url_1).returns(json_fixture('australia_post/calculate_domestic'))
107
+ @carrier.expects(:commit).with(url_2).returns(json_fixture('australia_post/calculate_domestic_2'))
108
+ @carrier.calculate_rates(@sydney, @melbourne, package_fixtures.values_at(:book, :small_half_pound), 'AUS_PARCEL_EXPRESS')
109
+ end
110
+
111
+ def test_calculate_domestic_simple_response
112
+ @carrier.expects(:commit).returns(json_fixture('australia_post/calculate_domestic'))
113
+ response = @carrier.calculate_rates(@sydney, @melbourne, package_fixtures[:book], 'AUS_PARCEL_EXPRESS')
114
+ prices = [1020]
115
+ assert_equal prices, response.rates.map(&:price)
116
+ service_codes = ['AUS_PARCEL_EXPRESS']
117
+ assert_equal service_codes, response.rates.map(&:service_code)
118
+ service_names = ['Express Post']
119
+ assert_equal service_names, response.rates.map(&:service_name)
120
+ end
121
+
122
+ def test_calculate_domestic_combined_response
123
+ @carrier.expects(:commit).returns(json_fixture('australia_post/calculate_domestic'))
124
+ @carrier.expects(:commit).returns(json_fixture('australia_post/calculate_domestic_2'))
125
+ response = @carrier.calculate_rates(@sydney, @melbourne, package_fixtures.values_at(:book, :small_half_pound), 'AUS_PARCEL_EXPRESS')
126
+ prices = [2490]
127
+ assert_equal prices, response.rates.map(&:price)
128
+ service_codes = ['AUS_PARCEL_EXPRESS']
129
+ assert_equal service_codes, response.rates.map(&:service_code)
130
+ service_names = ['Express Post']
131
+ assert_equal service_names, response.rates.map(&:service_name)
132
+ end
133
+
134
+ def test_calculate_international_simple_request
135
+ url = 'https://digitalapi.auspost.com.au/postage/parcel/international/calculate.json?country_code=CA&service_code=INT_PARCEL_COR_OWN_PACKAGING&weight=0.25'
136
+ @carrier.expects(:commit).with(url).returns(json_fixture('australia_post/calculate_international'))
137
+ @carrier.calculate_rates(@sydney, @ottawa, package_fixtures[:book], 'INT_PARCEL_COR_OWN_PACKAGING')
138
+ end
139
+
140
+ def test_calculate_international_combined_request
141
+ url_1 = 'https://digitalapi.auspost.com.au/postage/parcel/international/calculate.json?country_code=CA&service_code=INT_PARCEL_COR_OWN_PACKAGING&weight=0.25'
142
+ url_2 = 'https://digitalapi.auspost.com.au/postage/parcel/international/calculate.json?country_code=CA&service_code=INT_PARCEL_COR_OWN_PACKAGING&weight=0.23'
143
+ @carrier.expects(:commit).with(url_1).returns(json_fixture('australia_post/calculate_international'))
144
+ @carrier.expects(:commit).with(url_2).returns(json_fixture('australia_post/calculate_international_2'))
145
+ @carrier.calculate_rates(@sydney, @ottawa, package_fixtures.values_at(:book, :small_half_pound), 'INT_PARCEL_COR_OWN_PACKAGING')
146
+ end
147
+
148
+ def test_calculate_international_simple_response
149
+ @carrier.expects(:commit).returns(json_fixture('australia_post/calculate_international'))
150
+ response = @carrier.calculate_rates(@sydney, @ottawa, package_fixtures[:book], 'INT_PARCEL_COR_OWN_PACKAGING')
151
+ prices = [8736]
152
+ assert_equal prices, response.rates.map(&:price)
153
+ service_codes = ['INT_PARCEL_COR_OWN_PACKAGING']
154
+ assert_equal service_codes, response.rates.map(&:service_code)
155
+ service_names = ['Courier']
156
+ assert_equal service_names, response.rates.map(&:service_name)
157
+ end
158
+
159
+ def test_calculate_international_combined_response
160
+ @carrier.expects(:commit).returns(json_fixture('australia_post/calculate_international'))
161
+ @carrier.expects(:commit).returns(json_fixture('australia_post/calculate_international_2'))
162
+ response = @carrier.calculate_rates(@sydney, @melbourne, package_fixtures.values_at(:book, :small_half_pound), 'INT_PARCEL_COR_OWN_PACKAGING')
163
+ prices = [17472]
164
+ assert_equal prices, response.rates.map(&:price)
165
+ service_codes = ['INT_PARCEL_COR_OWN_PACKAGING']
166
+ assert_equal service_codes, response.rates.map(&:service_code)
167
+ service_names = ['Courier']
168
+ assert_equal service_names, response.rates.map(&:service_name)
169
+ end
170
+
171
+ def test_calculate_response_error
172
+ error = assert_raises(ReactiveShipping::ResponseError) do
173
+ raise_error = ReactiveShipping::ResponseError.new
174
+ raise_error.expects(:response).returns(OpenStruct.new(body: json_fixture('australia_post/error_message')))
175
+ @carrier.expects(:ssl_get).raises raise_error
176
+ @carrier.calculate_rates(@sydney, @melbourne, package_fixtures[:book], 'AUS_PARCEL_EXPRESS')
177
+ end
178
+ assert_equal 'Please enter From postcode.', error.response.message
179
+ end
180
+
181
+ end
@@ -0,0 +1,18 @@
1
+ require 'test_helper'
2
+
3
+ class BenchmarkTest < ActiveSupport::TestCase
4
+ include ReactiveShipping::Test::Fixtures
5
+
6
+ def setup
7
+ @carrier = BenchmarkCarrier.new
8
+ end
9
+
10
+ def test_benchmark_response_is_valid
11
+ @carrier.stubs(:generate_simulated_lag).returns(0)
12
+ response = @carrier.find_rates(location_fixtures[:london], location_fixtures[:new_york], package_fixtures[:wii])
13
+ assert_equal 1, response.rates.count
14
+ rate = response.rates.first
15
+ assert_equal "Free Benchmark Shipping", rate.service_name
16
+ assert_equal 0, rate.price
17
+ end
18
+ end
@@ -0,0 +1,379 @@
1
+ require 'test_helper'
2
+
3
+ class CanadaPostPwsRatingTest < ActiveSupport::TestCase
4
+ include ReactiveShipping::Test::Fixtures
5
+
6
+ def setup
7
+ # 100 grams, 93 cm long, 10 cm diameter, cylinders have different volume calculations
8
+ @pkg1 = Package.new(25, [93, 10], :cylinder => true)
9
+ # 7.5 lbs, times 16 oz/lb., 15x10x4.5 inches, not grams, not centimetres
10
+ @pkg2 = Package.new((7.5 * 16), [15, 10, 4.5], :units => :imperial)
11
+
12
+ @home_params = {
13
+ :name => "John Smith",
14
+ :company => "test",
15
+ :phone => "613-555-1212",
16
+ :address1 => "123 Elm St.",
17
+ :city => 'Ottawa',
18
+ :province => 'ON',
19
+ :country => 'CA',
20
+ :postal_code => 'K1P 1J1'
21
+ }
22
+ @home = Location.new(@home_params)
23
+
24
+ @dest_params = {
25
+ :name => "Frank White",
26
+ :address1 => '999 Wiltshire Blvd',
27
+ :city => 'Beverly Hills',
28
+ :state => 'CA',
29
+ :country => 'US',
30
+ :zip => '90210'
31
+ }
32
+ @dest = Location.new(@dest_params)
33
+
34
+ @shipping_opts1 = {:dc => true, :cod => :true, :cod_amount => 50.00, :cod_includes_shipping => true,
35
+ :cod_method_of_payment => 'CSH', :cov => true, :cov_amount => 100.00,
36
+ :so => true, :pa18 => true}
37
+
38
+ @customer_number = '654321'
39
+
40
+ credentials = { platform_id: 123, api_key: '456', secret: '789' }
41
+ @cp = CanadaPostPWS.new(credentials)
42
+ @cp.logger = Logger.new(StringIO.new)
43
+ @french_cp = CanadaPostPWS.new(credentials.merge(language: 'fr'))
44
+ @cp_customer_number = CanadaPostPWS.new(credentials.merge(customer_number: @customer_number))
45
+
46
+ @default_options = {:customer_number => '123456'}
47
+ end
48
+
49
+ # rating
50
+
51
+ def test_language_header
52
+ assert_equal 'fr-CA', @french_cp.language
53
+ assert_equal 'en-CA', @cp.language
54
+ end
55
+
56
+ def test_name_accessor
57
+ assert_equal 'Canada Post PWS', @cp.name
58
+ end
59
+
60
+ def test_find_rates
61
+ response = xml_fixture('canadapost_pws/rates_info')
62
+ expected_headers = {
63
+ 'Authorization' => "#{@cp.send(:encoded_authorization)}",
64
+ 'Accept-Language' => 'en-CA',
65
+ 'Accept' => 'application/vnd.cpc.ship.rate+xml',
66
+ 'Content-Type' => 'application/vnd.cpc.ship.rate+xml'
67
+ }
68
+ CanadaPostPWS.any_instance.expects(:ssl_post).with(anything, anything, expected_headers).returns(response)
69
+
70
+ rates_response = @cp.find_rates(@home_params, @dest_params, [@pkg1, @pkg2], @default_options)
71
+
72
+ assert_equal 4, rates_response.rates.size
73
+ rate = rates_response.rates.first
74
+ assert_equal RateEstimate, rate.class
75
+ assert_equal "Canada Post PWS", rate.carrier
76
+ assert_equal @home.to_s, Location.new(rate.origin).to_s
77
+ assert_equal @dest.to_s, Location.new(rate.destination).to_s
78
+ end
79
+
80
+ def test_find_rates_with_error
81
+ response = xml_fixture('canadapost_pws/rates_info_error')
82
+ http_response = mock
83
+ http_response.stubs(:code).returns('400')
84
+ http_response.stubs(:body).returns(response)
85
+ response_error = ActiveUtils::ResponseError.new(http_response)
86
+ @cp.expects(:ssl_post).raises(response_error)
87
+
88
+ exception = assert_raises ReactiveShipping::ResponseError do
89
+ @cp.find_rates(@home_params, @dest_params, [@pkg1, @pkg2], @default_options)
90
+ end
91
+
92
+ assert_equal "You cannot mail on behalf of the requested customer.", exception.message
93
+ end
94
+
95
+ def test_find_rates_line_items_single_object
96
+ response = xml_fixture('canadapost_pws/rates_info')
97
+ expected_headers = {
98
+ 'Authorization' => "#{@cp.send(:encoded_authorization)}",
99
+ 'Accept-Language' => 'en-CA',
100
+ 'Accept' => 'application/vnd.cpc.ship.rate+xml',
101
+ 'Content-Type' => 'application/vnd.cpc.ship.rate+xml'
102
+ }
103
+ CanadaPostPWS.any_instance.expects(:ssl_post).with(anything, anything, expected_headers).returns(response)
104
+
105
+ rates_response = @cp.find_rates(@home_params, @dest_params, @pkg1, @default_options)
106
+
107
+ assert_equal 4, rates_response.rates.size
108
+ rate = rates_response.rates.first
109
+ assert_equal RateEstimate, rate.class
110
+ assert_equal "Canada Post PWS", rate.carrier
111
+ assert_equal @home.to_s, Location.new(rate.origin).to_s
112
+ assert_equal @dest.to_s, Location.new(rate.destination).to_s
113
+ end
114
+
115
+ def test_find_rates_excluding_tax
116
+ response = xml_fixture('canadapost_pws/rates_info')
117
+ expected_headers = {
118
+ 'Authorization' => "#{@cp.send(:encoded_authorization)}",
119
+ 'Accept-Language' => 'en-CA',
120
+ 'Accept' => 'application/vnd.cpc.ship.rate+xml',
121
+ 'Content-Type' => 'application/vnd.cpc.ship.rate+xml'
122
+ }
123
+ CanadaPostPWS.any_instance.expects(:ssl_post).with(anything, anything, expected_headers).returns(response).twice
124
+
125
+ rates_tax_response = @cp.find_rates(@home_params, @dest_params, [@pkg1, @pkg2], {})
126
+ rates_no_tax_response = @cp.find_rates(@home_params, @dest_params, [@pkg1, @pkg2], {exclude_tax: true})
127
+
128
+ expected = [139, 407, 139, 240] #taken from fixture, tax in centsÏ
129
+ assert_equal rates_no_tax_response.rates.size, rates_tax_response.rates.size
130
+ expected.zip(rates_no_tax_response.rates, rates_tax_response.rates).each do |expected, no_tax, tax|
131
+ assert_equal expected, tax.total_price - no_tax.total_price
132
+ end
133
+ end
134
+ # build rates
135
+
136
+ def test_build_rates_request
137
+ xml = @cp.build_rates_request(@home_params, @dest_params, [@pkg1, @pkg2], @default_options)
138
+ doc = Nokogiri.XML(xml)
139
+ doc.remove_namespaces!
140
+
141
+ assert_equal @default_options[:customer_number], doc.at('//customer-number').text
142
+ assert_equal 'K1P1J1', doc.at('//origin-postal-code').text
143
+ assert_equal 'united-states', doc.at('//destination/*').name
144
+ assert !doc.xpath('//parcel-characteristics').empty?
145
+ assert_equal "3.427", doc.at('//parcel-characteristics//weight').text
146
+ end
147
+
148
+ def test_build_rates_request_use_carrier_customer_number
149
+ xml = @cp_customer_number.build_rates_request(@home_params, @dest_params, [@pkg1, @pkg2])
150
+ doc = Nokogiri.XML(xml)
151
+ doc.remove_namespaces!
152
+
153
+ assert_equal @customer_number, doc.at('//customer-number').text
154
+ assert_equal 'K1P1J1', doc.at('//origin-postal-code').text
155
+ assert_equal 'united-states', doc.at('//destination/*').name
156
+ assert !doc.xpath('//parcel-characteristics').empty?
157
+ assert_equal "3.427", doc.at('//parcel-characteristics//weight').text
158
+ end
159
+
160
+ def test_build_rates_request_override_carrier_customer_number
161
+ xml = @cp_customer_number.build_rates_request(@home_params, @dest_params, [@pkg1, @pkg2], @default_options)
162
+ doc = Nokogiri.XML(xml)
163
+ doc.remove_namespaces!
164
+
165
+ assert_equal @default_options[:customer_number], doc.at('//customer-number').text
166
+ assert_equal 'K1P1J1', doc.at('//origin-postal-code').text
167
+ assert_equal 'united-states', doc.at('//destination/*').name
168
+ assert doc.at('//parcel-characteristics')
169
+ assert_equal "3.427", doc.at('//parcel-characteristics//weight').text
170
+ end
171
+
172
+ def test_build_rates_request_location_object
173
+ xml = @cp.build_rates_request(Location.new(@home_params), Location.new(@dest_params), [@pkg1, @pkg2], @default_options)
174
+ doc = Nokogiri.XML(xml)
175
+ doc.remove_namespaces!
176
+
177
+ assert_equal @default_options[:customer_number], doc.at('//customer-number').text
178
+ assert_equal 'K1P1J1', doc.at('//origin-postal-code').text
179
+ assert_equal 'united-states', doc.at('//destination/*').name
180
+ assert !doc.xpath('//parcel-characteristics').empty?
181
+ assert_equal "3.427", doc.at('//parcel-characteristics//weight').text
182
+ end
183
+
184
+ def test_build_rates_request_domestic
185
+ @dest_params = {
186
+ :name => "John Smith",
187
+ :company => "test",
188
+ :phone => "613-555-1212",
189
+ :address1 => "123 Oak St.",
190
+ :city => 'Vanncouver',
191
+ :province => 'BC',
192
+ :country => 'CA',
193
+ :postal_code => 'V5J 1J1'
194
+ }
195
+ xml = @cp.build_rates_request(@home_params, @dest_params, [@pkg1, @pkg2], @default_options)
196
+ doc = Nokogiri.XML(xml)
197
+ doc.remove_namespaces!
198
+
199
+ assert_equal 'K1P1J1', doc.at('//origin-postal-code').text
200
+ assert_equal 'domestic', doc.at('//destination/*').name
201
+ assert_equal 'V5J1J1', doc.at('//destination//postal-code').text
202
+ end
203
+
204
+ def test_build_rates_request_international
205
+ @dest_params = {
206
+ :name => "John Smith",
207
+ :company => "test",
208
+ :phone => "613-555-1212",
209
+ :address1 => "123 Tokyo St",
210
+ :city => 'Tokyo',
211
+ :country => 'JP'
212
+ }
213
+ xml = @cp.build_rates_request(@home_params, @dest_params, [@pkg1, @pkg2], @default_options)
214
+ doc = Nokogiri.XML(xml)
215
+ doc.remove_namespaces!
216
+
217
+ assert_equal 'K1P1J1', doc.xpath('//origin-postal-code').text
218
+ assert_equal 'international', doc.at('//destination/*').name
219
+ assert_equal 'JP', doc.at('//destination//country-code').text
220
+ end
221
+
222
+ def test_build_rates_request_with_cod_option
223
+ opts = @default_options.merge(:cod => true, :cod_amount => 12.05)
224
+ xml = @cp.build_rates_request(@home_params, @dest_params, [@pkg1, @pkg2], opts)
225
+ doc = Nokogiri.XML(xml)
226
+ doc.remove_namespaces!
227
+ assert_equal 'COD', doc.xpath('//options/option/option-code').text
228
+ assert_equal '12.05', doc.xpath('//options/option/option-amount').text
229
+ end
230
+
231
+ def test_build_rates_request_with_signature_option
232
+ opts = @default_options.merge(:so => true)
233
+ xml = @cp.build_rates_request(@home_params, @dest_params, [@pkg1, @pkg2], opts)
234
+ doc = Nokogiri.XML(xml)
235
+ doc.remove_namespaces!
236
+ assert_equal 'SO', doc.at('//options/option/option-code').text
237
+ end
238
+
239
+ def test_build_rates_request_with_insurance_option
240
+ opts = @default_options.merge(:cov => true, :cov_amount => 122.05)
241
+ xml = @cp.build_rates_request(@home_params, @dest_params, [@pkg1, @pkg2], opts)
242
+ doc = Nokogiri.XML(xml)
243
+ doc.remove_namespaces!
244
+ assert_equal 'COV', doc.at('//options/option/option-code').text
245
+ assert_equal '122.05', doc.at('//options/option/option-amount').text
246
+ end
247
+
248
+ def test_build_rates_request_with_other_options
249
+ opts = @default_options.merge(:pa18 => true, :pa19 => true, :hfp => true, :dns => true, :lad => true)
250
+ xml = @cp.build_rates_request(@home_params, @dest_params, [@pkg1, @pkg2], opts)
251
+ doc = Nokogiri.XML(xml)
252
+ doc.remove_namespaces!
253
+ options = doc.xpath('//options/option/option-code').map(&:text).sort
254
+ assert_equal %w(PA18 PA19 HFP DNS LAD).sort, options
255
+ end
256
+
257
+ def test_build_rates_request_with_single_item
258
+ opts = @default_options
259
+ xml = @cp.build_rates_request(@home_params, @dest_params, [@pkg1], opts)
260
+ doc = Nokogiri.XML(xml)
261
+ doc.remove_namespaces!
262
+ assert_equal '0.025', doc.at('//parcel-characteristics/weight').text
263
+ end
264
+
265
+ def test_build_rates_request_with_mailing_tube
266
+ pkg = Package.new(25, [93, 10], :cylinder => true)
267
+ opts = @default_options
268
+ xml = @cp.build_rates_request(@home_params, @dest_params, [pkg], opts)
269
+ doc = Nokogiri.XML(xml)
270
+ doc.remove_namespaces!
271
+ assert_equal 'true', doc.at('//parcel-characteristics/mailing-tube').text
272
+ end
273
+
274
+ def test_build_rates_request_with_oversize
275
+ pkg = Package.new(25, [93, 10], :oversized => true)
276
+ opts = @default_options
277
+ xml = @cp.build_rates_request(@home_params, @dest_params, [pkg], opts)
278
+ doc = Nokogiri.XML(xml)
279
+ doc.remove_namespaces!
280
+ assert_equal 'true', doc.at('//parcel-characteristics/oversized').text
281
+ end
282
+
283
+ def test_build_rates_request_with_unpackaged
284
+ pkg = Package.new(25, [93, 10], :unpackaged => true)
285
+ opts = @default_options
286
+ xml = @cp.build_rates_request(@home_params, @dest_params, [pkg], opts)
287
+ doc = Nokogiri.XML(xml)
288
+ doc.remove_namespaces!
289
+ assert_equal 'true', doc.at('//parcel-characteristics/unpackaged').text
290
+ end
291
+
292
+ def test_build_rates_request_with_zero_weight
293
+ options = @default_options.merge(@shipping_opts1)
294
+ line_items = [Package.new(0, [93, 10]), Package.new(0, [10, 10])]
295
+ xml = @cp.build_rates_request(@home_params, @dest_params, line_items, options)
296
+ doc = Nokogiri.XML(xml)
297
+ doc.remove_namespaces!
298
+ assert_equal '0.001', doc.at('//parcel-characteristics/weight').text
299
+ end
300
+
301
+ # parse response
302
+
303
+ def test_parse_rates_response
304
+ body = xml_fixture('canadapost_pws/rates_info')
305
+ rates_response = @cp.parse_rates_response(body, @home, @dest, false)
306
+
307
+ assert_equal 4, rates_response.rates.count
308
+ rate = rates_response.rates.first
309
+ assert_equal "DOM.EP", rate.service_code
310
+ assert_equal 'Expedited Parcel', rate.service_name
311
+ assert_equal @home, rate.origin
312
+ assert_equal @dest, rate.destination
313
+ assert_equal 1301, rate.total_price
314
+ end
315
+
316
+ def test_parse_rates_response_with_invalid_response_raises
317
+ body = xml_fixture('canadapost_pws/rates_info_error')
318
+ exception = assert_raises ReactiveShipping::ResponseError do
319
+ @response = @cp.parse_rates_response(body, @home, @dest, false)
320
+ end
321
+ assert_equal "No Quotes", exception.message
322
+ end
323
+
324
+ def test_parse_services_response
325
+ body = xml_fixture('canadapost_pws/services_response')
326
+ response = @cp.parse_services_response(body)
327
+ assert_equal 6, response.size
328
+ assert service = response['INT.PW.ENV']
329
+ assert_equal "Priority Worldwide envelope INT'L", service[:name]
330
+ end
331
+
332
+ def test_parse_find_service_options_response
333
+ body = xml_fixture('canadapost_pws/service_options_response')
334
+ response = @cp.parse_service_options_response(body)
335
+ assert_equal 3, response[:options].size
336
+ assert_equal 0, response[:restrictions][:min_weight]
337
+ assert_equal 30000, response[:restrictions][:max_weight]
338
+ assert_equal 0.1, response[:restrictions][:min_length]
339
+ assert_equal 0.1, response[:restrictions][:min_height]
340
+ assert_equal 0.1, response[:restrictions][:min_width]
341
+ assert_equal 150, response[:restrictions][:max_length]
342
+ assert_equal 150, response[:restrictions][:max_height]
343
+ assert_equal 150, response[:restrictions][:max_width]
344
+ end
345
+
346
+ def test_parse_find_option_response
347
+ body = xml_fixture('canadapost_pws/option_response')
348
+ response = @cp.parse_option_response(body)
349
+ assert_equal "SO", response[:code]
350
+ assert_equal "Signature option", response[:name]
351
+ assert_equal "FEAT", response[:class]
352
+ assert_equal true, response[:prints_on_label]
353
+ assert_equal false, response[:qualifier_required]
354
+ assert_equal 1, response[:conflicting_options].size
355
+ assert_equal "LAD", response[:conflicting_options][0]
356
+ assert_equal 1, response[:prerequisite_options].size
357
+ assert_equal "DC", response[:prerequisite_options][0]
358
+ end
359
+
360
+ def test_parse_find_option_response_no_conflicts_or_prereqs
361
+ body = xml_fixture('canadapost_pws/option_response_no_conflicts')
362
+ response = @cp.parse_option_response(body)
363
+ assert_equal "SO", response[:code]
364
+ assert_equal "Signature option", response[:name]
365
+ assert_equal "FEAT", response[:class]
366
+ assert_equal true, response[:prints_on_label]
367
+ assert_equal false, response[:qualifier_required]
368
+ assert response[:conflicting_options].blank?
369
+ assert response[:prerequisite_options].blank?
370
+ end
371
+
372
+ def test_error_response_includes_error_code
373
+ response = xml_fixture('canadapost_pws/rates_info_error')
374
+ e = assert_raises ReactiveShipping::ResponseError do
375
+ @cp.error_response(response, CPPWSRateResponse)
376
+ end
377
+ assert_equal 'AA004', e.response.error_code
378
+ end
379
+ end