spree_api 3.2.9 → 3.3.0.rc1

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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/spree/api/base_controller.rb +11 -12
  3. data/app/controllers/spree/api/v1/checkouts_controller.rb +5 -8
  4. data/app/controllers/spree/api/v1/customer_returns_controller.rb +24 -0
  5. data/app/controllers/spree/api/v1/orders_controller.rb +13 -24
  6. data/app/controllers/spree/api/v1/payments_controller.rb +2 -3
  7. data/app/controllers/spree/api/v1/reimbursements_controller.rb +24 -0
  8. data/app/controllers/spree/api/v1/shipments_controller.rb +4 -4
  9. data/app/controllers/spree/api/v1/zones_controller.rb +8 -3
  10. data/app/helpers/spree/api/api_helpers.rb +13 -1
  11. data/app/models/concerns/spree/user_api_authentication.rb +19 -0
  12. data/app/models/concerns/spree/user_api_methods.rb +7 -0
  13. data/app/views/spree/api/v1/customer_returns/index.v1.rabl +7 -0
  14. data/app/views/spree/api/v1/line_items/show.v1.rabl +0 -1
  15. data/app/views/spree/api/v1/reimbursements/index.v1.rabl +7 -0
  16. data/config/initializers/user_class_extensions.rb +7 -0
  17. data/config/routes.rb +3 -0
  18. data/spec/controllers/spree/api/base_controller_spec.rb +84 -0
  19. data/spec/controllers/spree/api/v1/addresses_controller_spec.rb +56 -0
  20. data/spec/controllers/spree/api/v1/checkouts_controller_spec.rb +361 -0
  21. data/spec/controllers/spree/api/v1/classifications_controller_spec.rb +48 -0
  22. data/spec/controllers/spree/api/v1/countries_controller_spec.rb +48 -0
  23. data/spec/controllers/spree/api/v1/credit_cards_controller_spec.rb +80 -0
  24. data/spec/controllers/spree/api/v1/customer_returns_controller_spec.rb +27 -0
  25. data/spec/controllers/spree/api/v1/images_controller_spec.rb +114 -0
  26. data/spec/controllers/spree/api/v1/inventory_units_controller_spec.rb +48 -0
  27. data/spec/controllers/spree/api/v1/line_items_controller_spec.rb +210 -0
  28. data/spec/controllers/spree/api/v1/option_types_controller_spec.rb +122 -0
  29. data/spec/controllers/spree/api/v1/option_values_controller_spec.rb +141 -0
  30. data/spec/controllers/spree/api/v1/orders_controller_spec.rb +735 -0
  31. data/spec/controllers/spree/api/v1/payments_controller_spec.rb +234 -0
  32. data/spec/controllers/spree/api/v1/product_properties_controller_spec.rb +156 -0
  33. data/spec/controllers/spree/api/v1/products_controller_spec.rb +409 -0
  34. data/spec/controllers/spree/api/v1/promotion_application_spec.rb +50 -0
  35. data/spec/controllers/spree/api/v1/promotions_controller_spec.rb +64 -0
  36. data/spec/controllers/spree/api/v1/properties_controller_spec.rb +102 -0
  37. data/spec/controllers/spree/api/v1/reimbursements_controller_spec.rb +24 -0
  38. data/spec/controllers/spree/api/v1/return_authorizations_controller_spec.rb +161 -0
  39. data/spec/controllers/spree/api/v1/shipments_controller_spec.rb +187 -0
  40. data/spec/controllers/spree/api/v1/states_controller_spec.rb +86 -0
  41. data/spec/controllers/spree/api/v1/stock_items_controller_spec.rb +151 -0
  42. data/spec/controllers/spree/api/v1/stock_locations_controller_spec.rb +113 -0
  43. data/spec/controllers/spree/api/v1/stock_movements_controller_spec.rb +84 -0
  44. data/spec/controllers/spree/api/v1/stores_controller_spec.rb +133 -0
  45. data/spec/controllers/spree/api/v1/tags_controller_spec.rb +102 -0
  46. data/spec/controllers/spree/api/v1/taxonomies_controller_spec.rb +114 -0
  47. data/spec/controllers/spree/api/v1/taxons_controller_spec.rb +177 -0
  48. data/spec/controllers/spree/api/v1/unauthenticated_products_controller_spec.rb +26 -0
  49. data/spec/controllers/spree/api/v1/users_controller_spec.rb +153 -0
  50. data/spec/controllers/spree/api/v1/variants_controller_spec.rb +205 -0
  51. data/spec/controllers/spree/api/v1/zones_controller_spec.rb +91 -0
  52. data/spec/models/spree/legacy_user_spec.rb +19 -0
  53. data/spec/requests/rabl_cache_spec.rb +32 -0
  54. data/spec/requests/ransackable_attributes_spec.rb +79 -0
  55. data/spec/requests/version_spec.rb +19 -0
  56. data/spec/shared_examples/protect_product_actions.rb +17 -0
  57. data/spec/spec_helper.rb +63 -0
  58. data/spec/support/controller_hacks.rb +40 -0
  59. data/spec/support/database_cleaner.rb +14 -0
  60. data/spec/support/have_attributes_matcher.rb +13 -0
  61. data/spree_api.gemspec +4 -3
  62. metadata +105 -13
  63. data/app/views/spree/api/v1/config/money.v1.rabl +0 -2
  64. data/app/views/spree/api/v1/config/show.v1.rabl +0 -2
@@ -0,0 +1,409 @@
1
+ require 'spec_helper'
2
+ require 'shared_examples/protect_product_actions'
3
+
4
+ module Spree
5
+ describe Api::V1::ProductsController, type: :controller do
6
+ render_views
7
+
8
+ let!(:product) { create(:product) }
9
+ let!(:inactive_product) { create(:product, available_on: Time.current.tomorrow, name: "inactive") }
10
+ let(:base_attributes) { Api::ApiHelpers.product_attributes }
11
+ let(:show_attributes) { base_attributes.dup.push(:has_variants) }
12
+ let(:new_attributes) { base_attributes }
13
+
14
+ let(:product_data) do
15
+ { name: "The Other Product",
16
+ price: 19.99,
17
+ shipping_category_id: create(:shipping_category).id }
18
+ end
19
+ let(:attributes_for_variant) do
20
+ h = attributes_for(:variant).except(:option_values, :product)
21
+ h.merge({
22
+ options: [
23
+ { name: "size", value: "small" },
24
+ { name: "color", value: "black" }
25
+ ]
26
+ })
27
+ end
28
+
29
+ before do
30
+ stub_authentication!
31
+ end
32
+
33
+ context "as a normal user" do
34
+ context "with caching enabled" do
35
+ let!(:product_2) { create(:product) }
36
+
37
+ before do
38
+ ActionController::Base.perform_caching = true
39
+ end
40
+
41
+ it "returns unique products" do
42
+ api_get :index
43
+ product_ids = json_response["products"].map { |p| p["id"] }
44
+ expect(product_ids.uniq.count).to eq(product_ids.count)
45
+ end
46
+
47
+ after do
48
+ ActionController::Base.perform_caching = false
49
+ end
50
+ end
51
+
52
+ it "retrieves a list of products" do
53
+ api_get :index
54
+ expect(json_response["products"].first).to have_attributes(show_attributes)
55
+ expect(json_response["total_count"]).to eq(1)
56
+ expect(json_response["current_page"]).to eq(1)
57
+ expect(json_response["pages"]).to eq(1)
58
+ expect(json_response["per_page"]).to eq(Kaminari.config.default_per_page)
59
+ end
60
+
61
+ it "retrieves a list of products by id" do
62
+ api_get :index, ids: [product.id]
63
+ expect(json_response["products"].first).to have_attributes(show_attributes)
64
+ expect(json_response["total_count"]).to eq(1)
65
+ expect(json_response["current_page"]).to eq(1)
66
+ expect(json_response["pages"]).to eq(1)
67
+ expect(json_response["per_page"]).to eq(Kaminari.config.default_per_page)
68
+ end
69
+
70
+ context "product has more than one price" do
71
+ before { product.master.prices.create currency: "EUR", amount: 22 }
72
+
73
+ it "returns distinct products only" do
74
+ api_get :index
75
+ expect(assigns(:products).map(&:id).uniq).to eq assigns(:products).map(&:id)
76
+ end
77
+ end
78
+
79
+ it "retrieves a list of products by ids string" do
80
+ second_product = create(:product)
81
+ api_get :index, ids: [product.id, second_product.id].join(",")
82
+ expect(json_response["products"].first).to have_attributes(show_attributes)
83
+ expect(json_response["products"][1]).to have_attributes(show_attributes)
84
+ expect(json_response["total_count"]).to eq(2)
85
+ expect(json_response["current_page"]).to eq(1)
86
+ expect(json_response["pages"]).to eq(1)
87
+ expect(json_response["per_page"]).to eq(Kaminari.config.default_per_page)
88
+ end
89
+
90
+ it "does not return inactive products when queried by ids" do
91
+ api_get :index, ids: [inactive_product.id]
92
+ expect(json_response["count"]).to eq(0)
93
+ end
94
+
95
+ it "does not list unavailable products" do
96
+ api_get :index
97
+ expect(json_response["products"].first["name"]).not_to eq("inactive")
98
+ end
99
+
100
+ context "pagination" do
101
+ it "can select the next page of products" do
102
+ second_product = create(:product)
103
+ api_get :index, page: 2, per_page: 1
104
+ expect(json_response["products"].first).to have_attributes(show_attributes)
105
+ expect(json_response["total_count"]).to eq(2)
106
+ expect(json_response["current_page"]).to eq(2)
107
+ expect(json_response["pages"]).to eq(2)
108
+ end
109
+
110
+ it 'can control the page size through a parameter' do
111
+ create(:product)
112
+ api_get :index, per_page: 1
113
+ expect(json_response['count']).to eq(1)
114
+ expect(json_response['total_count']).to eq(2)
115
+ expect(json_response['current_page']).to eq(1)
116
+ expect(json_response['pages']).to eq(2)
117
+ end
118
+ end
119
+
120
+ it "can search for products" do
121
+ create(:product, name: "The best product in the world")
122
+ api_get :index, q: { name_cont: "best" }
123
+ expect(json_response["products"].first).to have_attributes(show_attributes)
124
+ expect(json_response["count"]).to eq(1)
125
+ end
126
+
127
+ it "gets a single product" do
128
+ product.master.images.create!(attachment: image("thinking-cat.jpg"))
129
+ create(:variant, product: product)
130
+ product.variants.first.images.create!(attachment: image("thinking-cat.jpg"))
131
+ product.set_property("spree", "rocks")
132
+ product.taxons << create(:taxon)
133
+
134
+ api_get :show, id: product.to_param
135
+
136
+ expect(json_response).to have_attributes(show_attributes)
137
+ expect(json_response['variants'].first).to have_attributes([:name,
138
+ :is_master,
139
+ :price,
140
+ :images,
141
+ :in_stock])
142
+
143
+ expect(json_response['variants'].first['images'].first).to have_attributes([:attachment_file_name,
144
+ :attachment_width,
145
+ :attachment_height,
146
+ :attachment_content_type,
147
+ :mini_url,
148
+ :small_url,
149
+ :product_url,
150
+ :large_url])
151
+
152
+ expect(json_response["product_properties"].first).to have_attributes([:value,
153
+ :product_id,
154
+ :property_name])
155
+
156
+ expect(json_response["classifications"].first).to have_attributes([:taxon_id, :position, :taxon])
157
+ expect(json_response["classifications"].first['taxon']).to have_attributes([:id, :name, :pretty_name, :permalink, :taxonomy_id, :parent_id])
158
+ end
159
+
160
+ context "tracking is disabled" do
161
+ before { Config.track_inventory_levels = false }
162
+
163
+ it "still displays valid json with total_on_hand Float::INFINITY" do
164
+ api_get :show, id: product.to_param
165
+ expect(response).to be_ok
166
+ expect(json_response[:total_on_hand]).to eq nil
167
+ end
168
+
169
+ after { Config.track_inventory_levels = true }
170
+ end
171
+
172
+ context "finds a product by slug first then by id" do
173
+ let!(:other_product) { create(:product, slug: "these-are-not-the-droids-you-are-looking-for") }
174
+
175
+ before do
176
+ product.update_column(:slug, "#{other_product.id}-and-1-ways")
177
+ end
178
+
179
+ specify do
180
+ api_get :show, id: product.to_param
181
+ expect(json_response["slug"]).to match(/and-1-ways/)
182
+ product.destroy
183
+
184
+ api_get :show, id: other_product.id
185
+ expect(json_response["slug"]).to match(/droids/)
186
+ end
187
+ end
188
+
189
+ it "cannot see inactive products" do
190
+ api_get :show, id: inactive_product.to_param
191
+ assert_not_found!
192
+ end
193
+
194
+ it "returns a 404 error when it cannot find a product" do
195
+ api_get :show, id: "non-existant"
196
+ assert_not_found!
197
+ end
198
+
199
+ it "can learn how to create a new product" do
200
+ api_get :new
201
+ expect(json_response["attributes"]).to eq(new_attributes.map(&:to_s))
202
+ required_attributes = json_response["required_attributes"]
203
+ expect(required_attributes).to include("name")
204
+ expect(required_attributes).to include("price")
205
+ expect(required_attributes).to include("shipping_category")
206
+ end
207
+
208
+ it_behaves_like "modifying product actions are restricted"
209
+ end
210
+
211
+ context "as an admin" do
212
+ let(:taxon_1) { create(:taxon) }
213
+ let(:taxon_2) { create(:taxon) }
214
+
215
+ sign_in_as_admin!
216
+
217
+ it "can see all products" do
218
+ api_get :index
219
+ expect(json_response["products"].count).to eq(2)
220
+ expect(json_response["count"]).to eq(2)
221
+ expect(json_response["current_page"]).to eq(1)
222
+ expect(json_response["pages"]).to eq(1)
223
+ end
224
+
225
+ # Regression test for #1626
226
+ context "deleted products" do
227
+ before do
228
+ create(:product, deleted_at: 1.day.ago)
229
+ end
230
+
231
+ it "does not include deleted products" do
232
+ api_get :index
233
+ expect(json_response["products"].count).to eq(2)
234
+ end
235
+
236
+ it "can include deleted products" do
237
+ api_get :index, show_deleted: 1
238
+ expect(json_response["products"].count).to eq(3)
239
+ end
240
+ end
241
+
242
+ describe "creating a product" do
243
+ it "can create a new product" do
244
+ api_post :create, product: { name: "The Other Product",
245
+ price: 19.99,
246
+ shipping_category_id: create(:shipping_category).id }
247
+ expect(json_response).to have_attributes(base_attributes)
248
+ expect(response.status).to eq(201)
249
+ end
250
+
251
+ it "creates with embedded variants" do
252
+ product_data.merge!({
253
+ variants: [attributes_for_variant, attributes_for_variant]
254
+ })
255
+
256
+ api_post :create, product: product_data
257
+ expect(response.status).to eq 201
258
+
259
+ variants = json_response['variants']
260
+ expect(variants.count).to eq(2)
261
+ expect(variants.last['option_values'][0]['name']).to eq('small')
262
+ expect(variants.last['option_values'][0]['option_type_name']).to eq('size')
263
+
264
+ expect(json_response['option_types'].count).to eq(2) # size, color
265
+ end
266
+
267
+ it "can create a new product with embedded product_properties" do
268
+ product_data.merge!({
269
+ product_properties_attributes: [{
270
+ property_name: "fabric",
271
+ value: "cotton"
272
+ }]
273
+ })
274
+
275
+ api_post :create, product: product_data
276
+
277
+ expect(json_response['product_properties'][0]['property_name']).to eq('fabric')
278
+ expect(json_response['product_properties'][0]['value']).to eq('cotton')
279
+ end
280
+
281
+ it "can create a new product with option_types" do
282
+ product_data.merge!({
283
+ option_types: ['size', 'color']
284
+ })
285
+
286
+ api_post :create, product: product_data
287
+ expect(json_response['option_types'].count).to eq(2)
288
+ end
289
+
290
+ it "creates product with option_types ids" do
291
+ option_type = create(:option_type)
292
+ product_data.merge!(option_type_ids: [option_type.id])
293
+ api_post :create, product: product_data
294
+ expect(json_response['option_types'].first['id']).to eq option_type.id
295
+ end
296
+
297
+ it "creates with shipping categories" do
298
+ hash = { name: "The Other Product",
299
+ price: 19.99,
300
+ shipping_category: "Free Ships" }
301
+
302
+ api_post :create, product: hash
303
+ expect(response.status).to eq 201
304
+
305
+ shipping_id = ShippingCategory.find_by_name("Free Ships").id
306
+ expect(json_response['shipping_category_id']).to eq shipping_id
307
+ end
308
+
309
+ it "puts the created product in the given taxons" do
310
+ product_data[:taxon_ids] = [taxon_1.id, taxon_2.id]
311
+ api_post :create, product: product_data
312
+ expect(json_response["taxon_ids"]).to eq([taxon_1.id, taxon_2.id])
313
+ end
314
+
315
+ # Regression test for #2140
316
+ context "with authentication_required set to false" do
317
+ before do
318
+ Spree::Api::Config.requires_authentication = false
319
+ end
320
+
321
+ after do
322
+ Spree::Api::Config.requires_authentication = true
323
+ end
324
+
325
+ it "can still create a product" do
326
+ api_post :create, product: product_data, token: "fake"
327
+ expect(json_response).to have_attributes(show_attributes)
328
+ expect(response.status).to eq(201)
329
+ end
330
+ end
331
+
332
+ it "cannot create a new product with invalid attributes" do
333
+ api_post :create, product: { foo: :bar }
334
+ expect(response.status).to eq(422)
335
+ expect(json_response["error"]).to eq("Invalid resource. Please fix errors and try again.")
336
+ errors = json_response["errors"]
337
+ errors.delete("slug") # Don't care about this one.
338
+ expect(errors.keys).to match_array(["name", "price", "shipping_category"])
339
+ end
340
+ end
341
+
342
+ context 'updating a product' do
343
+ it "can update a product" do
344
+ api_put :update, id: product.to_param, product: { name: "New and Improved Product!" }
345
+ expect(response.status).to eq(200)
346
+ end
347
+
348
+ it "can create new option types on a product" do
349
+ api_put :update, id: product.to_param, product: { option_types: ['shape', 'color'] }
350
+ expect(json_response['option_types'].count).to eq(2)
351
+ end
352
+
353
+ it "can create new variants on a product" do
354
+ api_put :update, id: product.to_param, product: { variants: [attributes_for_variant, attributes_for_variant.merge(sku: "ABC-#{Kernel.rand(9999)}")] }
355
+ expect(response.status).to eq 200
356
+ expect(json_response['variants'].count).to eq(2) # 2 variants
357
+
358
+ variants = json_response['variants'].select { |v| !v['is_master'] }
359
+ expect(variants.last['option_values'][0]['name']).to eq('small')
360
+ expect(variants.last['option_values'][0]['option_type_name']).to eq('size')
361
+
362
+ expect(json_response['option_types'].count).to eq(2) # size, color
363
+ end
364
+
365
+ it "can update an existing variant on a product" do
366
+ variant_hash = {
367
+ sku: '123', price: 19.99, options: [{name: "size", value: "small"}]
368
+ }
369
+ variant_id = product.variants.create!({ product: product }.merge(variant_hash)).id
370
+
371
+ api_put :update, id: product.to_param, product: {
372
+ variants: [
373
+ variant_hash.merge(
374
+ id: variant_id.to_s,
375
+ sku: '456',
376
+ options: [{name: "size", value: "large" }]
377
+ )
378
+ ]
379
+ }
380
+
381
+ expect(json_response['variants'].count).to eq(1)
382
+ variants = json_response['variants'].select { |v| !v['is_master'] }
383
+ expect(variants.last['option_values'][0]['name']).to eq('large')
384
+ expect(variants.last['sku']).to eq('456')
385
+ expect(variants.count).to eq(1)
386
+ end
387
+
388
+ it "cannot update a product with an invalid attribute" do
389
+ api_put :update, id: product.to_param, product: { name: "" }
390
+ expect(response.status).to eq(422)
391
+ expect(json_response["error"]).to eq("Invalid resource. Please fix errors and try again.")
392
+ expect(json_response["errors"]["name"]).to eq(["can't be blank"])
393
+ end
394
+
395
+ it "puts the updated product in the given taxons" do
396
+ api_put :update, id: product.to_param, product: { taxon_ids: [taxon_1.id, taxon_2.id] }
397
+ expect(json_response["taxon_ids"].to_set).to eql([taxon_1.id, taxon_2.id].to_set)
398
+ end
399
+ end
400
+
401
+ it "can delete a product" do
402
+ expect(product.deleted_at).to be_nil
403
+ api_delete :destroy, id: product.to_param
404
+ expect(response.status).to eq(204)
405
+ expect(product.reload.deleted_at).not_to be_nil
406
+ end
407
+ end
408
+ end
409
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Api::V1::OrdersController, type: :controller do
5
+ render_views
6
+
7
+ before do
8
+ stub_authentication!
9
+ end
10
+
11
+ context "with an available promotion" do
12
+ let!(:order) { create(:order_with_line_items, line_items_count: 1) }
13
+ let!(:promotion) do
14
+ promotion = Spree::Promotion.create(name: "10% off", code: "10off")
15
+ calculator = Spree::Calculator::FlatPercentItemTotal.create(preferred_flat_percent: "10")
16
+ action = Spree::Promotion::Actions::CreateItemAdjustments.create(calculator: calculator)
17
+ promotion.actions << action
18
+ promotion
19
+ end
20
+
21
+ it "can apply a coupon code to the order" do
22
+ expect(order.total).to eq(110.00)
23
+ api_put :apply_coupon_code, id: order.to_param, coupon_code: "10off", order_token: order.guest_token
24
+ expect(response.status).to eq(200)
25
+ expect(order.reload.total).to eq(109.00)
26
+ expect(json_response["success"]).to eq("The coupon code was successfully applied to your order.")
27
+ expect(json_response["error"]).to be_blank
28
+ expect(json_response["successful"]).to be true
29
+ expect(json_response["status_code"]).to eq("coupon_code_applied")
30
+ end
31
+
32
+ context "with an expired promotion" do
33
+ before do
34
+ promotion.starts_at = 2.weeks.ago
35
+ promotion.expires_at = 1.week.ago
36
+ promotion.save
37
+ end
38
+
39
+ it "fails to apply" do
40
+ api_put :apply_coupon_code, id: order.to_param, coupon_code: "10off", order_token: order.guest_token
41
+ expect(response.status).to eq(422)
42
+ expect(json_response["success"]).to be_blank
43
+ expect(json_response["error"]).to eq("The coupon code is expired")
44
+ expect(json_response["successful"]).to be false
45
+ expect(json_response["status_code"]).to eq("coupon_code_expired")
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Api::V1::PromotionsController, type: :controller do
5
+ render_views
6
+
7
+ shared_examples "a JSON response" do
8
+ it 'should be ok' do
9
+ expect(subject).to be_ok
10
+ end
11
+
12
+ it 'should return JSON' do
13
+ payload = HashWithIndifferentAccess.new(JSON.parse(subject.body))
14
+ expect(payload).to_not be_nil
15
+ Spree::Api::ApiHelpers.promotion_attributes.each do |attribute|
16
+ expect(payload.has_key?(attribute)).to be true
17
+ end
18
+ end
19
+ end
20
+
21
+ before do
22
+ stub_authentication!
23
+ end
24
+
25
+ let(:promotion) { create :promotion, :with_order_adjustment, code: '10off' }
26
+
27
+ describe 'GET #show' do
28
+ subject { api_get :show, id: id }
29
+
30
+ context 'when admin' do
31
+ sign_in_as_admin!
32
+
33
+ context 'when finding by id' do
34
+ let(:id) { promotion.id }
35
+
36
+ it_behaves_like "a JSON response"
37
+ end
38
+
39
+ context 'when finding by code' do
40
+ let(:id) { promotion.code }
41
+
42
+ it_behaves_like "a JSON response"
43
+ end
44
+
45
+ context 'when id does not exist' do
46
+ let(:id) { 'argh' }
47
+
48
+ it 'should be 404' do
49
+ expect(subject.status).to eq(404)
50
+ end
51
+ end
52
+ end
53
+
54
+ context 'when non admin' do
55
+ let(:id) { promotion.id }
56
+
57
+ it 'should be unauthorized' do
58
+ subject
59
+ assert_unauthorized!
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+ module Spree
3
+ describe Api::V1::PropertiesController, type: :controller do
4
+ render_views
5
+
6
+ let!(:property_1) { Property.create!(name: "foo", presentation: "Foo") }
7
+ let!(:property_2) { Property.create!(name: "bar", presentation: "Bar") }
8
+
9
+ let(:attributes) { [:id, :name, :presentation] }
10
+
11
+ before do
12
+ stub_authentication!
13
+ end
14
+
15
+ it "can see a list of all properties" do
16
+ api_get :index
17
+ expect(json_response["properties"].count).to eq(2)
18
+ expect(json_response["properties"].first).to have_attributes(attributes)
19
+ end
20
+
21
+ it "can control the page size through a parameter" do
22
+ api_get :index, per_page: 1
23
+ expect(json_response['properties'].count).to eq(1)
24
+ expect(json_response['current_page']).to eq(1)
25
+ expect(json_response['pages']).to eq(2)
26
+ end
27
+
28
+ it 'can query the results through a parameter' do
29
+ api_get :index, q: { name_cont: 'ba' }
30
+ expect(json_response['count']).to eq(1)
31
+ expect(json_response['properties'].first['presentation']).to eq property_2.presentation
32
+ end
33
+
34
+ it "retrieves a list of properties by id" do
35
+ api_get :index, ids: [property_1.id]
36
+ expect(json_response["properties"].first).to have_attributes(attributes)
37
+ expect(json_response["count"]).to eq(1)
38
+ end
39
+
40
+ it "retrieves a list of properties by ids string" do
41
+ api_get :index, ids: [property_1.id, property_2.id].join(",")
42
+ expect(json_response["properties"].first).to have_attributes(attributes)
43
+ expect(json_response["properties"][1]).to have_attributes(attributes)
44
+ expect(json_response["count"]).to eq(2)
45
+ end
46
+
47
+ it "can see a single property" do
48
+ api_get :show, id: property_1.id
49
+ expect(json_response).to have_attributes(attributes)
50
+ end
51
+
52
+ it "can see a property by name" do
53
+ api_get :show, id: property_1.name
54
+ expect(json_response).to have_attributes(attributes)
55
+ end
56
+
57
+ it "can learn how to create a new property" do
58
+ api_get :new
59
+ expect(json_response["attributes"]).to eq(attributes.map(&:to_s))
60
+ expect(json_response["required_attributes"]).to be_empty
61
+ end
62
+
63
+ it "cannot create a new property if not an admin" do
64
+ api_post :create, property: { name: "My Property 3" }
65
+ assert_unauthorized!
66
+ end
67
+
68
+ it "cannot update a property" do
69
+ api_put :update, id: property_1.name, property: { presentation: "my value 456" }
70
+ assert_unauthorized!
71
+ end
72
+
73
+ it "cannot delete a property" do
74
+ api_delete :destroy, id: property_1.id
75
+ assert_unauthorized!
76
+ expect { property_1.reload }.not_to raise_error
77
+ end
78
+
79
+ context "as an admin" do
80
+ sign_in_as_admin!
81
+
82
+ it "can create a new property" do
83
+ expect(Spree::Property.count).to eq(2)
84
+ api_post :create, property: { name: "My Property 3", presentation: "my value 3" }
85
+ expect(json_response).to have_attributes(attributes)
86
+ expect(response.status).to eq(201)
87
+ expect(Spree::Property.count).to eq(3)
88
+ end
89
+
90
+ it "can update a property" do
91
+ api_put :update, id: property_1.name, property: { presentation: "my value 456" }
92
+ expect(response.status).to eq(200)
93
+ end
94
+
95
+ it "can delete a property" do
96
+ api_delete :destroy, id: property_1.name
97
+ expect(response.status).to eq(204)
98
+ expect { property_1.reload }.to raise_error(ActiveRecord::RecordNotFound)
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Api::V1::ReimbursementsController, type: :controller do
5
+ render_views
6
+
7
+ before do
8
+ stub_authentication!
9
+ end
10
+
11
+ describe '#index' do
12
+ let!(:reimbursement) { create(:reimbursement) }
13
+
14
+ before do
15
+ api_get :index
16
+ end
17
+
18
+ it 'loads reimbursements' do
19
+ expect(response.status).to eq(200)
20
+ expect(json_response['count']).to eq(1)
21
+ end
22
+ end
23
+ end
24
+ end