channeladvisor 0.1.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 (205) hide show
  1. data/.gitignore +7 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +6 -0
  4. data/.yardopts +8 -0
  5. data/Gemfile +31 -0
  6. data/Guardfile +28 -0
  7. data/LICENSE +19 -0
  8. data/README.md +40 -0
  9. data/Rakefile +69 -0
  10. data/channeladvisor.gemspec +29 -0
  11. data/lib/channeladvisor.rb +27 -0
  12. data/lib/channeladvisor/account_authorization.rb +14 -0
  13. data/lib/channeladvisor/address.rb +39 -0
  14. data/lib/channeladvisor/admin.rb +75 -0
  15. data/lib/channeladvisor/base.rb +34 -0
  16. data/lib/channeladvisor/client.rb +3 -0
  17. data/lib/channeladvisor/configuration.rb +11 -0
  18. data/lib/channeladvisor/error.rb +30 -0
  19. data/lib/channeladvisor/line_item.rb +38 -0
  20. data/lib/channeladvisor/order.rb +179 -0
  21. data/lib/channeladvisor/order_status.rb +14 -0
  22. data/lib/channeladvisor/payment.rb +15 -0
  23. data/lib/channeladvisor/services.rb +11 -0
  24. data/lib/channeladvisor/services/admin_service.rb +47 -0
  25. data/lib/channeladvisor/services/base_service.rb +26 -0
  26. data/lib/channeladvisor/services/inventory_service.rb +90 -0
  27. data/lib/channeladvisor/services/order_service.rb +117 -0
  28. data/lib/channeladvisor/services/shipping_service.rb +164 -0
  29. data/lib/channeladvisor/shipment.rb +71 -0
  30. data/lib/channeladvisor/shopping_cart.rb +26 -0
  31. data/lib/channeladvisor/version.rb +3 -0
  32. data/spec/fixtures/requests/admin_service/get_authorization_list.xml +1 -0
  33. data/spec/fixtures/requests/admin_service/get_authorization_list_with_local_id.xml +1 -0
  34. data/spec/fixtures/requests/admin_service/ping.xml +1 -0
  35. data/spec/fixtures/requests/admin_service/request_access.xml +1 -0
  36. data/spec/fixtures/requests/inventory_service/ping.xml +1 -0
  37. data/spec/fixtures/requests/inventory_service/update_inventory_item_quantity_and_price_list/with_one_item/price_only.xml +1 -0
  38. data/spec/fixtures/requests/inventory_service/update_inventory_item_quantity_and_price_list/with_one_item/quantity_and_price.xml +1 -0
  39. data/spec/fixtures/requests/inventory_service/update_inventory_item_quantity_and_price_list/with_one_item/quantity_only.xml +1 -0
  40. data/spec/fixtures/requests/inventory_service/update_inventory_item_quantity_and_price_list/with_two_items/price_only.xml +1 -0
  41. data/spec/fixtures/requests/inventory_service/update_inventory_item_quantity_and_price_list/with_two_items/quantity_and_price.xml +1 -0
  42. data/spec/fixtures/requests/inventory_service/update_inventory_item_quantity_and_price_list/with_two_items/quantity_only.xml +1 -0
  43. data/spec/fixtures/requests/inventory_service/update_item_price.xml +1 -0
  44. data/spec/fixtures/requests/inventory_service/update_item_quantity.xml +1 -0
  45. data/spec/fixtures/requests/inventory_service/update_item_quantity_and_price.xml +1 -0
  46. data/spec/fixtures/requests/order_service/get_order_list/with_checkout_status_filter.xml +1 -0
  47. data/spec/fixtures/requests/order_service/get_order_list/with_created_from_date.xml +1 -0
  48. data/spec/fixtures/requests/order_service/get_order_list/with_created_to_date.xml +1 -0
  49. data/spec/fixtures/requests/order_service/get_order_list/with_detail_level.xml +1 -0
  50. data/spec/fixtures/requests/order_service/get_order_list/with_distribution_center_code.xml +1 -0
  51. data/spec/fixtures/requests/order_service/get_order_list/with_export_state.xml +1 -0
  52. data/spec/fixtures/requests/order_service/get_order_list/with_join_dates.xml +1 -0
  53. data/spec/fixtures/requests/order_service/get_order_list/with_one_client_order_id.xml +1 -0
  54. data/spec/fixtures/requests/order_service/get_order_list/with_one_order_id.xml +1 -0
  55. data/spec/fixtures/requests/order_service/get_order_list/with_order_state_filter.xml +1 -0
  56. data/spec/fixtures/requests/order_service/get_order_list/with_page_number_filter.xml +1 -0
  57. data/spec/fixtures/requests/order_service/get_order_list/with_page_size.xml +1 -0
  58. data/spec/fixtures/requests/order_service/get_order_list/with_payment_status_filter.xml +1 -0
  59. data/spec/fixtures/requests/order_service/get_order_list/with_refund_status_filter.xml +1 -0
  60. data/spec/fixtures/requests/order_service/get_order_list/with_shipping_status_filter.xml +1 -0
  61. data/spec/fixtures/requests/order_service/get_order_list/with_two_client_order_ids.xml +1 -0
  62. data/spec/fixtures/requests/order_service/get_order_list/with_two_order_ids.xml +1 -0
  63. data/spec/fixtures/requests/order_service/get_order_list/with_updated_from_date.xml +1 -0
  64. data/spec/fixtures/requests/order_service/get_order_list/with_updated_to_date.xml +1 -0
  65. data/spec/fixtures/requests/order_service/get_order_list/without_order_criteria.xml +1 -0
  66. data/spec/fixtures/requests/order_service/ping.xml +1 -0
  67. data/spec/fixtures/requests/order_service/set_orders_export_status/with_one_client_order_id.xml +1 -0
  68. data/spec/fixtures/requests/order_service/set_orders_export_status/with_two_client_order_ids.xml +1 -0
  69. data/spec/fixtures/requests/shipping_service/get_shipping_carrier_list.xml +1 -0
  70. data/spec/fixtures/requests/shipping_service/ping.xml +1 -0
  71. data/spec/fixtures/requests/shipping_service/submit_order_shipment_list/full_shipment/with_one_shipment.xml +1 -0
  72. data/spec/fixtures/requests/shipping_service/submit_order_shipment_list/full_shipment/with_two_shipments.xml +1 -0
  73. data/spec/fixtures/requests/shipping_service/submit_order_shipment_list/full_shipment/without_carrier_code.xml +1 -0
  74. data/spec/fixtures/requests/shipping_service/submit_order_shipment_list/full_shipment/without_class_code.xml +1 -0
  75. data/spec/fixtures/requests/shipping_service/submit_order_shipment_list/full_shipment/without_client_order_id.xml +1 -0
  76. data/spec/fixtures/requests/shipping_service/submit_order_shipment_list/full_shipment/without_seller_id.xml +1 -0
  77. data/spec/fixtures/requests/shipping_service/submit_order_shipment_list/full_shipment/without_tracking_number.xml +1 -0
  78. data/spec/fixtures/requests/shipping_service/submit_order_shipment_list/partial_shipment/with_one_line_item.xml +1 -0
  79. data/spec/fixtures/requests/shipping_service/submit_order_shipment_list/partial_shipment/with_two_line_items.xml +1 -0
  80. data/spec/fixtures/requests/shipping_service/submit_order_shipment_list/partial_shipment/with_two_shipments.xml +1 -0
  81. data/spec/fixtures/requests/shipping_service/submit_order_shipment_list/partial_shipment/without_carrier_code.xml +1 -0
  82. data/spec/fixtures/requests/shipping_service/submit_order_shipment_list/partial_shipment/without_class_code.xml +1 -0
  83. data/spec/fixtures/requests/shipping_service/submit_order_shipment_list/partial_shipment/without_seller_id.xml +1 -0
  84. data/spec/fixtures/requests/shipping_service/submit_order_shipment_list/partial_shipment/without_tracking_number.xml +1 -0
  85. data/spec/fixtures/requests/shipping_service/submit_order_shipment_list/with_partial_and_full_shipments.xml +1 -0
  86. data/spec/fixtures/responses/admin/get_authorization_list/failure.yml +50 -0
  87. data/spec/fixtures/responses/admin/get_authorization_list/no_authorizations.yml +49 -0
  88. data/spec/fixtures/responses/admin/get_authorization_list/one_authorization.yml +49 -0
  89. data/spec/fixtures/responses/admin/get_authorization_list/success.yml +49 -0
  90. data/spec/fixtures/responses/admin/get_authorization_list/two_authorizations.yml +49 -0
  91. data/spec/fixtures/responses/admin/ping/failure.yml +50 -0
  92. data/spec/fixtures/responses/admin/ping/success.yml +218 -0
  93. data/spec/fixtures/responses/admin/request_access/failure.yml +50 -0
  94. data/spec/fixtures/responses/admin/request_access/success.yml +49 -0
  95. data/spec/fixtures/responses/admin_service/get_authorization_list/with_invalid_local_id.yml +219 -0
  96. data/spec/fixtures/responses/admin_service/get_authorization_list/with_local_id/success.yml +218 -0
  97. data/spec/fixtures/responses/admin_service/get_authorization_list/with_valid_local_id/multiple_authorizations.yml +49 -0
  98. data/spec/fixtures/responses/admin_service/get_authorization_list/with_valid_local_id/no_authorizations.yml +49 -0
  99. data/spec/fixtures/responses/admin_service/get_authorization_list/with_valid_local_id/one_authorization.yml +49 -0
  100. data/spec/fixtures/responses/admin_service/get_authorization_list/with_valid_local_id/success.yml +218 -0
  101. data/spec/fixtures/responses/admin_service/get_authorization_list/without_local_id/multiple_authorizations.yml +49 -0
  102. data/spec/fixtures/responses/admin_service/get_authorization_list/without_local_id/no_authorizations.yml +49 -0
  103. data/spec/fixtures/responses/admin_service/get_authorization_list/without_local_id/one_authorization.yml +49 -0
  104. data/spec/fixtures/responses/admin_service/get_authorization_list/without_local_id/success.yml +218 -0
  105. data/spec/fixtures/responses/admin_service/ping/failure.yml +222 -0
  106. data/spec/fixtures/responses/admin_service/ping/success.yml +218 -0
  107. data/spec/fixtures/responses/admin_service/request_access/failure.yml +219 -0
  108. data/spec/fixtures/responses/admin_service/request_access/success.yml +218 -0
  109. data/spec/fixtures/responses/http_error.yml +48 -0
  110. data/spec/fixtures/responses/inventory_service/ping.yml +1356 -0
  111. data/spec/fixtures/responses/inventory_service/update_inventory_item_quantity_and_price.yml +1356 -0
  112. data/spec/fixtures/responses/inventory_service/update_inventory_item_quantity_and_price/price_only.yml +144 -0
  113. data/spec/fixtures/responses/inventory_service/update_inventory_item_quantity_and_price/quantity_and_price.yml +191 -0
  114. data/spec/fixtures/responses/inventory_service/update_inventory_item_quantity_and_price/quantity_only.yml +1403 -0
  115. data/spec/fixtures/responses/inventory_service/update_inventory_item_quantity_and_price_list.yml +243 -0
  116. data/spec/fixtures/responses/inventory_service/update_inventory_item_quantity_and_price_list/with_one_item/price_only.yml +97 -0
  117. data/spec/fixtures/responses/inventory_service/update_inventory_item_quantity_and_price_list/with_one_item/quantity_and_price.yml +144 -0
  118. data/spec/fixtures/responses/inventory_service/update_inventory_item_quantity_and_price_list/with_one_item/quantity_only.yml +51 -0
  119. data/spec/fixtures/responses/inventory_service/update_inventory_item_quantity_and_price_list/with_two_items/price_only.yml +238 -0
  120. data/spec/fixtures/responses/inventory_service/update_inventory_item_quantity_and_price_list/with_two_items/quantity_and_price.yml +285 -0
  121. data/spec/fixtures/responses/inventory_service/update_inventory_item_quantity_and_price_list/with_two_items/quantity_only.yml +191 -0
  122. data/spec/fixtures/responses/order/instance_set_export_status.yml +51 -0
  123. data/spec/fixtures/responses/order/instance_set_export_status/failure.yml +51 -0
  124. data/spec/fixtures/responses/order/instance_set_export_status/success/result_false.yml +51 -0
  125. data/spec/fixtures/responses/order/instance_set_export_status/success/result_true.yml +51 -0
  126. data/spec/fixtures/responses/order/list.yml +58 -0
  127. data/spec/fixtures/responses/order/list/failure.yml +56 -0
  128. data/spec/fixtures/responses/order/list/no_matching_orders.yml +56 -0
  129. data/spec/fixtures/responses/order/list/one_matching_order.yml +57 -0
  130. data/spec/fixtures/responses/order/list/two_matching_orders.yml +59 -0
  131. data/spec/fixtures/responses/order/list/with_criteria.yml +52 -0
  132. data/spec/fixtures/responses/order/list/with_no_criteria.yml +58 -0
  133. data/spec/fixtures/responses/order/ping.yml +868 -0
  134. data/spec/fixtures/responses/order/ping/failure.yml +50 -0
  135. data/spec/fixtures/responses/order/ping/success.yml +867 -0
  136. data/spec/fixtures/responses/order/set_export_status/failure.yml +51 -0
  137. data/spec/fixtures/responses/order/set_export_status/success/with_one_client_order_id.yml +51 -0
  138. data/spec/fixtures/responses/order/set_export_status/success/with_two_client_order_ids.yml +51 -0
  139. data/spec/fixtures/responses/order_service/get_order_list/.gitkeep +0 -0
  140. data/spec/fixtures/responses/order_service/get_order_list/with_checkout_status_filter.yml +875 -0
  141. data/spec/fixtures/responses/order_service/get_order_list/with_created_from_date.yml +874 -0
  142. data/spec/fixtures/responses/order_service/get_order_list/with_created_to_date.yml +874 -0
  143. data/spec/fixtures/responses/order_service/get_order_list/with_detail_level.yml +875 -0
  144. data/spec/fixtures/responses/order_service/get_order_list/with_distribution_center_code.yml +872 -0
  145. data/spec/fixtures/responses/order_service/get_order_list/with_export_state.yml +875 -0
  146. data/spec/fixtures/responses/order_service/get_order_list/with_join_dates.yml +869 -0
  147. data/spec/fixtures/responses/order_service/get_order_list/with_one_client_order_id.yml +872 -0
  148. data/spec/fixtures/responses/order_service/get_order_list/with_one_order_id.yml +873 -0
  149. data/spec/fixtures/responses/order_service/get_order_list/with_order_state_filter.yml +875 -0
  150. data/spec/fixtures/responses/order_service/get_order_list/with_page_number_filter.yml +875 -0
  151. data/spec/fixtures/responses/order_service/get_order_list/with_page_size.yml +874 -0
  152. data/spec/fixtures/responses/order_service/get_order_list/with_payment_status_filter.yml +875 -0
  153. data/spec/fixtures/responses/order_service/get_order_list/with_refund_status_filter.yml +875 -0
  154. data/spec/fixtures/responses/order_service/get_order_list/with_shipping_status_filter.yml +875 -0
  155. data/spec/fixtures/responses/order_service/get_order_list/with_two_client_order_ids.yml +872 -0
  156. data/spec/fixtures/responses/order_service/get_order_list/with_two_order_ids.yml +875 -0
  157. data/spec/fixtures/responses/order_service/get_order_list/with_updated_from_date.yml +874 -0
  158. data/spec/fixtures/responses/order_service/get_order_list/with_updated_to_date.yml +874 -0
  159. data/spec/fixtures/responses/order_service/get_order_list/without_order_criteria.yml +871 -0
  160. data/spec/fixtures/responses/order_service/get_order_refund_history/.gitkeep +0 -0
  161. data/spec/fixtures/responses/order_service/order_merge/.gitkeep +0 -0
  162. data/spec/fixtures/responses/order_service/order_split/.gitkeep +0 -0
  163. data/spec/fixtures/responses/order_service/ping/.gitkeep +0 -0
  164. data/spec/fixtures/responses/order_service/ping/failure.yml +871 -0
  165. data/spec/fixtures/responses/order_service/ping/success.yml +868 -0
  166. data/spec/fixtures/responses/order_service/set_orders_export_status/with_one_client_order_id.yml +867 -0
  167. data/spec/fixtures/responses/order_service/set_orders_export_status/with_two_client_order_id.yml +867 -0
  168. data/spec/fixtures/responses/order_service/set_seller_order_id/.gitkeep +0 -0
  169. data/spec/fixtures/responses/order_service/set_seller_order_item_id_list/.gitkeep +0 -0
  170. data/spec/fixtures/responses/order_service/submit_order/.gitkeep +0 -0
  171. data/spec/fixtures/responses/order_service/submit_order_refund/.gitkeep +0 -0
  172. data/spec/fixtures/responses/order_service/update_order_list/.gitkeep +0 -0
  173. data/spec/fixtures/responses/shipment/get_carriers.yml +53 -0
  174. data/spec/fixtures/responses/shipment/get_carriers/failure.yml +52 -0
  175. data/spec/fixtures/responses/shipment/submit.yml +464 -0
  176. data/spec/fixtures/responses/shipment/submit/failure.yml +462 -0
  177. data/spec/fixtures/responses/shipment/submit/one_shipment.yml +464 -0
  178. data/spec/fixtures/responses/shipment/submit/two_shipments.yml +56 -0
  179. data/spec/fixtures/responses/shipping_service/get_shipping_carrier_list.yml +953 -0
  180. data/spec/fixtures/responses/shipping_service/ping/failure.yml +55 -0
  181. data/spec/fixtures/responses/shipping_service/ping/success.yml +460 -0
  182. data/spec/fixtures/responses/shipping_service/submit_order_shipment_list.yml +55 -0
  183. data/spec/fixtures/responses/soap_fault.yml +53 -0
  184. data/spec/lib/channeladvisor/address_spec.rb +107 -0
  185. data/spec/lib/channeladvisor/admin_spec.rb +216 -0
  186. data/spec/lib/channeladvisor/line_item_spec.rb +147 -0
  187. data/spec/lib/channeladvisor/order_spec.rb +623 -0
  188. data/spec/lib/channeladvisor/order_status_spec.rb +36 -0
  189. data/spec/lib/channeladvisor/payment_spec.rb +38 -0
  190. data/spec/lib/channeladvisor/services/admin_service_spec.rb +65 -0
  191. data/spec/lib/channeladvisor/services/base_service_spec.rb +11 -0
  192. data/spec/lib/channeladvisor/services/inventory_service_spec.rb +214 -0
  193. data/spec/lib/channeladvisor/services/order_service_spec.rb +267 -0
  194. data/spec/lib/channeladvisor/services/shipping_service_spec.rb +288 -0
  195. data/spec/lib/channeladvisor/shipment_spec.rb +257 -0
  196. data/spec/lib/channeladvisor/shopping_cart_spec.rb +173 -0
  197. data/spec/lib/channeladvisor_spec.rb +18 -0
  198. data/spec/spec_helper.rb +29 -0
  199. data/spec/support/credentials.rb +15 -0
  200. data/spec/support/matchers/boolean.rb +17 -0
  201. data/spec/support/matchers/markup.rb +50 -0
  202. data/spec/support/rr.rb +38 -0
  203. data/spec/support/shared_examples.rb +4 -0
  204. data/spec/support/vcr.rb +38 -0
  205. metadata +501 -0
@@ -0,0 +1,288 @@
1
+ require 'spec_helper'
2
+ require 'timecop'
3
+
4
+ module ChannelAdvisor
5
+ module Services
6
+ describe ShippingService do
7
+ describe ".ping" do
8
+ use_vcr_cassette "responses/shipping_service/ping/success", :allow_playback_repeats => true
9
+
10
+ before(:each) do
11
+ @last_request, @last_response = nil
12
+
13
+ ShippingService.client.config.hooks.define(:ping, :soap_request) do |callback, request|
14
+ @last_request = request.http
15
+ @last_response = callback.call
16
+ end
17
+ end
18
+
19
+ it "sends a valid SOAP request" do
20
+ ShippingService.ping
21
+ @last_request.should match_valid_xml_body_for :ping
22
+ end
23
+
24
+ it "returns a SOAP response" do
25
+ soap_response = ShippingService.ping
26
+ soap_response.should be_a Savon::SOAP::Response
27
+ end
28
+ end # .ping
29
+
30
+ describe ".submit_order_shipment_list" do
31
+ use_vcr_cassette "responses/shipping_service/submit_order_shipment_list", :allow_playback_repeats => true
32
+
33
+ before(:each) do
34
+ @last_request, @last_response = nil
35
+
36
+ ShippingService.client.config.hooks.define(:submit_order_shipment_list, :soap_request) do |callback, request|
37
+ @last_request = request.http
38
+ @last_response = callback.call
39
+ end
40
+ end
41
+
42
+ context "with full shipments" do
43
+ let(:full_shipment) do
44
+ {
45
+ :order_id => 123456,
46
+ :client_order_id => "ABCD1234",
47
+ :type => "Full",
48
+ :date => DateTime.new(2012,05,19),
49
+ :carrier => "UPS",
50
+ :class => "GND",
51
+ :tracking_number => "1ZABCE09813473497",
52
+ :seller_id => "999999",
53
+ :cost => "5.99",
54
+ :tax => "1.99",
55
+ :insurance => "2.99"
56
+ }
57
+ end
58
+
59
+ it "returns a SOAP response" do
60
+ soap_response = ShippingService.submit_order_shipment_list([full_shipment])
61
+ soap_response.should be_a Savon::SOAP::Response
62
+ end
63
+
64
+ context "with one full shipment" do
65
+ it "sends a valid SOAP request with full shipment data" do
66
+ ShippingService.submit_order_shipment_list([full_shipment])
67
+ @last_request.should match_valid_xml_body_for "submit_order_shipment_list/full_shipment/with_one_shipment"
68
+ end
69
+
70
+ context "without a client order ID" do
71
+ it "sends a valid SOAP request without the client order ID" do
72
+ full_shipment.delete(:client_order_id)
73
+ ShippingService.submit_order_shipment_list([full_shipment])
74
+ @last_request.should match_valid_xml_body_for "submit_order_shipment_list/full_shipment/without_client_order_id"
75
+ end
76
+ end
77
+
78
+ context "without a carrier code" do
79
+ it "sends a valid SOAP request without the carrier code" do
80
+ full_shipment.delete(:carrier)
81
+ ShippingService.submit_order_shipment_list([full_shipment])
82
+ @last_request.should match_valid_xml_body_for "submit_order_shipment_list/full_shipment/without_carrier_code"
83
+ end
84
+ end
85
+
86
+ context "without a class code" do
87
+ it "sends a valid SOAP request without the class code" do
88
+ full_shipment.delete(:class)
89
+ ShippingService.submit_order_shipment_list([full_shipment])
90
+ @last_request.should match_valid_xml_body_for "submit_order_shipment_list/full_shipment/without_class_code"
91
+ end
92
+ end
93
+
94
+ context "without a tracking number" do
95
+ it "sends a valid SOAP request without the tracking number" do
96
+ full_shipment.delete(:tracking_number)
97
+ ShippingService.submit_order_shipment_list([full_shipment])
98
+ @last_request.should match_valid_xml_body_for "submit_order_shipment_list/full_shipment/without_tracking_number"
99
+ end
100
+ end
101
+
102
+ context "without a seller fulfillment ID" do
103
+ it "sends a valid SOAP request without the seller fulfillment ID" do
104
+ full_shipment.delete(:seller_id)
105
+ ShippingService.submit_order_shipment_list([full_shipment])
106
+ @last_request.should match_valid_xml_body_for "submit_order_shipment_list/full_shipment/without_seller_id"
107
+ end
108
+ end
109
+ end # with one full shipment
110
+
111
+ context "with two full shipments" do
112
+ it "sends a valid SOAP request with two full shipments" do
113
+ shipments = []
114
+ second_shipment = {
115
+ :order_id => 567890,
116
+ :client_order_id => "EFGH1234",
117
+ :type => "Full",
118
+ :date => DateTime.new(2012,05,21),
119
+ :carrier => "FEDEX",
120
+ :class => "GROUND",
121
+ :tracking_number => "1234567890",
122
+ :seller_id => "555555",
123
+ :cost => "7.50",
124
+ :tax => "1.50",
125
+ :insurance => "2.50"
126
+ }
127
+ shipments << full_shipment
128
+ shipments << second_shipment
129
+ ShippingService.submit_order_shipment_list(shipments)
130
+ @last_request.should match_valid_xml_body_for "submit_order_shipment_list/full_shipment/with_two_shipments"
131
+ end
132
+ end # with two full shipments
133
+ end # with full shipments
134
+
135
+ context "with partial shipments" do
136
+ let(:partial_shipment) do
137
+ {
138
+ :order_id => 123456,
139
+ :client_order_id => "ABCD1234",
140
+ :type => "Partial",
141
+ :line_items => [{:sku => "ABCD", :quantity => 5}],
142
+ :date => DateTime.new(2012,05,19),
143
+ :carrier => "UPS",
144
+ :class => "GND",
145
+ :tracking_number => "1ZABCE09813473497",
146
+ :seller_id => "999999",
147
+ :cost => "5.99",
148
+ :tax => "1.99",
149
+ :insurance => "2.99"
150
+ }
151
+ end
152
+
153
+ context "with one partial shipment" do
154
+ context "with one line item" do
155
+ it "sends a valid SOAP request with one line item" do
156
+ ShippingService.submit_order_shipment_list([partial_shipment])
157
+ @last_request.should match_valid_xml_body_for "submit_order_shipment_list/partial_shipment/with_one_line_item"
158
+ end
159
+
160
+ context "without a carrier code" do
161
+ it "sends a valid SOAP request without the carrier code" do
162
+ partial_shipment.delete(:carrier)
163
+ ShippingService.submit_order_shipment_list([partial_shipment])
164
+ @last_request.should match_valid_xml_body_for "submit_order_shipment_list/partial_shipment/without_carrier_code"
165
+ end
166
+ end
167
+
168
+ context "without a class code" do
169
+ it "sends a valid SOAP request without the class code" do
170
+ partial_shipment.delete(:class)
171
+ ShippingService.submit_order_shipment_list([partial_shipment])
172
+ @last_request.should match_valid_xml_body_for "submit_order_shipment_list/partial_shipment/without_class_code"
173
+ end
174
+ end
175
+
176
+ context "without a tracking number" do
177
+ it "sends a valid SOAP request without the tracking number" do
178
+ partial_shipment.delete(:tracking_number)
179
+ ShippingService.submit_order_shipment_list([partial_shipment])
180
+ @last_request.should match_valid_xml_body_for "submit_order_shipment_list/partial_shipment/without_tracking_number"
181
+ end
182
+ end
183
+
184
+ context "without a seller fulfillment ID" do
185
+ it "sends a valid SOAP request without the seller fulfillment ID" do
186
+ partial_shipment.delete(:seller_id)
187
+ ShippingService.submit_order_shipment_list([partial_shipment])
188
+ @last_request.should match_valid_xml_body_for "submit_order_shipment_list/partial_shipment/without_seller_id"
189
+ end
190
+ end
191
+ end
192
+
193
+ context "with two line items" do
194
+ it "sends a valid SOAP request with two line items" do
195
+ partial_shipment[:line_items] << {:sku => "EFGH", :quantity => 3}
196
+ ShippingService.submit_order_shipment_list([partial_shipment])
197
+ @last_request.should match_valid_xml_body_for "submit_order_shipment_list/partial_shipment/with_two_line_items"
198
+ end
199
+ end
200
+ end # with one partial shipment
201
+
202
+ context "with two partial shipments" do
203
+ it "sends a valid SOAP request with two partial shipments" do
204
+ shipments = []
205
+ second_shipment = {
206
+ :order_id => 567890,
207
+ :client_order_id => "EFGH1234",
208
+ :type => "Partial",
209
+ :line_items => [{:sku => "EFGH", :quantity => 3}],
210
+ :date => DateTime.new(2012,05,21),
211
+ :carrier => "FEDEX",
212
+ :class => "GROUND",
213
+ :tracking_number => "1234567890",
214
+ :seller_id => "555555",
215
+ :cost => "7.50",
216
+ :tax => "1.50",
217
+ :insurance => "2.50"
218
+ }
219
+ shipments << partial_shipment
220
+ shipments << second_shipment
221
+ ShippingService.submit_order_shipment_list(shipments)
222
+ @last_request.should match_valid_xml_body_for "submit_order_shipment_list/partial_shipment/with_two_shipments"
223
+ end
224
+ end # with two partial shipments
225
+ end # with partial shipments
226
+
227
+ context "with both partial and full shipments" do
228
+ it "sends a valid SOAP request with two partial shipments" do
229
+ shipments = []
230
+ full_shipment = {
231
+ :order_id => 123456,
232
+ :client_order_id => "ABCD1234",
233
+ :type => "Full",
234
+ :date => DateTime.new(2012,05,19),
235
+ :carrier => "UPS",
236
+ :class => "GND",
237
+ :tracking_number => "1ZABCE09813473497",
238
+ :seller_id => "999999",
239
+ :cost => "5.99",
240
+ :tax => "1.99",
241
+ :insurance => "2.99"
242
+ }
243
+ partial_shipment = {
244
+ :order_id => 567890,
245
+ :client_order_id => "EFGH1234",
246
+ :type => "Partial",
247
+ :line_items => [{:sku => "EFGH", :quantity => 3}],
248
+ :date => DateTime.new(2012,05,21),
249
+ :carrier => "FEDEX",
250
+ :class => "GROUND",
251
+ :tracking_number => "1234567890",
252
+ :seller_id => "555555",
253
+ :cost => "7.50",
254
+ :tax => "1.50",
255
+ :insurance => "2.50"
256
+ }
257
+ shipments << full_shipment
258
+ shipments << partial_shipment
259
+ ShippingService.submit_order_shipment_list(shipments)
260
+ @last_request.should match_valid_xml_body_for "submit_order_shipment_list/with_partial_and_full_shipments"
261
+ end
262
+ end # with both full and partial shipments
263
+ end # .submit_order_shipment_list
264
+
265
+ describe ".get_shipping_carrier_list" do
266
+ use_vcr_cassette "responses/shipping_service/get_shipping_carrier_list", :allow_playback_repeats => true
267
+ before(:each) do
268
+ @last_request, @last_response = nil
269
+
270
+ ShippingService.client.config.hooks.define(:get_shipping_carrier_list, :soap_request) do |callback, request|
271
+ @last_request = request.http
272
+ @last_response = callback.call
273
+ end
274
+ end
275
+
276
+ it "sends a valid SOAP request" do
277
+ ShippingService.get_shipping_carrier_list
278
+ @last_request.should match_valid_xml_body_for :get_shipping_carrier_list
279
+ end
280
+
281
+ it "returns a SOAP response" do
282
+ soap_response = ShippingService.get_shipping_carrier_list
283
+ soap_response.should be_a Savon::SOAP::Response
284
+ end
285
+ end # .get_shipping_carrier_list
286
+ end # ShippingService
287
+ end # Services
288
+ end # ChannelAdvisor
@@ -0,0 +1,257 @@
1
+ require 'spec_helper'
2
+ require 'timecop'
3
+
4
+ module ChannelAdvisor
5
+ describe Shipment do
6
+ describe ".new" do
7
+ before(:each) do
8
+ @attrs = {
9
+ :shipping_carrier => "UPS",
10
+ :shipping_class => "GND",
11
+ :tracking_number => "1234567890"
12
+ }
13
+ @shipment = Shipment.new(@attrs)
14
+ end
15
+
16
+ it "sets @shipping_carrier" do
17
+ @shipment.shipping_carrier.should == @attrs[:shipping_carrier]
18
+ end
19
+
20
+ it "sets @shipping_class" do
21
+ @shipment.shipping_class.should == @attrs[:shipping_class]
22
+ end
23
+
24
+ it "sets @tracking_number" do
25
+ @shipment.tracking_number.should == @attrs[:tracking_number]
26
+ end
27
+ end # .new
28
+
29
+ describe ".submit" do
30
+ use_vcr_cassette "responses/shipment/submit", :allow_playback_repeats => true
31
+ before { stub.proxy(Services::ShippingService).submit_order_shipment_list }
32
+
33
+ let(:original_shipment) do
34
+ {
35
+ :order_id => 123456,
36
+ :client_order_id => "ABCD1234",
37
+ :date => DateTime.new(2012,05,19),
38
+ :carrier => "UPS",
39
+ :class => "GND",
40
+ :tracking_number => "1ZABCE09813473497",
41
+ :seller_id => "999999",
42
+ :cost => 5.99,
43
+ :tax => 1.99,
44
+ :insurance => 2.99
45
+ }
46
+ end
47
+
48
+ context "with one shipment" do
49
+ use_vcr_cassette "responses/shipment/submit/one_shipment"
50
+
51
+ let(:actual_shipment) { original_shipment.dup }
52
+ before do
53
+ actual_shipment[:type] = "Full"
54
+ actual_shipment[:cost] = "%.2f" % actual_shipment[:cost]
55
+ actual_shipment[:tax] = "%.2f" % actual_shipment[:tax]
56
+ actual_shipment[:insurance] = "%.2f" % actual_shipment[:insurance]
57
+ end
58
+
59
+ it "sends one shipment to the shipping service" do
60
+ Shipment.submit(original_shipment)
61
+ Services::ShippingService.should have_received.submit_order_shipment_list([actual_shipment])
62
+ end
63
+
64
+ it "returns a boolean result" do
65
+ response = Shipment.submit(original_shipment)
66
+ response.should be_a_boolean
67
+ end
68
+
69
+ context "without a ship date" do
70
+ it "sends a shipment with the current date" do
71
+ original_shipment.delete(:date)
72
+ ::Timecop.freeze(DateTime.now) do
73
+ actual_shipment[:date] = DateTime.now
74
+ Shipment.submit(original_shipment)
75
+ Services::ShippingService.should have_received.submit_order_shipment_list([actual_shipment])
76
+ end
77
+ end
78
+ end
79
+
80
+ context "without a ship cost" do
81
+ it "sends a shipment with a shipping cost of 0.00" do
82
+ original_shipment.delete(:cost)
83
+ actual_shipment[:cost] = "0.00"
84
+ Shipment.submit(original_shipment)
85
+ Services::ShippingService.should have_received.submit_order_shipment_list([actual_shipment])
86
+ end
87
+ end
88
+
89
+ context "without a tax cost" do
90
+ it "sends a shipment with a tax cost of 0.00" do
91
+ original_shipment.delete(:tax)
92
+ actual_shipment[:tax] = "0.00"
93
+ Shipment.submit(original_shipment)
94
+ Services::ShippingService.should have_received.submit_order_shipment_list([actual_shipment])
95
+ end
96
+ end
97
+
98
+ context "without an insurance cost" do
99
+ it "sends a shipment with an insurance cost of 0.00" do
100
+ original_shipment.delete(:insurance)
101
+ actual_shipment[:insurance] = "0.00"
102
+ Shipment.submit(original_shipment)
103
+ Services::ShippingService.should have_received.submit_order_shipment_list([actual_shipment])
104
+ end
105
+ end
106
+
107
+ context "with line items" do
108
+ it "sends a partial shipment" do
109
+ actual_shipment[:line_items] = original_shipment[:line_items] = [{:sku => "ABCD", :quantity => 5}]
110
+ actual_shipment[:type] = "Partial"
111
+ Shipment.submit(original_shipment)
112
+ Services::ShippingService.should have_received.submit_order_shipment_list([actual_shipment])
113
+ end
114
+ end
115
+ end # with one shipment
116
+
117
+ context "with two shipments" do
118
+ use_vcr_cassette "responses/shipment/submit/two_shipments", :allow_playback_repeats => true
119
+
120
+ let(:shipment1) { original_shipment.dup }
121
+ let(:shipment2) do
122
+ {
123
+ :order_id => 567890,
124
+ :client_order_id => "EFGH1234",
125
+ :date => DateTime.new(2012,05,19),
126
+ :carrier => "USPS",
127
+ :class => "PRIORITY",
128
+ :tracking_number => "99999000000000",
129
+ :seller_id => "555555",
130
+ :cost => 5.99,
131
+ :tax => 1.99,
132
+ :insurance => 2.99
133
+ }
134
+ end
135
+ let(:shipments) { [shipment1, shipment2] }
136
+
137
+ it "sends two shipments to the shipping service" do
138
+ Shipment.submit(shipments)
139
+ Services::ShippingService.should have_received.submit_order_shipment_list(shipments)
140
+ end
141
+
142
+ it "returns hash of boolean results" do
143
+ results = Shipment.submit(shipments)
144
+ shipments.map { |shipment| shipment[:order_id].to_s }.each do |order_id|
145
+ results[order_id].should be_a_boolean
146
+ end
147
+ end
148
+ end # with two shipments
149
+
150
+ context "with a Failure status" do
151
+ use_vcr_cassette "responses/shipment/submit/failure", :allow_playback_repeats => true
152
+
153
+ it "raises a ServiceFailure error" do
154
+ expect { Shipment.submit(original_shipment) }.to raise_error ServiceFailure
155
+ end
156
+ end
157
+
158
+ context "with a SOAP fault" do
159
+ use_vcr_cassette "responses/soap_fault", :match_requests_on => [:method], :allow_playback_repeats => true
160
+
161
+ it "raises a SOAP fault error" do
162
+ expect { Shipment.submit(original_shipment) }.to raise_error SOAPFault, "Server was unable to process request. Authentication failed."
163
+ end
164
+
165
+ it "stores the SOAP fault code" do
166
+ begin
167
+ Shipment.submit(original_shipment)
168
+ rescue SOAPFault => fault
169
+ fault.code.should == "soap:Server"
170
+ end
171
+ end
172
+ end # with a SOAP Fault
173
+
174
+ context "with an HTTP error" do
175
+ http_status = {:code => 500, :message => "Internal Server Error"}
176
+ use_vcr_cassette "responses/http_error", :match_requests_on => [:method], :erb => http_status, :allow_playback_repeats => true
177
+
178
+ it "raises an HTTP error" do
179
+ expect { Shipment.submit(original_shipment) }.to raise_error HTTPError, "Failed with HTTP error #{http_status[:code]}"
180
+ end
181
+
182
+ it "stores the HTTP status code" do
183
+ begin
184
+ Shipment.submit(original_shipment)
185
+ rescue HTTPError => error
186
+ error.code.should == http_status[:code]
187
+ end
188
+ end
189
+ end # with an HTTP error
190
+ end # .submit
191
+
192
+ describe ".get_carriers" do
193
+ use_vcr_cassette "responses/shipment/get_carriers", :allow_playback_repeats => true
194
+
195
+ it "calls the get_shipping_carrier_list" do
196
+ stub.proxy(Services::ShippingService).get_shipping_carrier_list
197
+ Shipment.get_carriers
198
+ Services::ShippingService.should have_received.get_shipping_carrier_list
199
+ end
200
+
201
+ it "returns an array of shipping carrier hashes" do
202
+ results = Shipment.get_carriers
203
+ results.each do |carrier_data|
204
+ carrier_data.should include(
205
+ :carrier_id,
206
+ :class_id,
207
+ :carrier_name,
208
+ :carrier_code,
209
+ :class_code,
210
+ :class_name
211
+ )
212
+ end
213
+ end
214
+
215
+ context "with a Failure status" do
216
+ use_vcr_cassette "responses/shipment/get_carriers/failure", :allow_playback_repeats => true
217
+
218
+ it "raises a ServiceFailure error" do
219
+ expect { Shipment.get_carriers }.to raise_error ServiceFailure
220
+ end
221
+ end
222
+
223
+ context "with a SOAP fault" do
224
+ use_vcr_cassette "responses/soap_fault", :match_requests_on => [:method], :allow_playback_repeats => true
225
+
226
+ it "raises a SOAP fault error" do
227
+ expect { Shipment.get_carriers }.to raise_error SOAPFault, "Server was unable to process request. Authentication failed."
228
+ end
229
+
230
+ it "stores the SOAP fault code" do
231
+ begin
232
+ Shipment.get_carriers
233
+ rescue SOAPFault => fault
234
+ fault.code.should == "soap:Server"
235
+ end
236
+ end
237
+ end # with a SOAP Fault
238
+
239
+ context "with an HTTP error" do
240
+ http_status = {:code => 500, :message => "Internal Server Error"}
241
+ use_vcr_cassette "responses/http_error", :match_requests_on => [:method], :erb => http_status, :allow_playback_repeats => true
242
+
243
+ it "raises an HTTP error" do
244
+ expect { Shipment.get_carriers }.to raise_error HTTPError, "Failed with HTTP error #{http_status[:code]}"
245
+ end
246
+
247
+ it "stores the HTTP status code" do
248
+ begin
249
+ Shipment.get_carriers
250
+ rescue HTTPError => error
251
+ error.code.should == http_status[:code]
252
+ end
253
+ end
254
+ end # with an HTTP error
255
+ end # .get_carriers
256
+ end # Shipment
257
+ end # ChannelAdvisor