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,76 @@
1
+ require 'test_helper'
2
+
3
+ class CanadaPostPwsRegisterTest < ActiveSupport::TestCase
4
+ include ReactiveShipping::Test::Fixtures
5
+
6
+ def setup
7
+ @cp = CanadaPostPWS.new(platform_id: 123, api_key: '456', secret: '789')
8
+ end
9
+
10
+ def test_register_merchant
11
+ endpoint = @cp.endpoint + "ot/token"
12
+ response = xml_fixture('canadapost_pws/register_token_response')
13
+ @cp.expects(:ssl_post).with(endpoint, anything, anything).returns(response)
14
+
15
+ response = @cp.register_merchant
16
+ assert response.is_a?(CPPWSRegisterResponse)
17
+ assert_equal "34536456345353534535", response.token_id
18
+ end
19
+
20
+ def test_register_merchant_with_error
21
+ endpoint = @cp.endpoint + "ot/token"
22
+ response = xml_fixture('canadapost_pws/register_token_error')
23
+ http_response = mock
24
+ http_response.stubs(:code).returns('400')
25
+ http_response.stubs(:body).returns(response)
26
+ response_error = ActiveUtils::ResponseError.new(http_response)
27
+ @cp.expects(:ssl_post).with(endpoint, anything, anything).raises(response_error)
28
+
29
+ exception = assert_raises ReactiveShipping::ResponseError do
30
+ @cp.register_merchant
31
+ end
32
+
33
+ assert_equal "Platform not active", exception.message
34
+ end
35
+
36
+ def test_register_response_redirect_url
37
+ endpoint = @cp.endpoint + "ot/token"
38
+ response = xml_fixture('canadapost_pws/register_token_response')
39
+ @cp.expects(:ssl_post).with(endpoint, anything, anything).returns(response)
40
+ url = 'http://localhost:3000/cp-register/'
41
+ customer_id = "12345"
42
+
43
+ response = @cp.register_merchant
44
+ assert_equal "http://www.canadapost.ca/cpotools/apps/drc/merchant?return-url=#{customer_id}&token-id=#{response.token_id}&platform-id=#{url}", response.redirect_url(url, customer_id)
45
+ end
46
+
47
+ def test_retrieve_merchant_details
48
+ endpoint = @cp.endpoint + "ot/token/1234567890"
49
+ response = xml_fixture('canadapost_pws/merchant_details_response')
50
+ @cp.expects(:ssl_get).with(endpoint, anything).returns(response)
51
+
52
+ response = @cp.retrieve_merchant_details(:token_id => '1234567890')
53
+ assert response.is_a?(CPPWSMerchantDetailsResponse)
54
+ assert_equal "1234567890", response.customer_number
55
+ assert_equal "1234567890-", response.contract_number
56
+ assert_equal "1234567890123456", response.username
57
+ assert_equal "12343567890123456789012", response.password
58
+ assert_equal false, response.has_default_credit_card
59
+ end
60
+
61
+ def test_retrieve_merchant_with_error
62
+ endpoint = @cp.endpoint + "ot/token/1234567890"
63
+ response = xml_fixture('canadapost_pws/merchant_details_error')
64
+ http_response = mock
65
+ http_response.stubs(:code).returns('400')
66
+ http_response.stubs(:body).returns(response)
67
+ response_error = ActiveUtils::ResponseError.new(http_response)
68
+ @cp.expects(:ssl_get).with(endpoint, anything).raises(response_error)
69
+
70
+ exception = assert_raises ReactiveShipping::ResponseError do
71
+ @cp.retrieve_merchant_details(:token_id => '1234567890')
72
+ end
73
+
74
+ assert_equal "Merchant Details Error", exception.message
75
+ end
76
+ end
@@ -0,0 +1,258 @@
1
+ require 'test_helper'
2
+ class CanadaPostPwsShippingTest < ActiveSupport::TestCase
3
+ include ReactiveShipping::Test::Fixtures
4
+
5
+ def setup
6
+ # 100 grams, 93 cm long, 10 cm diameter, cylinders have different volume calculations
7
+ @pkg1 = Package.new(25, [93, 10], :cylinder => true)
8
+
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
+ @line_item1 = line_item_fixture
13
+
14
+ @home_params = {
15
+ :name => "John Smith",
16
+ :company => "test",
17
+ :phone => "613-555-1212",
18
+ :address1 => "123 Elm St.",
19
+ :city => 'Ottawa',
20
+ :province => 'ON',
21
+ :country => 'CA',
22
+ :postal_code => 'K1P 1J1'
23
+ }
24
+
25
+ @dom_params = {
26
+ :name => "Mrs. Smith",
27
+ :company => "",
28
+ :phone => "604-555-1212",
29
+ :address1 => "5000 Oak St.",
30
+ :address2 => "",
31
+ :city => 'Vancouver',
32
+ :province => 'BC',
33
+ :country => 'CA',
34
+ :postal_code => 'V5J 2N2'
35
+ }
36
+
37
+ @us_params = {
38
+ :name => "John Smith",
39
+ :company => "test",
40
+ :phone => "613-555-1212",
41
+ :address1 => "123 Elm St.",
42
+ :address2 => "",
43
+ :city => 'Beverly Hills',
44
+ :province => 'CA',
45
+ :country => 'US',
46
+ :postal_code => '90210'
47
+ }
48
+
49
+ @paris_params = {
50
+ :name => "John Smith",
51
+ :company => "test",
52
+ :phone => "613-555-1212",
53
+ :address1 => "5 avenue Anatole France - Champ de Mars",
54
+ :address2 => "",
55
+ :city => 'Paris',
56
+ :province => '',
57
+ :country => 'FR',
58
+ :postal_code => '75007'
59
+ }
60
+
61
+ @shipping_opts1 = {:dc => true, :cod => :true, :cod_amount => 50.00, :cod_includes_shipping => true,
62
+ :cod_method_of_payment => 'CSH', :cov => true, :cov_amount => 100.00,
63
+ :so => true, :pa18 => true}
64
+
65
+ @default_options = {:customer_number => '123456'}
66
+
67
+ @DEFAULT_RESPONSE = {
68
+ :shipping_id => "406951321983787352",
69
+ :tracking_number => "11111118901234",
70
+ :label_url => "https://ct.soa-gw.canadapost.ca/ers/artifact/c70da5ed5a0d2c32/20238/0"
71
+ }
72
+
73
+ @cp = CanadaPostPWS.new(platform_id: 123, api_key: '456', secret: '789')
74
+ end
75
+
76
+ def test_build_shipment_customs_node
77
+ options = @default_options.dup
78
+ destination = Location.new(@us_params)
79
+ builder = Nokogiri::XML::Builder.new do |xml|
80
+ response = @cp.shipment_customs_node(xml, destination, @line_item1, options)
81
+ end
82
+ doc = builder.doc
83
+ assert root_node = doc.at('customs')
84
+ assert_equal "CAD", root_node.at('currency').text
85
+ assert items_node = root_node.at('sku-list')
86
+ assert_equal 2, items_node.xpath('item').size
87
+ assert_equal 199.0, items_node.at('item/customs-value-per-unit').text.to_f
88
+ end
89
+
90
+ def test_build_shipment_request_for_domestic
91
+ options = @default_options.dup
92
+ request = @cp.build_shipment_request(@home_params, @dom_params, @pkg1, @line_item1, options)
93
+ refute request.blank?
94
+ end
95
+
96
+ def test_build_shipment_request_for_US
97
+ options = @default_options.dup
98
+ request = @cp.build_shipment_request(@home_params, @us_params, @pkg1, @line_item1, options)
99
+ refute request.blank?
100
+
101
+ doc = Nokogiri.XML(request)
102
+ doc.remove_namespaces!
103
+
104
+ assert root_node = doc.at('non-contract-shipment')
105
+ assert delivery_spec = root_node.at('delivery-spec')
106
+ assert destination = delivery_spec.at('destination')
107
+ assert address_details = destination.at('address-details')
108
+ assert_equal 'US', address_details.at('country-code').text
109
+ end
110
+
111
+ def test_build_shipment_request_for_international
112
+ options = @default_options.dup
113
+ request = @cp.build_shipment_request(@home_params, @paris_params, @pkg1, @line_item1, options)
114
+ refute request.blank?
115
+ end
116
+
117
+ def test_build_shipment_request_location_object
118
+ options = @default_options.dup
119
+ request = @cp.build_shipment_request(Location.new(@home_params), Location.new(@dom_params), @pkg1, @line_item1, options)
120
+ refute request.blank?
121
+ end
122
+
123
+ def test_create_shipment_request_with_options
124
+ options = @default_options.merge(@shipping_opts1)
125
+ request = @cp.build_shipment_request(@home_params, @paris_params, @pkg1, @line_item1, options)
126
+ refute request.blank?
127
+
128
+ doc = Nokogiri.XML(request)
129
+ doc.remove_namespaces!
130
+
131
+ assert root_node = doc.at('non-contract-shipment')
132
+ assert delivery_spec = root_node.at('delivery-spec')
133
+ assert options = delivery_spec.at('options')
134
+ assert_equal 5, options.xpath('*').size
135
+ end
136
+
137
+ def test_build_shipping_request_with_zero_weight
138
+ options = @default_options.merge(@shipping_opts1)
139
+ package = Package.new(0, [93, 10])
140
+ request = @cp.build_shipment_request(@home_params, @dom_params, package, @line_item1, options)
141
+ refute request.blank?
142
+
143
+ doc = Nokogiri.XML(request)
144
+ doc.remove_namespaces!
145
+
146
+ assert root_node = doc.at('non-contract-shipment')
147
+ assert delivery_spec = root_node.at('delivery-spec')
148
+ assert parcel_node = delivery_spec.at('parcel-characteristics')
149
+ assert_equal '0.001', parcel_node.at('weight').text
150
+ end
151
+
152
+ def test_create_shipment_domestic
153
+ options = @default_options.dup
154
+ response = xml_fixture('canadapost_pws/shipment_response')
155
+ @cp.expects(:ssl_post).once.returns(response)
156
+ response = @cp.create_shipment(@home_params, @dom_params, @pkg1, @line_item1, options)
157
+ assert response.is_a?(CPPWSShippingResponse)
158
+ assert_equal @DEFAULT_RESPONSE[:shipping_id], response.shipping_id
159
+ assert_equal @DEFAULT_RESPONSE[:tracking_number], response.tracking_number
160
+ assert_equal @DEFAULT_RESPONSE[:label_url], response.label_url
161
+ end
162
+
163
+ def test_create_shipment_us
164
+ options = @default_options.dup
165
+ response = xml_fixture('canadapost_pws/shipment_response')
166
+ @cp.expects(:ssl_post).once.returns(response)
167
+ response = @cp.create_shipment(@home_params, @us_params, @pkg1, @line_item1, options)
168
+ assert response.is_a?(CPPWSShippingResponse)
169
+ assert_equal @DEFAULT_RESPONSE[:shipping_id], response.shipping_id
170
+ assert_equal @DEFAULT_RESPONSE[:tracking_number], response.tracking_number
171
+ assert_equal @DEFAULT_RESPONSE[:label_url], response.label_url
172
+ end
173
+
174
+ def test_create_shipment_international
175
+ options = @default_options.dup
176
+ response = xml_fixture('canadapost_pws/shipment_response')
177
+ @cp.expects(:ssl_post).once.returns(response)
178
+ response = @cp.create_shipment(@home_params, @us_params, @pkg1, @line_item1, options)
179
+ assert response.is_a?(CPPWSShippingResponse)
180
+ assert_equal @DEFAULT_RESPONSE[:shipping_id], response.shipping_id
181
+ assert_equal @DEFAULT_RESPONSE[:tracking_number], response.tracking_number
182
+ assert_equal @DEFAULT_RESPONSE[:label_url], response.label_url
183
+ end
184
+
185
+ def test_retrieve_shipping_label
186
+ shipping_response = CPPWSShippingResponse.new(true, '', {}, @DEFAULT_RESPONSE)
187
+ @cp.expects(:ssl_get).once.returns(file_fixture('label1.pdf'))
188
+ response = @cp.retrieve_shipping_label(shipping_response)
189
+ assert_equal "%PDF", response[0...4]
190
+ end
191
+
192
+ def test_retrieve_shipment
193
+ options = @default_options.dup
194
+ shipping_response = CPPWSShippingResponse.new(true, '', {}, @DEFAULT_RESPONSE)
195
+ response = xml_fixture('canadapost_pws/shipment_response')
196
+ @cp.expects(:ssl_post).once.returns(response)
197
+ response = @cp.retrieve_shipment(shipping_response.shipping_id, options)
198
+ assert response.is_a?(CPPWSShippingResponse)
199
+ assert_equal @DEFAULT_RESPONSE[:shipping_id], response.shipping_id
200
+ assert_equal @DEFAULT_RESPONSE[:tracking_number], response.tracking_number
201
+ assert_equal @DEFAULT_RESPONSE[:label_url], response.label_url
202
+ end
203
+
204
+ def test_parse_find_shipment_receipt_response
205
+ body = xml_fixture('canadapost_pws/receipt_response')
206
+ response = @cp.parse_shipment_receipt_response(body)
207
+ assert_equal "J4W4T0", response[:final_shipping_point]
208
+ assert_equal "BP BROSSARD", response[:shipping_point_name]
209
+ assert_equal "DOM.EP", response[:service_code]
210
+ assert_equal 15.000, response[:rated_weight]
211
+ assert_equal 18.10, response[:base_amount]
212
+ assert_equal 19.46, response[:pre_tax_amount]
213
+ assert_equal 0.00, response[:gst_amount]
214
+ assert_equal 0.00, response[:pst_amount]
215
+ assert_equal 2.53, response[:hst_amount]
216
+ assert_equal 1, response[:priced_options].size
217
+ assert_equal 0.0, response[:priced_options]['DC']
218
+ assert_equal 21.99, response[:charge_amount]
219
+ assert_equal 'CAD', response[:currency]
220
+ assert_equal 1, response[:expected_transit_days]
221
+ assert_equal '2012-03-14', response[:expected_delivery_date]
222
+ end
223
+
224
+ def test_find_shipment_receipt
225
+ options = @default_options.dup
226
+ xml_response = xml_fixture('canadapost_pws/receipt_response')
227
+ @cp.expects(:ssl_get).once.returns(xml_response)
228
+ response = @cp.find_shipment_receipt('1234567', options)
229
+ assert_equal @cp.parse_shipment_receipt_response(xml_response), response
230
+ end
231
+
232
+ def test_character_limit_on_customs_description
233
+ @line_item1.first.stubs(:name).returns("Some super long description that exceeds the 44 character limit")
234
+ options = @default_options.dup
235
+
236
+ response = xml_fixture('canadapost_pws/shipment_response')
237
+ @cp.expects(:ssl_post).with do |_url, request|
238
+ request_hash = Hash.from_xml(request)
239
+
240
+ assert_equal 44, request_hash['non_contract_shipment']['delivery_spec']['customs']['sku_list']['item'].first['customs_description'].length
241
+ true
242
+ end.once.returns(response)
243
+
244
+ response = @cp.create_shipment(@home_params, @us_params, @pkg1, @line_item1, options)
245
+ assert response.is_a?(CPPWSShippingResponse)
246
+ end
247
+
248
+ def test_parse_find_shipment_receipt_doesnt_break_without_priced_options
249
+ body = xml_fixture('canadapost_pws/receipt_response_no_priced_options')
250
+ response = @cp.parse_shipment_receipt_response(body)
251
+
252
+ assert_equal 0, response[:priced_options].size
253
+ end
254
+
255
+ def test_maximum_address_field_length
256
+ assert_equal 44, @cp.maximum_address_field_length
257
+ end
258
+ end
@@ -0,0 +1,59 @@
1
+ require 'test_helper'
2
+
3
+ class CanadaPostPwsTest < ActiveSupport::TestCase
4
+
5
+ def setup
6
+ credentials = { platform_id: 123, api_key: '456', secret: '789' }
7
+ @cp = CanadaPostPWS.new(credentials)
8
+ end
9
+
10
+ def test_get_sanitized_postal_code_location_nil
11
+ postal_code = @cp.send(:get_sanitized_postal_code, nil)
12
+
13
+ assert_equal nil, postal_code
14
+ end
15
+
16
+ def test_get_sanitized_postal_code_postal_code_nil
17
+ location = Location.new(name: 'Test test')
18
+
19
+ assert_equal nil, location.postal_code
20
+
21
+ postal_code = @cp.send(:get_sanitized_postal_code, location)
22
+
23
+ assert_equal nil, postal_code
24
+ end
25
+
26
+ def test_get_sanitized_postal_code_spaces
27
+ location = Location.new(postal_code: ' K2P 1L4 ')
28
+
29
+ postal_code = @cp.send(:get_sanitized_postal_code, location)
30
+
31
+ assert_equal 'K2P1L4', postal_code
32
+ end
33
+
34
+ def test_get_sanitized_postal_code_lowercase
35
+ location = Location.new(postal_code: 'k2p 1l4')
36
+
37
+ postal_code = @cp.send(:get_sanitized_postal_code, location)
38
+
39
+ assert_equal 'K2P1L4', postal_code
40
+ end
41
+
42
+ def test_get_sanitzied_postal_code_proper
43
+ location = Location.new(postal_code: 'K2P1L4')
44
+
45
+ postal_code = @cp.send(:get_sanitized_postal_code, location)
46
+
47
+ assert_equal 'K2P1L4', postal_code
48
+ end
49
+
50
+ def test_get_sanitzied_postal_code_does_not_alter_original
51
+ location = Location.new(postal_code: 'K2P 1l4')
52
+
53
+ assert_equal 'K2P 1l4', location.postal_code
54
+
55
+ @cp.send(:get_sanitized_postal_code, location)
56
+
57
+ assert_equal 'K2P 1l4', location.postal_code
58
+ end
59
+ end
@@ -0,0 +1,154 @@
1
+ require 'test_helper'
2
+
3
+ class CanadaPostPwsTrackingTest < 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 = Location.new(
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 => 'K1P1J1'
21
+ )
22
+
23
+ @dest = Location.new(
24
+ :name => "Frank White",
25
+ :address1 => '999 Wiltshire Blvd',
26
+ :city => 'Beverly Hills',
27
+ :state => 'CA',
28
+ :country => 'US',
29
+ :zip => '90210'
30
+ )
31
+
32
+ @cp = CanadaPostPWS.new(platform_id: 123, api_key: '456', secret: '789')
33
+ end
34
+
35
+ def test_find_tracking_info_with_valid_pin
36
+ pin = '1371134583769923'
37
+ endpoint = @cp.endpoint + "vis/track/pin/%s/detail" % pin
38
+ response = xml_fixture('canadapost_pws/tracking_details_en')
39
+ @cp.expects(:ssl_get).with(endpoint, anything).returns(response)
40
+
41
+ response = @cp.find_tracking_info(pin)
42
+ assert response.is_a?(CPPWSTrackingResponse)
43
+ end
44
+
45
+ def test_find_tracking_info_with_15_digit_dnc
46
+ dnc = "315052413796541"
47
+ endpoint = @cp.endpoint + "vis/track/dnc/%s/detail" % dnc
48
+ response = xml_fixture('canadapost_pws/dnc_tracking_details_en')
49
+ @cp.expects(:ssl_get).with(endpoint, anything).returns(response)
50
+
51
+ response = @cp.find_tracking_info(dnc)
52
+ assert response.is_a?(CPPWSTrackingResponse)
53
+ end
54
+
55
+ def test_find_tracking_info_when_pin_doesnt_exist
56
+ pin = '1371134583769924'
57
+ response = xml_fixture('canadapost_pws/tracking_details_en_error')
58
+ http_response = mock
59
+ http_response.stubs(:code).returns('400')
60
+ http_response.stubs(:body).returns(response)
61
+ response_error = ActiveUtils::ResponseError.new(http_response)
62
+ @cp.expects(:ssl_get).raises(response_error)
63
+
64
+ exception = assert_raises ReactiveShipping::ResponseError do
65
+ @cp.find_tracking_info(pin)
66
+ end
67
+
68
+ assert_equal "No Pin History", exception.message
69
+ end
70
+
71
+ def test_find_tracking_info_with_invalid_pin_format
72
+ pin = '123'
73
+ @cp.expects(:ssl_get).never
74
+
75
+ exception = assert_raises ReactiveShipping::ResponseError do
76
+ @cp.find_tracking_info(pin)
77
+ end
78
+ assert_equal "Invalid Pin Format", exception.message
79
+ end
80
+
81
+ # parse_tracking_response
82
+
83
+ def test_parse_tracking_response
84
+ @response = xml_fixture('canadapost_pws/tracking_details_en')
85
+ @cp.expects(:ssl_get).returns(@response)
86
+
87
+ response = @cp.find_tracking_info('1371134583769923', {})
88
+
89
+ assert_equal CPPWSTrackingResponse, response.class
90
+ assert_equal "Xpresspost", response.service_name
91
+ assert_equal Date.parse("2011-02-01"), response.expected_date
92
+ assert_equal "Customer addressing error found; attempting to correct", response.change_reason
93
+ assert_equal "1371134583769923", response.tracking_number
94
+ assert_equal 10, response.shipment_events.size
95
+
96
+ assert_equal response.origin.city, "LACHINE"
97
+ assert_equal response.origin.province, "QC"
98
+
99
+ assert response.origin.is_a?(Location)
100
+ assert response.destination.is_a?(Location)
101
+ assert_equal "G1K4M7", response.destination.to_s
102
+ assert_equal "0001371134", response.customer_number
103
+ assert_equal true, response.delivered?
104
+ assert_equal Time.parse('2011-02-03 16:59:59 UTC'), response.actual_delivery_time
105
+ end
106
+
107
+ def test_parse_tracking_response_no_expected_delivery_date
108
+ @response = xml_fixture('canadapost_pws/tracking_details_no_expected_delivery_date')
109
+ @cp.expects(:ssl_get).returns(@response)
110
+
111
+ response = @cp.find_tracking_info('1371134583769923', {})
112
+
113
+ assert_equal CPPWSTrackingResponse, response.class
114
+ assert_equal "Expedited Parcels", response.service_name
115
+ assert_nil response.expected_date
116
+ assert_equal "8213295707205355", response.tracking_number
117
+ assert_equal 1, response.shipment_events.size
118
+ assert_equal response.origin.city, "MAPLE"
119
+ assert_equal response.origin.province, "ON"
120
+ assert response.origin.is_a?(Location)
121
+ assert response.destination.is_a?(Location)
122
+ assert_equal "J7Y0E4", response.destination.to_s
123
+ assert_equal "0008213295", response.customer_number
124
+ assert_equal false, response.delivered?
125
+ end
126
+
127
+ def test_parse_undelivered_tracking_response
128
+ @response = xml_fixture('canadapost_pws/tracking_details_en_undelivered')
129
+ @cp.expects(:ssl_get).returns(@response)
130
+ response = @cp.find_tracking_info('1371134583769923', {})
131
+
132
+ assert_equal false, response.delivered?
133
+ assert_nil response.actual_delivery_time
134
+ end
135
+
136
+ def test_parse_tracking_response_shipment_events
137
+ @response = xml_fixture('canadapost_pws/tracking_details_en')
138
+ @cp.expects(:ssl_get).returns(@response)
139
+
140
+ response = @cp.find_tracking_info('1371134583769923', {})
141
+ events = response.shipment_events
142
+
143
+ event = events.first
144
+ assert_equal ShipmentEvent, event.class
145
+ assert_equal "1496", event.name
146
+ assert_equal "SAINTE-FOY, QC", event.location
147
+ assert event.time.is_a?(Time)
148
+ assert_equal "Item successfully delivered", event.message
149
+
150
+ timestamps = events.map(&:time)
151
+ ordered = timestamps.dup.sort.reverse # newest => oldest
152
+ assert_equal ordered, timestamps
153
+ end
154
+ end