channeladvisor 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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