reactive_shipping 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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,232 @@
1
+ require 'test_helper'
2
+
3
+ class PackageItemTest < ActiveSupport::TestCase
4
+ setup do
5
+ @name = "Fancy Pants"
6
+ @weight = 100
7
+ @value = 1299
8
+ @quantity = 3
9
+ @sku = "1234567890"
10
+ @hs_code = "1234.56.78"
11
+ @options = {
12
+ units: :metric,
13
+ sku: @sku,
14
+ hs_code: @hs_code,
15
+ type: :actual,
16
+ }
17
+
18
+ @item = PackageItem.new(@name, @weight, @value, @quantity, @options)
19
+ @mass = Measured::Weight.new(@weight, :grams)
20
+ end
21
+
22
+ test "#initialize with all attributes" do
23
+ assert_equal @name, @item.name
24
+ assert_equal @options, @item.options
25
+ assert_equal @hs_code, @item.hs_code
26
+ assert_equal @sku, @item.sku
27
+ assert_equal @value, @item.value
28
+ assert_equal @quantity, @item.quantity
29
+ end
30
+
31
+ test "#initialize assumes symbol keys" do
32
+ options = {
33
+ "units" => :imperial,
34
+ "sku" => @sku,
35
+ "hs_code" => @hs_code,
36
+ }
37
+ @item = PackageItem.new(@name, @weight, @value, @quantity, options)
38
+
39
+ assert_nil @item.hs_code
40
+ assert_nil @item.sku
41
+ refute_equal @weight, @item.ounces
42
+ assert_equal @weight, @item.grams
43
+ end
44
+
45
+ test "#initialize with a negative quantity" do
46
+ assert_equal 1, PackageItem.new(@name, @weight, @value, -1).quantity
47
+ assert_equal 1, PackageItem.new(@name, @weight, @value, 0).quantity
48
+ end
49
+
50
+ test "#initialize weight mass object" do
51
+ @item = PackageItem.new(@name, @mass, @value, @quantity, @options)
52
+ assert_equal @mass, @item.weight
53
+ end
54
+
55
+ test "#initialize weight default metric" do
56
+ assert_equal @weight, @item.grams
57
+ refute_equal @weight, @item.ounces
58
+ end
59
+
60
+ test "#initialize weight accepts imperial" do
61
+ @item = PackageItem.new(@name, @weight, @value, @quantity, @options.merge(units: :imperial))
62
+
63
+ assert_equal @weight, @item.ounces
64
+ refute_equal @weight, @item.grams
65
+ end
66
+
67
+ test "#initialize_weight accepts metric" do
68
+ @item = PackageItem.new(@name, @weight, @value, @quantity, @options.merge(units: :metric))
69
+
70
+ assert_equal @weight, @item.grams
71
+ refute_equal @weight, @item.ounces
72
+ end
73
+
74
+ test "#initialize weight does not accept strings" do
75
+ @item = PackageItem.new(@name, @weight, @value, @quantity, @options.merge(units: "imperial"))
76
+
77
+ assert_equal @weight, @item.grams
78
+ refute_equal @weight, @item.ounces
79
+ end
80
+
81
+ test "#initialize value from cents" do
82
+ @item = PackageItem.new(@name, @weight, "1.23", @quantity, @options)
83
+
84
+ assert_equal 123, @item.value
85
+ end
86
+
87
+ test "#weight default lookup" do
88
+ assert_equal @mass, @item.weight
89
+ assert_instance_of Measured::Weight, @item.weight
90
+ end
91
+
92
+ test "#weight type: actual" do
93
+ assert_equal @mass, @item.weight(type: :actual)
94
+ assert_instance_of Measured::Weight, @item.weight(type: :actual)
95
+ end
96
+
97
+ test "#weight type: volumetric" do
98
+ begin
99
+ assert_equal :todo, @item.weight(type: :volumetric)
100
+ assert_instance_of Measured::Weight, @item.weight(type: :volumetric)
101
+ flunk "This code path is broken but passed unexpectedly"
102
+ rescue NoMethodError
103
+ skip "This code path is broken"
104
+ end
105
+ end
106
+
107
+ test "#weight type: dimensional" do
108
+ begin
109
+ assert_equal :todo, @item.weight(type: :dimensional)
110
+ assert_instance_of Measured::Weight, @item.weight(type: :dimensional)
111
+ flunk "This code path is broken but passed unexpectedly"
112
+ rescue NoMethodError
113
+ skip "This code path is broken"
114
+ end
115
+ end
116
+
117
+ test "#weight type: billable is the max of weight and volumetric" do
118
+ begin
119
+ assert_equal :todo, @item.weight(type: :billable)
120
+ assert_instance_of Measured::Weight, @item.weight(type: :billable)
121
+ flunk "This code path is broken but passed unexpectedly"
122
+ rescue NoMethodError
123
+ skip "This code path is broken"
124
+ end
125
+ end
126
+
127
+ test "#grams is the value" do
128
+ assert_equal 100, @item.grams
129
+ end
130
+
131
+ test "#grams accepts options with type" do
132
+ begin
133
+ assert_equal :todo, @item.grams(type: :volumetric)
134
+ flunk "This code path is broken but passed unexpectedly"
135
+ rescue NoMethodError
136
+ skip "This code path is broken"
137
+ end
138
+ end
139
+
140
+ test "#grams converts to another unit" do
141
+ @item = PackageItem.new(@name, 100, @value, @quantity, @options.merge(units: :imperial))
142
+
143
+ assert_in_delta 2834.9, @item.grams, 0.1
144
+ end
145
+
146
+ test "#grams aliases to g" do
147
+ assert_equal @item.grams, @item.g
148
+ end
149
+
150
+ test "#ounces is the value" do
151
+ @item = PackageItem.new(@name, @weight, @value, @quantity, @options.merge(units: :imperial))
152
+
153
+ assert_equal 100, @item.ounces
154
+ end
155
+
156
+ test "#ounces accepts options with type" do
157
+ begin
158
+ assert_equal :todo, @item.ounces(type: :volumetric)
159
+ flunk "This code path is broken but passed unexpectedly"
160
+ rescue NoMethodError
161
+ skip "This code path is broken"
162
+ end
163
+ end
164
+
165
+ test "#ounces converts to another unit" do
166
+ @item = PackageItem.new(@name, @weight, @value, @quantity, @options.merge(units: :metric))
167
+
168
+ assert_in_delta 3.5, @item.ounces, 0.1
169
+ end
170
+
171
+ test "#ounces aliases to oz" do
172
+ assert_equal @item.ounces, @item.oz
173
+ end
174
+
175
+ test "#pounds is the value" do
176
+ @item = PackageItem.new(@name, 32, @value, @quantity, @options.merge(units: :imperial))
177
+
178
+ assert_equal 2, @item.pounds
179
+ end
180
+
181
+ test "#pounds accepts options with type" do
182
+ begin
183
+ assert_equal :todo, @item.pounds(type: :volumetric)
184
+ flunk "This code path is broken but passed unexpectedly"
185
+ rescue
186
+ skip "This code path is broken"
187
+ end
188
+ end
189
+
190
+ test "#pounds converts to another unit" do
191
+ @item = PackageItem.new(@name, 1000, @value, @quantity, @options.merge(units: :metric))
192
+
193
+ assert_in_delta 2.2, @item.pounds, 0.1
194
+ end
195
+
196
+ test "#pounds aliases to lb" do
197
+ assert_equal @item.pounds, @item.lb
198
+ end
199
+
200
+ test "#pounds aliases to lbs" do
201
+ assert_equal @item.pounds, @item.lbs
202
+ end
203
+
204
+ test "#kilograms is the value" do
205
+ @item = PackageItem.new(@name, 1000, @value, @quantity, @options.merge(units: :metric))
206
+
207
+ assert_equal 1, @item.kilograms
208
+ end
209
+
210
+ test "#kilograms accepts options with type" do
211
+ begin
212
+ assert_equal :todo, @item.kilograms(type: :volumetric)
213
+ flunk "This code path is broken but passed unexpectedly"
214
+ rescue
215
+ skip "This code path is broken"
216
+ end
217
+ end
218
+
219
+ test "#kilograms converts to another unit" do
220
+ @item = PackageItem.new(@name, 1000, @value, @quantity, @options.merge(units: :imperial))
221
+
222
+ assert_in_delta 28.3, @item.kilograms, 0.1
223
+ end
224
+
225
+ test "#kilograms aliases to kg" do
226
+ assert_equal @item.kilograms, @item.kg
227
+ end
228
+
229
+ test "#kilograms aliases to kgs" do
230
+ assert_equal @item.kilograms, @item.kgs
231
+ end
232
+ end
@@ -0,0 +1,404 @@
1
+ require 'test_helper'
2
+
3
+ class PackageTest < ActiveSupport::TestCase
4
+ setup do
5
+ @weight = 100
6
+ @dimensions = [5, 6, 7]
7
+ @value = 1299
8
+ @currency = "USD"
9
+ @cylinder = false
10
+ @tube = false
11
+ @gift = false
12
+ @oversized = false
13
+ @unpackaged = false
14
+ @dim_units = :metric
15
+ @units = :metric
16
+ @weight_units = :metric
17
+ @options = {
18
+ value: @value,
19
+ currency: @currency,
20
+ cylinder: @cylinder,
21
+ tube: @tube,
22
+ gift: @gift,
23
+ oversized: @oversized,
24
+ unpackaged: @unpackaged,
25
+ dim_units: @dim_units,
26
+ units: @units,
27
+ weight_units: @weight_units,
28
+ }
29
+
30
+ @package = Package.new(@weight, @dimensions, @options)
31
+ @imperial_package = Package.new(@weight, @dimensions, @options.merge(units: :imperial, dim_units: :imperial, weight_units: :imperial))
32
+
33
+ @mass = Measured::Weight.new(@weight, :grams)
34
+ end
35
+
36
+ test "#initialize package from mass" do
37
+ ten_pounds = Measured::Weight.new(10, :pounds)
38
+ package = Package.new(ten_pounds, [])
39
+ assert_equal ten_pounds, package.weight
40
+ end
41
+
42
+ test "#initialize with defaults" do
43
+ assert_equal @value, @package.value
44
+ assert_equal @currency, @package.currency
45
+ assert_equal @cylinder, @package.cylinder?
46
+ assert_equal @tube, @package.tube?
47
+ assert_equal @oversized, @package.oversized?
48
+ assert_equal @unpackaged, @package.unpackaged?
49
+ assert_equal @gift, @package.gift?
50
+ end
51
+
52
+ test "#initialize with currency cents" do
53
+ @package = Package.new(@weight, @dimensions, value: money)
54
+ assert_equal @currency, @package.currency
55
+ assert_equal @value, @package.value
56
+ end
57
+
58
+ test "#initialize sorts the passed in dimensions" do
59
+ @package = Package.new(@weight, [9, 8, 7], @options)
60
+
61
+ assert_equal [7, 8, 9], @package.centimetres
62
+ end
63
+
64
+ test "#initialize sets default dimensions if blank" do
65
+ @package = Package.new(@weight, [], @options)
66
+
67
+ assert_equal [0, 0, 0], @package.centimetres
68
+ end
69
+
70
+ test "#initialize increases dimension size to three elements in the array and pads" do
71
+ @package = Package.new(@weight, [2], @options)
72
+
73
+ assert_equal [2, 2, 2], @package.centimetres
74
+ end
75
+
76
+ test "#initialize default units" do
77
+ assert_equal @dimensions, @package.centimetres
78
+ assert_equal @weight, @package.grams
79
+ end
80
+
81
+ test "#initialize units" do
82
+ assert_equal @dimensions, @imperial_package.inches
83
+ end
84
+
85
+ test "#initialize weight_units" do
86
+ @package = Package.new(@weight, @dimensions, @options.merge(weight_units: :imperial))
87
+
88
+ assert_equal @weight, @package.ounces
89
+ end
90
+
91
+ test "#unpackaged?" do
92
+ assert_predicate Package.new(@weight, @dimensions, unpackaged: true), :unpackaged?
93
+ refute_predicate Package.new(@weight, @dimensions, unpackaged: false), :unpackaged?
94
+ end
95
+
96
+ test "#oversized?" do
97
+ assert_predicate Package.new(@weight, @dimensions, oversized: true), :oversized?
98
+ refute_predicate Package.new(@weight, @dimensions, oversized: false), :oversized?
99
+ end
100
+
101
+ test "#gift?" do
102
+ assert_predicate Package.new(@weight, @dimensions, gift: true), :gift?
103
+ refute_predicate Package.new(@weight, @dimensions, gift: false), :gift?
104
+ end
105
+
106
+ test "#cylinder? and #tube? check both values" do
107
+ @package = Package.new(@weight, @dimensions, cylinder: false, tube: false)
108
+ refute_predicate @package, :cylinder?
109
+ refute_predicate @package, :tube?
110
+
111
+ @package = Package.new(@weight, @dimensions, cylinder: true, tube: false)
112
+ assert_predicate @package, :cylinder?
113
+ assert_predicate @package, :tube?
114
+
115
+ @package = Package.new(@weight, @dimensions, cylinder: false, tube: true)
116
+ assert_predicate @package, :cylinder?
117
+ assert_predicate @package, :tube?
118
+
119
+ @package = Package.new(@weight, @dimensions, cylinder: true, tube: true)
120
+ assert_predicate @package, :cylinder?
121
+ assert_predicate @package, :tube?
122
+ end
123
+
124
+ test "#inches performs lookup with a numerical index" do
125
+ assert_equal @dimensions[0], @imperial_package.inches(0)
126
+ assert_equal @dimensions[1], @imperial_package.inches(1)
127
+ assert_equal @dimensions[2], @imperial_package.inches(2)
128
+ assert_nil @imperial_package.inches(3)
129
+ end
130
+
131
+ test "#inches for dimension x" do
132
+ assert_equal @dimensions[2], @imperial_package.inches(:x)
133
+ assert_equal @dimensions[2], @imperial_package.inches(:max)
134
+ assert_equal @dimensions[2], @imperial_package.inches(:length)
135
+ assert_equal @dimensions[2], @imperial_package.inches(:long)
136
+ end
137
+
138
+ test "#inches for dimension y" do
139
+ assert_equal @dimensions[1], @imperial_package.inches(:y)
140
+ assert_equal @dimensions[1], @imperial_package.inches(:mid)
141
+ assert_equal @dimensions[1], @imperial_package.inches(:width)
142
+ assert_equal @dimensions[1], @imperial_package.inches(:wide)
143
+ end
144
+
145
+ test "#inches for dimension z" do
146
+ assert_equal @dimensions[0], @imperial_package.inches(:z)
147
+ assert_equal @dimensions[0], @imperial_package.inches(:min)
148
+ assert_equal @dimensions[0], @imperial_package.inches(:height)
149
+ assert_equal @dimensions[0], @imperial_package.inches(:depth)
150
+ assert_equal @dimensions[0], @imperial_package.inches(:high)
151
+ assert_equal @dimensions[0], @imperial_package.inches(:deep)
152
+ end
153
+
154
+ test "#inches for girth of a cylinder" do
155
+ @imperial_package = Package.new(@weight, @dimensions, @options.merge(cylinder: true, units: :imperial, dim_units: :imperial))
156
+
157
+ assert_predicate @imperial_package, :cylinder?
158
+ assert_in_delta 17.2, @imperial_package.inches(:girth), 1
159
+ assert_in_delta 17.2, @imperial_package.inches(:around), 1
160
+ assert_in_delta 17.2, @imperial_package.inches(:circumference), 1
161
+
162
+ end
163
+
164
+ test "#inches for girth of a non cylinder" do
165
+ refute_predicate @imperial_package, :cylinder?
166
+ assert_in_delta 22, @imperial_package.inches(:girth), 1
167
+ assert_in_delta 22, @imperial_package.inches(:around), 1
168
+ assert_in_delta 22, @imperial_package.inches(:circumference), 1
169
+ end
170
+
171
+ test "#inches for the volume of a cylinder" do
172
+ @imperial_package = Package.new(@weight, @dimensions, @options.merge(cylinder: true, units: :imperial, dim_units: :imperial))
173
+
174
+ assert_predicate @imperial_package, :cylinder?
175
+ assert_in_delta 522.4, @imperial_package.inches(:volume), 1
176
+ end
177
+
178
+ test "#inches for volume" do
179
+ refute_predicate @imperial_package, :cylinder?
180
+ assert_equal 210, @imperial_package.inches(:volume)
181
+ end
182
+
183
+ test "#inches for box_volume" do
184
+ assert_equal 210, @imperial_package.inches(:box_volume)
185
+ end
186
+
187
+ test "#inches of an unknown value" do
188
+ assert_nil @imperial_package.inches(:unknown)
189
+ end
190
+
191
+ test "#inches alias to #in" do
192
+ assert_equal @dimensions, @imperial_package.inches
193
+ assert_equal @dimensions, @imperial_package.in
194
+ end
195
+
196
+ test "#centimetres performs lookup with a numerical index" do
197
+ assert_equal @dimensions[0], @package.centimetres(0)
198
+ assert_equal @dimensions[1], @package.centimetres(1)
199
+ assert_equal @dimensions[2], @package.centimetres(2)
200
+ assert_nil @package.centimetres(3)
201
+ end
202
+
203
+ test "#centimetres for dimension x" do
204
+ assert_equal @dimensions[2], @package.centimetres(:x)
205
+ assert_equal @dimensions[2], @package.centimetres(:max)
206
+ assert_equal @dimensions[2], @package.centimetres(:length)
207
+ assert_equal @dimensions[2], @package.centimetres(:long)
208
+ end
209
+
210
+ test "#centimetres for dimension y" do
211
+ assert_equal @dimensions[1], @package.centimetres(:y)
212
+ assert_equal @dimensions[1], @package.centimetres(:mid)
213
+ assert_equal @dimensions[1], @package.centimetres(:width)
214
+ assert_equal @dimensions[1], @package.centimetres(:wide)
215
+ end
216
+
217
+ test "#centimetres for dimension z" do
218
+ assert_equal @dimensions[0], @package.centimetres(:z)
219
+ assert_equal @dimensions[0], @package.centimetres(:min)
220
+ assert_equal @dimensions[0], @package.centimetres(:height)
221
+ assert_equal @dimensions[0], @package.centimetres(:depth)
222
+ assert_equal @dimensions[0], @package.centimetres(:high)
223
+ assert_equal @dimensions[0], @package.centimetres(:deep)
224
+ end
225
+
226
+ test "#centimetres for girth of a cylinder" do
227
+ @package = Package.new(@weight, @dimensions, @options.merge(cylinder: true, units: :metric, dim_units: :metric))
228
+
229
+ assert_predicate @package, :cylinder?
230
+ assert_in_delta 17.2, @package.centimetres(:girth), 1
231
+ assert_in_delta 17.2, @package.centimetres(:around), 1
232
+ assert_in_delta 17.2, @package.centimetres(:circumference), 1
233
+
234
+ end
235
+
236
+ test "#centimetres for girth of a non-cylinder" do
237
+ refute_predicate @package, :cylinder?
238
+ assert_in_delta 22, @package.centimetres(:girth), 1
239
+ assert_in_delta 22, @package.centimetres(:around), 1
240
+ assert_in_delta 22, @package.centimetres(:circumference), 1
241
+ end
242
+
243
+ test "#centimetres for the volume of a cylinder" do
244
+ @package = Package.new(@weight, @dimensions, @options.merge(cylinder: true, units: :metric, dim_units: :metric))
245
+
246
+ assert_predicate @package, :cylinder?
247
+ assert_in_delta 522.4, @package.centimetres(:volume), 1
248
+ end
249
+
250
+ test "#centimetres for volume" do
251
+ refute_predicate @package, :cylinder?
252
+ assert_equal 210, @package.centimetres(:volume)
253
+ end
254
+
255
+ test "#centimetres for box_volume" do
256
+ assert_equal 210, @package.centimetres(:box_volume)
257
+ end
258
+
259
+ test "#centimetres of an unknown value" do
260
+ assert_nil @package.centimetres(:unknown)
261
+ end
262
+
263
+ test "#centimetres alias to #cm" do
264
+ assert_equal @dimensions, @package.centimetres
265
+ assert_equal @dimensions, @package.cm
266
+ end
267
+
268
+ test "#weight" do
269
+ assert_equal @mass, @package.weight
270
+ assert_instance_of Measured::Weight, @package.weight
271
+ end
272
+
273
+ test "#weight for actual" do
274
+ assert_equal @mass, @package.weight(type: :actual)
275
+ assert_instance_of Measured::Weight, @package.weight(type: :actual)
276
+ end
277
+
278
+ test "#weight volumetric" do
279
+ assert_equal Measured::Weight.new(35, :grams), @package.weight(type: :volumetric)
280
+ end
281
+
282
+ test "#weight dimensional" do
283
+ assert_equal Measured::Weight.new(35, :grams), @package.weight(type: :dimensional)
284
+ end
285
+
286
+ test "#weight billable is the max of weight and volumetric" do
287
+ assert_equal Measured::Weight.new(100, :grams), @package.weight(type: :billable)
288
+
289
+ @package = Package.new(500, [1, 1, 1], @options)
290
+ assert_equal Measured::Weight.new(500, :grams), @package.weight(type: :billable)
291
+ end
292
+
293
+ test "#grams value" do
294
+ assert_equal 100, @package.grams
295
+ end
296
+
297
+ test "#grams accepts options with type" do
298
+ assert_in_delta 35, @package.grams(type: :volumetric), 1
299
+ end
300
+
301
+ test "#grams converts to another unit from another system" do
302
+ @package = Package.new(@weight, @dimensions, weight_units: :imperial)
303
+
304
+ assert_in_delta 2834.9, @package.grams, 1
305
+ end
306
+
307
+ test "#grams alias to #g" do
308
+ assert_equal @package.grams, @package.g
309
+ end
310
+
311
+ test "#ounces value" do
312
+ assert_equal 100, @imperial_package.ounces
313
+ end
314
+
315
+ test "#ounces accepts options with type" do
316
+ assert_in_delta 20.2, @imperial_package.ounces(type: :volumetric), 1
317
+ end
318
+
319
+ test "#ounces converts to another unit from another system" do
320
+ assert_in_delta 3.5, @package.ounces, 1
321
+ end
322
+
323
+ test "#ounces alias to #oz" do
324
+ assert_equal @imperial_package.ounces, @imperial_package.oz
325
+ end
326
+
327
+ test "#pounds value" do
328
+ assert_equal 6.25, @imperial_package.pounds
329
+ end
330
+
331
+ test "#pounds accepts options with type" do
332
+ assert_in_delta 0.07, @package.pounds(type: :volumetric), 0.01
333
+ end
334
+
335
+ test "#pounds converts to another unit from another system" do
336
+ assert_in_delta 0.22, @package.pounds, 0.01
337
+ end
338
+
339
+ test "#pounds alias to #lb" do
340
+ assert_equal @package.pounds, @package.lb
341
+ end
342
+
343
+ test "#pounds alias to #lbs" do
344
+ assert_equal @package.pounds, @package.lbs
345
+ end
346
+
347
+ test "#kilograms value" do
348
+ assert_equal 0.1, @package.kilograms
349
+ end
350
+
351
+ test "#kilograms accepts options with type" do
352
+ assert_equal 0.035, @package.kilograms(type: :volumetric)
353
+ end
354
+
355
+ test "#kilograms converts to another unit from another system" do
356
+ assert_in_delta 2.8, @imperial_package.kilograms, 1
357
+ end
358
+
359
+ test "#kilograms alias to #kg" do
360
+ assert_equal 0.1, @package.kg
361
+ end
362
+
363
+ test "#kilograms alias to #kgs" do
364
+ assert_equal @package.kilograms, @package.kgs
365
+ end
366
+
367
+ test ".cents_from nil" do
368
+ assert_nil Package.cents_from(nil)
369
+ end
370
+
371
+ test ".cents_from cents on a money object" do
372
+ assert_equal @value, Package.cents_from(money)
373
+ end
374
+
375
+ test ".cents_from float" do
376
+ assert_equal 120, Package.cents_from(1.2)
377
+ end
378
+
379
+ test ".cents_from string" do
380
+ assert_equal 120, Package.cents_from("1.20")
381
+ end
382
+
383
+ test ".cents_from integer" do
384
+ assert_equal 12, Package.cents_from(12)
385
+ end
386
+
387
+ test ".cents_from an unhandled object" do
388
+ exception = assert_raises NoMethodError do
389
+ Package.cents_from(Object.new)
390
+ end
391
+ assert_match /undefined method `to_i'/, exception.message
392
+ end
393
+
394
+ private
395
+
396
+ def money
397
+ @money ||= begin
398
+ value = Class.new { attr_accessor :currency, :cents }.new
399
+ value.currency = @currency
400
+ value.cents = @value
401
+ value
402
+ end
403
+ end
404
+ end