solidus_api 1.0.0.pre

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 (202) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/CHANGELOG.md +1 -0
  4. data/Gemfile +5 -0
  5. data/LICENSE +27 -0
  6. data/Rakefile +16 -0
  7. data/app/controllers/spree/api/addresses_controller.rb +43 -0
  8. data/app/controllers/spree/api/base_controller.rb +189 -0
  9. data/app/controllers/spree/api/checkouts_controller.rb +133 -0
  10. data/app/controllers/spree/api/classifications_controller.rb +18 -0
  11. data/app/controllers/spree/api/config_controller.rb +6 -0
  12. data/app/controllers/spree/api/countries_controller.rb +23 -0
  13. data/app/controllers/spree/api/credit_cards_controller.rb +25 -0
  14. data/app/controllers/spree/api/images_controller.rb +47 -0
  15. data/app/controllers/spree/api/inventory_units_controller.rb +52 -0
  16. data/app/controllers/spree/api/line_items_controller.rb +74 -0
  17. data/app/controllers/spree/api/option_types_controller.rb +49 -0
  18. data/app/controllers/spree/api/option_values_controller.rb +58 -0
  19. data/app/controllers/spree/api/orders_controller.rb +155 -0
  20. data/app/controllers/spree/api/payments_controller.rb +81 -0
  21. data/app/controllers/spree/api/product_properties_controller.rb +72 -0
  22. data/app/controllers/spree/api/products_controller.rb +129 -0
  23. data/app/controllers/spree/api/promotions_controller.rb +26 -0
  24. data/app/controllers/spree/api/properties_controller.rb +71 -0
  25. data/app/controllers/spree/api/return_authorizations_controller.rb +71 -0
  26. data/app/controllers/spree/api/shipments_controller.rb +172 -0
  27. data/app/controllers/spree/api/states_controller.rb +35 -0
  28. data/app/controllers/spree/api/stock_items_controller.rb +84 -0
  29. data/app/controllers/spree/api/stock_locations_controller.rb +50 -0
  30. data/app/controllers/spree/api/stock_movements_controller.rb +42 -0
  31. data/app/controllers/spree/api/stock_transfers_controller.rb +19 -0
  32. data/app/controllers/spree/api/store_credit_events_controller.rb +9 -0
  33. data/app/controllers/spree/api/stores_controller.rb +55 -0
  34. data/app/controllers/spree/api/taxonomies_controller.rb +64 -0
  35. data/app/controllers/spree/api/taxons_controller.rb +93 -0
  36. data/app/controllers/spree/api/transfer_items_controller.rb +42 -0
  37. data/app/controllers/spree/api/users_controller.rb +56 -0
  38. data/app/controllers/spree/api/variants_controller.rb +75 -0
  39. data/app/controllers/spree/api/zones_controller.rb +50 -0
  40. data/app/helpers/spree/api/api_helpers.rb +190 -0
  41. data/app/models/spree/api_configuration.rb +5 -0
  42. data/app/models/spree/option_value_decorator.rb +9 -0
  43. data/app/views/spree/api/addresses/show.v1.rabl +10 -0
  44. data/app/views/spree/api/adjustments/show.v1.rabl +4 -0
  45. data/app/views/spree/api/config/money.v1.rabl +2 -0
  46. data/app/views/spree/api/config/show.v1.rabl +2 -0
  47. data/app/views/spree/api/countries/index.v1.rabl +7 -0
  48. data/app/views/spree/api/countries/show.v1.rabl +5 -0
  49. data/app/views/spree/api/credit_cards/index.v1.rabl +7 -0
  50. data/app/views/spree/api/credit_cards/show.v1.rabl +3 -0
  51. data/app/views/spree/api/errors/gateway_error.v1.rabl +2 -0
  52. data/app/views/spree/api/errors/invalid_api_key.v1.rabl +2 -0
  53. data/app/views/spree/api/errors/invalid_resource.v1.rabl +3 -0
  54. data/app/views/spree/api/errors/must_specify_api_key.v1.rabl +2 -0
  55. data/app/views/spree/api/errors/not_found.v1.rabl +2 -0
  56. data/app/views/spree/api/errors/unauthorized.v1.rabl +2 -0
  57. data/app/views/spree/api/errors/variant_not_in_stock_transfer.v1.rabl +2 -0
  58. data/app/views/spree/api/images/index.v1.rabl +4 -0
  59. data/app/views/spree/api/images/show.v1.rabl +6 -0
  60. data/app/views/spree/api/inventory_units/show.rabl +2 -0
  61. data/app/views/spree/api/line_items/new.v1.rabl +3 -0
  62. data/app/views/spree/api/line_items/show.v1.rabl +15 -0
  63. data/app/views/spree/api/option_types/index.v1.rabl +3 -0
  64. data/app/views/spree/api/option_types/show.v1.rabl +5 -0
  65. data/app/views/spree/api/option_values/index.v1.rabl +3 -0
  66. data/app/views/spree/api/option_values/show.v1.rabl +2 -0
  67. data/app/views/spree/api/orders/address.v1.rabl +0 -0
  68. data/app/views/spree/api/orders/canceled.v1.rabl +0 -0
  69. data/app/views/spree/api/orders/cart.v1.rabl +0 -0
  70. data/app/views/spree/api/orders/complete.v1.rabl +0 -0
  71. data/app/views/spree/api/orders/could_not_apply_coupon.v1.rabl +2 -0
  72. data/app/views/spree/api/orders/could_not_transition.v1.rabl +3 -0
  73. data/app/views/spree/api/orders/expected_total_mismatch.v1.rabl +2 -0
  74. data/app/views/spree/api/orders/index.v1.rabl +7 -0
  75. data/app/views/spree/api/orders/invalid_shipping_method.v1.rabl +2 -0
  76. data/app/views/spree/api/orders/mine.v1.rabl +9 -0
  77. data/app/views/spree/api/orders/order.v1.rabl +9 -0
  78. data/app/views/spree/api/orders/payment.v1.rabl +3 -0
  79. data/app/views/spree/api/orders/show.v1.rabl +52 -0
  80. data/app/views/spree/api/payments/credit_over_limit.v1.rabl +2 -0
  81. data/app/views/spree/api/payments/index.v1.rabl +7 -0
  82. data/app/views/spree/api/payments/new.v1.rabl +5 -0
  83. data/app/views/spree/api/payments/show.v1.rabl +2 -0
  84. data/app/views/spree/api/payments/update_forbidden.v1.rabl +2 -0
  85. data/app/views/spree/api/product_properties/index.v1.rabl +7 -0
  86. data/app/views/spree/api/product_properties/new.v1.rabl +2 -0
  87. data/app/views/spree/api/product_properties/show.v1.rabl +2 -0
  88. data/app/views/spree/api/products/index.v1.rabl +9 -0
  89. data/app/views/spree/api/products/new.v1.rabl +3 -0
  90. data/app/views/spree/api/products/product.v1.rabl +1 -0
  91. data/app/views/spree/api/products/show.v1.rabl +31 -0
  92. data/app/views/spree/api/promotions/handler.v1.rabl +5 -0
  93. data/app/views/spree/api/promotions/show.v1.rabl +2 -0
  94. data/app/views/spree/api/properties/index.v1.rabl +7 -0
  95. data/app/views/spree/api/properties/new.v1.rabl +2 -0
  96. data/app/views/spree/api/properties/show.v1.rabl +2 -0
  97. data/app/views/spree/api/return_authorizations/index.v1.rabl +7 -0
  98. data/app/views/spree/api/return_authorizations/new.v1.rabl +3 -0
  99. data/app/views/spree/api/return_authorizations/show.v1.rabl +2 -0
  100. data/app/views/spree/api/shared/stock_location_required.v1.rabl +2 -0
  101. data/app/views/spree/api/shipments/big.v1.rabl +48 -0
  102. data/app/views/spree/api/shipments/cannot_ready_shipment.v1.rabl +2 -0
  103. data/app/views/spree/api/shipments/mine.v1.rabl +9 -0
  104. data/app/views/spree/api/shipments/show.v1.rabl +32 -0
  105. data/app/views/spree/api/shipments/small.v1.rabl +37 -0
  106. data/app/views/spree/api/shipping_rates/show.v1.rabl +2 -0
  107. data/app/views/spree/api/states/index.v1.rabl +14 -0
  108. data/app/views/spree/api/states/show.v1.rabl +2 -0
  109. data/app/views/spree/api/stock_items/index.v1.rabl +7 -0
  110. data/app/views/spree/api/stock_items/show.v1.rabl +5 -0
  111. data/app/views/spree/api/stock_locations/index.v1.rabl +7 -0
  112. data/app/views/spree/api/stock_locations/show.v1.rabl +8 -0
  113. data/app/views/spree/api/stock_movements/index.v1.rabl +7 -0
  114. data/app/views/spree/api/stock_movements/show.v1.rabl +5 -0
  115. data/app/views/spree/api/stock_transfers/receive.v1.rabl +5 -0
  116. data/app/views/spree/api/store_credit_events/mine.v1.rabl +10 -0
  117. data/app/views/spree/api/stores/index.v1.rabl +4 -0
  118. data/app/views/spree/api/stores/show.v1.rabl +2 -0
  119. data/app/views/spree/api/taxonomies/index.v1.rabl +7 -0
  120. data/app/views/spree/api/taxonomies/jstree.rabl +8 -0
  121. data/app/views/spree/api/taxonomies/nested.v1.rabl +11 -0
  122. data/app/views/spree/api/taxonomies/new.v1.rabl +3 -0
  123. data/app/views/spree/api/taxonomies/show.v1.rabl +15 -0
  124. data/app/views/spree/api/taxons/index.v1.rabl +12 -0
  125. data/app/views/spree/api/taxons/jstree.rabl +8 -0
  126. data/app/views/spree/api/taxons/new.v1.rabl +3 -0
  127. data/app/views/spree/api/taxons/show.v1.rabl +6 -0
  128. data/app/views/spree/api/taxons/taxons.v1.rabl +5 -0
  129. data/app/views/spree/api/transfer_items/show.v1.rabl +6 -0
  130. data/app/views/spree/api/users/index.v1.rabl +7 -0
  131. data/app/views/spree/api/users/new.v1.rabl +3 -0
  132. data/app/views/spree/api/users/show.v1.rabl +10 -0
  133. data/app/views/spree/api/variants/big.v1.rabl +17 -0
  134. data/app/views/spree/api/variants/index.v1.rabl +9 -0
  135. data/app/views/spree/api/variants/new.v1.rabl +2 -0
  136. data/app/views/spree/api/variants/show.v1.rabl +3 -0
  137. data/app/views/spree/api/variants/small.v1.rabl +17 -0
  138. data/app/views/spree/api/zones/index.v1.rabl +7 -0
  139. data/app/views/spree/api/zones/show.v1.rabl +6 -0
  140. data/config/initializers/metal_load_paths.rb +1 -0
  141. data/config/locales/en.yml +29 -0
  142. data/config/routes.rb +139 -0
  143. data/db/migrate/20100107141738_add_api_key_to_spree_users.rb +7 -0
  144. data/db/migrate/20120411123334_resize_api_key_field.rb +7 -0
  145. data/db/migrate/20120530054546_rename_api_key_to_spree_api_key.rb +7 -0
  146. data/db/migrate/20131017162334_add_index_to_user_spree_api_key.rb +7 -0
  147. data/lib/solidus_api.rb +1 -0
  148. data/lib/spree/api/engine.rb +38 -0
  149. data/lib/spree/api/responders/rabl_template.rb +31 -0
  150. data/lib/spree/api/responders.rb +11 -0
  151. data/lib/spree/api/testing_support/caching.rb +10 -0
  152. data/lib/spree/api/testing_support/helpers.rb +44 -0
  153. data/lib/spree/api/testing_support/setup.rb +16 -0
  154. data/lib/spree/api.rb +10 -0
  155. data/lib/spree_api.rb +3 -0
  156. data/script/rails +9 -0
  157. data/solidus_api.gemspec +21 -0
  158. data/spec/controllers/spree/api/addresses_controller_spec.rb +56 -0
  159. data/spec/controllers/spree/api/base_controller_spec.rb +164 -0
  160. data/spec/controllers/spree/api/checkouts_controller_spec.rb +386 -0
  161. data/spec/controllers/spree/api/classifications_controller_spec.rb +48 -0
  162. data/spec/controllers/spree/api/config_controller_spec.rb +23 -0
  163. data/spec/controllers/spree/api/countries_controller_spec.rb +48 -0
  164. data/spec/controllers/spree/api/credit_cards_controller_spec.rb +80 -0
  165. data/spec/controllers/spree/api/images_controller_spec.rb +93 -0
  166. data/spec/controllers/spree/api/inventory_units_controller_spec.rb +50 -0
  167. data/spec/controllers/spree/api/line_items_controller_spec.rb +186 -0
  168. data/spec/controllers/spree/api/option_types_controller_spec.rb +116 -0
  169. data/spec/controllers/spree/api/option_values_controller_spec.rb +135 -0
  170. data/spec/controllers/spree/api/orders_controller_spec.rb +759 -0
  171. data/spec/controllers/spree/api/payments_controller_spec.rb +254 -0
  172. data/spec/controllers/spree/api/product_properties_controller_spec.rb +116 -0
  173. data/spec/controllers/spree/api/products_controller_spec.rb +454 -0
  174. data/spec/controllers/spree/api/promotion_application_spec.rb +50 -0
  175. data/spec/controllers/spree/api/promotions_controller_spec.rb +64 -0
  176. data/spec/controllers/spree/api/properties_controller_spec.rb +102 -0
  177. data/spec/controllers/spree/api/return_authorizations_controller_spec.rb +173 -0
  178. data/spec/controllers/spree/api/shipments_controller_spec.rb +252 -0
  179. data/spec/controllers/spree/api/states_controller_spec.rb +82 -0
  180. data/spec/controllers/spree/api/stock_items_controller_spec.rb +307 -0
  181. data/spec/controllers/spree/api/stock_locations_controller_spec.rb +172 -0
  182. data/spec/controllers/spree/api/stock_movements_controller_spec.rb +84 -0
  183. data/spec/controllers/spree/api/stock_transfers_controller_spec.rb +83 -0
  184. data/spec/controllers/spree/api/store_credit_events_controller_spec.rb +68 -0
  185. data/spec/controllers/spree/api/stores_controller_spec.rb +133 -0
  186. data/spec/controllers/spree/api/taxonomies_controller_spec.rb +114 -0
  187. data/spec/controllers/spree/api/taxons_controller_spec.rb +177 -0
  188. data/spec/controllers/spree/api/transfer_items_controller_spec.rb +152 -0
  189. data/spec/controllers/spree/api/unauthenticated_products_controller_spec.rb +26 -0
  190. data/spec/controllers/spree/api/users_controller_spec.rb +153 -0
  191. data/spec/controllers/spree/api/variants_controller_spec.rb +235 -0
  192. data/spec/controllers/spree/api/zones_controller_spec.rb +115 -0
  193. data/spec/features/checkout_spec.rb +187 -0
  194. data/spec/fixtures/thinking-cat.jpg +0 -0
  195. data/spec/models/spree/legacy_user_spec.rb +45 -0
  196. data/spec/requests/rabl_cache_spec.rb +32 -0
  197. data/spec/shared_examples/protect_product_actions.rb +17 -0
  198. data/spec/spec_helper.rb +60 -0
  199. data/spec/support/controller_hacks.rb +38 -0
  200. data/spec/support/database_cleaner.rb +14 -0
  201. data/spec/support/have_attributes_matcher.rb +13 -0
  202. metadata +334 -0
@@ -0,0 +1,173 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Api::ReturnAuthorizationsController, :type => :controller do
5
+ render_views
6
+
7
+ let!(:order) { create(:shipped_order) }
8
+
9
+ let(:product) { create(:product) }
10
+ let(:attributes) { [:id, :memo, :state] }
11
+ let(:resource_scoping) { { :order_id => order.to_param } }
12
+
13
+ before do
14
+ stub_authentication!
15
+ end
16
+
17
+ shared_examples_for 'a return authorization creator' do
18
+ it "can create a new return authorization" do
19
+ stock_location = FactoryGirl.create(:stock_location)
20
+ reason = FactoryGirl.create(:return_authorization_reason)
21
+ rma_params = { :stock_location_id => stock_location.id,
22
+ :return_authorization_reason_id => reason.id,
23
+ :memo => "Defective" }
24
+ api_post :create, :order_id => order.number, :return_authorization => rma_params
25
+ response.status.should == 201
26
+ json_response.should have_attributes(attributes)
27
+ json_response["state"].should_not be_blank
28
+ end
29
+ end
30
+
31
+ context "as the order owner" do
32
+ before do
33
+ allow_any_instance_of(Order).to receive_messages :user => current_api_user
34
+ end
35
+
36
+ it "cannot see any return authorizations" do
37
+ api_get :index
38
+ assert_unauthorized!
39
+ end
40
+
41
+ it "cannot see a single return authorization" do
42
+ api_get :show, :id => 1
43
+ assert_unauthorized!
44
+ end
45
+
46
+ it "cannot learn how to create a new return authorization" do
47
+ api_get :new
48
+ assert_unauthorized!
49
+ end
50
+
51
+ it_behaves_like "a return authorization creator"
52
+
53
+ it "cannot update a return authorization" do
54
+ api_put :update, id: 0
55
+ assert_not_found!
56
+ end
57
+
58
+ it "cannot delete a return authorization" do
59
+ api_delete :destroy, id: 0
60
+ assert_not_found!
61
+ end
62
+ end
63
+
64
+ context "as another non-admin user that's not the order's owner" do
65
+ before do
66
+ Order.any_instance.stub :user => create(:user)
67
+ end
68
+
69
+ it "cannot create a new return authorization" do
70
+ api_post :create
71
+ assert_unauthorized!
72
+ end
73
+ end
74
+
75
+ context "as an admin" do
76
+ sign_in_as_admin!
77
+
78
+ it "can show return authorization" do
79
+ FactoryGirl.create(:return_authorization, :order => order)
80
+ return_authorization = order.return_authorizations.first
81
+ api_get :show, :order_id => order.number, :id => return_authorization.id
82
+ expect(response.status).to eq(200)
83
+ expect(json_response).to have_attributes(attributes)
84
+ expect(json_response["state"]).not_to be_blank
85
+ end
86
+
87
+ it "can get a list of return authorizations" do
88
+ FactoryGirl.create(:return_authorization, :order => order)
89
+ FactoryGirl.create(:return_authorization, :order => order)
90
+ api_get :index, { :order_id => order.number }
91
+ expect(response.status).to eq(200)
92
+ return_authorizations = json_response["return_authorizations"]
93
+ expect(return_authorizations.first).to have_attributes(attributes)
94
+ expect(return_authorizations.first).not_to eq(return_authorizations.last)
95
+ end
96
+
97
+ it 'can control the page size through a parameter' do
98
+ FactoryGirl.create(:return_authorization, :order => order)
99
+ FactoryGirl.create(:return_authorization, :order => order)
100
+ api_get :index, :order_id => order.number, :per_page => 1
101
+ expect(json_response['count']).to eq(1)
102
+ expect(json_response['current_page']).to eq(1)
103
+ expect(json_response['pages']).to eq(2)
104
+ end
105
+
106
+ it 'can query the results through a paramter' do
107
+ FactoryGirl.create(:return_authorization, :order => order)
108
+ expected_result = create(:return_authorization, :memo => 'damaged')
109
+ order.return_authorizations << expected_result
110
+ api_get :index, :q => { :memo_cont => 'damaged' }
111
+ expect(json_response['count']).to eq(1)
112
+ expect(json_response['return_authorizations'].first['memo']).to eq expected_result.memo
113
+ end
114
+
115
+ it "can learn how to create a new return authorization" do
116
+ api_get :new
117
+ expect(json_response["attributes"]).to eq(["id", "number", "state", "order_id", "memo", "created_at", "updated_at"])
118
+ required_attributes = json_response["required_attributes"]
119
+ expect(required_attributes).to include("order")
120
+ end
121
+
122
+ it "can update a return authorization on the order" do
123
+ FactoryGirl.create(:return_authorization, :order => order)
124
+ return_authorization = order.return_authorizations.first
125
+ api_put :update, :id => return_authorization.id, :return_authorization => { :memo => "ABC" }
126
+ expect(response.status).to eq(200)
127
+ expect(json_response).to have_attributes(attributes)
128
+ end
129
+
130
+ it "can cancel a return authorization on the order" do
131
+ FactoryGirl.create(:new_return_authorization, :order => order)
132
+ return_authorization = order.return_authorizations.first
133
+ expect(return_authorization.state).to eq("authorized")
134
+ api_delete :cancel, :id => return_authorization.id
135
+ expect(response.status).to eq(200)
136
+ expect(return_authorization.reload.state).to eq("canceled")
137
+ end
138
+
139
+ it "can delete a return authorization on the order" do
140
+ FactoryGirl.create(:return_authorization, :order => order)
141
+ return_authorization = order.return_authorizations.first
142
+ api_delete :destroy, :id => return_authorization.id
143
+ expect(response.status).to eq(204)
144
+ expect { return_authorization.reload }.to raise_error(ActiveRecord::RecordNotFound)
145
+ end
146
+
147
+ it_behaves_like "a return authorization creator"
148
+ end
149
+
150
+ context "as just another user" do
151
+ it "cannot add a return authorization to the order" do
152
+ api_post :create, :return_autorization => { :order_id => order.number, :memo => "Defective" }
153
+ assert_unauthorized!
154
+ end
155
+
156
+ it "cannot update a return authorization on the order" do
157
+ FactoryGirl.create(:return_authorization, :order => order)
158
+ return_authorization = order.return_authorizations.first
159
+ api_put :update, :id => return_authorization.id, :return_authorization => { :memo => "ABC" }
160
+ assert_unauthorized!
161
+ expect(return_authorization.reload.memo).not_to eq("ABC")
162
+ end
163
+
164
+ it "cannot delete a return authorization on the order" do
165
+ FactoryGirl.create(:return_authorization, :order => order)
166
+ return_authorization = order.return_authorizations.first
167
+ api_delete :destroy, :id => return_authorization.id
168
+ assert_unauthorized!
169
+ expect { return_authorization.reload }.not_to raise_error
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,252 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Api::ShipmentsController, :type => :controller do
4
+ render_views
5
+ let!(:shipment) { create(:shipment, address: create(:address), inventory_units: [build(:inventory_unit, shipment: nil)]) }
6
+ let!(:attributes) { [:id, :tracking, :number, :cost, :shipped_at, :stock_location_name, :order_id, :shipping_rates, :shipping_methods] }
7
+
8
+ before do
9
+ stub_authentication!
10
+ end
11
+
12
+ let!(:resource_scoping) { { id: shipment.to_param, shipment: { order_id: shipment.order.to_param } } }
13
+
14
+ context "as a non-admin" do
15
+ it "cannot make a shipment ready" do
16
+ api_put :ready
17
+ assert_not_found!
18
+ end
19
+
20
+ it "cannot make a shipment shipped" do
21
+ api_put :ship
22
+ assert_not_found!
23
+ end
24
+ end
25
+
26
+ context "as an admin" do
27
+ let!(:order) { shipment.order }
28
+ let!(:stock_location) { create(:stock_location_with_items) }
29
+ let!(:variant) { create(:variant) }
30
+
31
+ sign_in_as_admin!
32
+
33
+ # Start writing this spec a bit differently than before....
34
+ describe 'POST #create' do
35
+ let(:params) do
36
+ {
37
+ variant_id: stock_location.stock_items.first.variant.to_param,
38
+ shipment: { order_id: order.number },
39
+ stock_location_id: stock_location.to_param
40
+ }
41
+ end
42
+
43
+ subject do
44
+ api_post :create, params
45
+ end
46
+
47
+ [:variant_id, :stock_location_id].each do |field|
48
+ context "when #{field} is missing" do
49
+ before do
50
+ params.delete(field)
51
+ end
52
+
53
+ it 'should return proper error' do
54
+ subject
55
+ expect(response.status).to eq(422)
56
+ expect(json_response['exception']).to eq("param is missing or the value is empty: #{field.to_s}")
57
+ end
58
+ end
59
+ end
60
+
61
+ it 'should create a new shipment' do
62
+ expect(subject).to be_ok
63
+ expect(json_response).to have_attributes(attributes)
64
+ end
65
+ end
66
+
67
+ it 'can update a shipment' do
68
+ params = {
69
+ shipment: {
70
+ stock_location_id: stock_location.to_param
71
+ }
72
+ }
73
+
74
+ api_put :update, params
75
+ expect(response.status).to eq(200)
76
+ expect(json_response['stock_location_name']).to eq(stock_location.name)
77
+ end
78
+
79
+ it "can make a shipment ready" do
80
+ allow_any_instance_of(Spree::Order).to receive_messages(:paid? => true, :complete? => true)
81
+ api_put :ready
82
+ expect(json_response).to have_attributes(attributes)
83
+ expect(json_response["state"]).to eq("ready")
84
+ expect(shipment.reload.state).to eq("ready")
85
+ end
86
+
87
+ it "cannot make a shipment ready if the order is unpaid" do
88
+ allow_any_instance_of(Spree::Order).to receive_messages(:paid? => false)
89
+ api_put :ready
90
+ expect(json_response["error"]).to eq("Cannot ready shipment.")
91
+ expect(response.status).to eq(422)
92
+ end
93
+
94
+ context 'for completed shipments' do
95
+ let(:order) { create :completed_order_with_totals }
96
+ let!(:resource_scoping) { { id: order.shipments.first.to_param, shipment: { order_id: order.to_param } } }
97
+
98
+ it 'adds a variant to a shipment' do
99
+ api_put :add, { variant_id: variant.to_param, quantity: 2 }
100
+ expect(response.status).to eq(200)
101
+ expect(json_response['manifest'].detect { |h| h['variant']['id'] == variant.id }["quantity"]).to eq(2)
102
+ end
103
+
104
+ it 'removes a variant from a shipment' do
105
+ order.contents.add(variant, 2)
106
+
107
+ api_put :remove, { variant_id: variant.to_param, quantity: 1 }
108
+ expect(response.status).to eq(200)
109
+ expect(json_response['manifest'].detect { |h| h['variant']['id'] == variant.id }["quantity"]).to eq(1)
110
+ end
111
+
112
+ it 'removes a destroyed variant from a shipment' do
113
+ order.contents.add(variant, 2)
114
+ variant.destroy
115
+
116
+ api_put :remove, { variant_id: variant.to_param, quantity: 1 }
117
+ expect(response.status).to eq(200)
118
+ expect(json_response['manifest'].detect { |h| h['variant']['id'] == variant.id }["quantity"]).to eq(1)
119
+ end
120
+ end
121
+
122
+ describe '#mine' do
123
+ subject do
124
+ api_get :mine, format: 'json', params: params
125
+ end
126
+
127
+ let(:params) { {} }
128
+
129
+ before { subject }
130
+
131
+ context "the current api user is authenticated and has orders" do
132
+ let(:current_api_user) { shipped_order.user }
133
+ let(:shipped_order) { create(:shipped_order) }
134
+
135
+ it 'succeeds' do
136
+ expect(response.status).to eq 200
137
+ end
138
+
139
+ describe 'json output' do
140
+ render_views
141
+
142
+ let(:rendered_shipment_ids) { json_response['shipments'].map { |s| s['id'] } }
143
+
144
+ it 'contains the shipments' do
145
+ expect(rendered_shipment_ids).to match_array current_api_user.orders.flat_map(&:shipments).map(&:id)
146
+ end
147
+ end
148
+
149
+ context 'with filtering' do
150
+ let(:params) { {q: {order_completed_at_not_null: 1}} }
151
+
152
+ let!(:incomplete_order) { create(:order, user: current_api_user) }
153
+
154
+ it 'filters' do
155
+ expect(assigns(:shipments).map(&:id)).to match_array current_api_user.orders.complete.flat_map(&:shipments).map(&:id)
156
+ end
157
+ end
158
+ end
159
+
160
+ context "the current api user does not exist" do
161
+ let(:current_api_user) { nil }
162
+
163
+ it "returns a 401" do
164
+ expect(response.status).to eq(401)
165
+ end
166
+ end
167
+ end
168
+
169
+ end
170
+
171
+ describe "#ship" do
172
+ let(:shipment) { create(:order_ready_to_ship).shipments.first }
173
+
174
+ let(:send_mailer) { nil }
175
+ subject { api_put :ship, id: shipment.to_param, send_mailer: send_mailer }
176
+
177
+ context "the user is allowed to ship the shipment" do
178
+ sign_in_as_admin!
179
+ it "ships the shipment" do
180
+ Timecop.freeze do
181
+ subject
182
+ shipment.reload
183
+ expect(shipment.state).to eq 'shipped'
184
+ expect(shipment.shipped_at.to_i).to eq Time.now.to_i
185
+ end
186
+ end
187
+
188
+ context "send_mailer not present" do
189
+ it "sends the shipped shipments mailer" do
190
+ with_test_mail { subject }
191
+ expect(ActionMailer::Base.deliveries.size).to eq 1
192
+ expect(ActionMailer::Base.deliveries.last.subject).to match /Shipment Notification/
193
+ end
194
+ end
195
+
196
+ context "send_mailer set to false" do
197
+ let(:send_mailer) { 'false' }
198
+ it "does not send the shipped shipments mailer" do
199
+ with_test_mail { subject }
200
+ expect(ActionMailer::Base.deliveries.size).to eq 0
201
+ end
202
+ end
203
+
204
+ context "send_mailer set to true" do
205
+ let(:send_mailer) { 'true' }
206
+ it "sends the shipped shipments mailer" do
207
+ with_test_mail { subject }
208
+ expect(ActionMailer::Base.deliveries.size).to eq 1
209
+ expect(ActionMailer::Base.deliveries.last.subject).to match /Shipment Notification/
210
+ end
211
+ end
212
+ end
213
+
214
+ context "the user is not allowed to ship the shipment" do
215
+ sign_in_as_admin!
216
+
217
+ before do
218
+ ability = Spree::Ability.new(current_api_user)
219
+ ability.cannot :ship, Spree::Shipment
220
+ allow(controller).to receive(:current_ability) { ability }
221
+ end
222
+
223
+ it "does nothing" do
224
+ expect {
225
+ expect {
226
+ subject
227
+ }.not_to change(shipment, :state)
228
+ }.not_to change(shipment, :shipped_at)
229
+ end
230
+
231
+ it "responds with a 401" do
232
+ subject
233
+ expect(response.status).to eq 401
234
+ end
235
+ end
236
+
237
+ context "the user is not allowed to view the shipment" do
238
+ it "does nothing" do
239
+ expect {
240
+ expect {
241
+ subject
242
+ }.not_to change(shipment, :state)
243
+ }.not_to change(shipment, :shipped_at)
244
+ end
245
+
246
+ it "responds with a 404" do
247
+ subject
248
+ expect(response).to be_not_found
249
+ end
250
+ end
251
+ end
252
+ end
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Api::StatesController, :type => :controller do
5
+ render_views
6
+
7
+ let!(:state) { create(:state, :name => "Victoria") }
8
+ let(:attributes) { [:id, :name, :abbr, :country_id] }
9
+
10
+ before do
11
+ stub_authentication!
12
+ end
13
+
14
+ it "gets all states" do
15
+ api_get :index
16
+ expect(json_response["states"].first).to have_attributes(attributes)
17
+ expect(json_response['states'].first['name']).to eq(state.name)
18
+ end
19
+
20
+ it "gets all the states for a particular country" do
21
+ api_get :index, :country_id => state.country.id
22
+ expect(json_response["states"].first).to have_attributes(attributes)
23
+ expect(json_response['states'].first['name']).to eq(state.name)
24
+ end
25
+
26
+ context "pagination" do
27
+ before do
28
+ expect(State).to receive(:accessible_by).and_return(@scope = double)
29
+ allow(@scope).to receive_message_chain(:ransack, :result, :includes, :order).and_return(@scope)
30
+ end
31
+
32
+ it "does not paginate states results when asked not to do so" do
33
+ expect(@scope).not_to receive(:page)
34
+ expect(@scope).not_to receive(:per)
35
+ api_get :index
36
+ end
37
+
38
+ it "paginates when page parameter is passed through" do
39
+ expect(@scope).to receive(:page).with(1).and_return(@scope)
40
+ expect(@scope).to receive(:per).with(nil)
41
+ api_get :index, :page => 1
42
+ end
43
+
44
+ it "paginates when per_page parameter is passed through" do
45
+ expect(@scope).to receive(:page).with(nil).and_return(@scope)
46
+ expect(@scope).to receive(:per).with(25)
47
+ api_get :index, :per_page => 25
48
+ end
49
+ end
50
+
51
+
52
+ context "with two states" do
53
+ before { create(:state, :name => "New South Wales") }
54
+
55
+ it "gets all states for a country" do
56
+ country = create(:country, :states_required => true)
57
+ state.country = country
58
+ state.save
59
+
60
+ api_get :index, :country_id => country.id
61
+ expect(json_response["states"].first).to have_attributes(attributes)
62
+ expect(json_response["states"].count).to eq(1)
63
+ json_response["states_required"] = true
64
+ end
65
+
66
+ it "can view all states" do
67
+ api_get :index
68
+ expect(json_response["states"].first).to have_attributes(attributes)
69
+ end
70
+
71
+ it 'can query the results through a paramter' do
72
+ api_get :index, :q => { :name_cont => 'Vic' }
73
+ expect(json_response['states'].first['name']).to eq("Victoria")
74
+ end
75
+ end
76
+
77
+ it "can view a state" do
78
+ api_get :show, :id => state.id
79
+ expect(json_response).to have_attributes(attributes)
80
+ end
81
+ end
82
+ end