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,80 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Api::CreditCardsController, :type => :controller do
5
+ render_views
6
+
7
+ let!(:admin_user) do
8
+ user = Spree.user_class.new(:email => "spree@example.com", :id => 1)
9
+ user.generate_spree_api_key!
10
+ allow(user).to receive(:has_spree_role?).with('admin').and_return(true)
11
+ user
12
+ end
13
+
14
+ let!(:normal_user) do
15
+ user = Spree.user_class.new(:email => "spree2@example.com", :id => 2)
16
+ user.generate_spree_api_key!
17
+ user
18
+ end
19
+
20
+ let!(:card) { create(:credit_card, :user_id => admin_user.id, gateway_customer_profile_id: "random") }
21
+
22
+ before do
23
+ stub_authentication!
24
+ end
25
+
26
+ it "the user id doesn't exist" do
27
+ api_get :index, user_id: 1000
28
+ expect(response.status).to eq(404)
29
+ end
30
+
31
+ context "calling user is in admin role" do
32
+ let(:current_api_user) do
33
+ user = admin_user
34
+ user
35
+ end
36
+
37
+ it "no credit cards exist for user" do
38
+ api_get :index, user_id: normal_user.id
39
+
40
+ expect(response.status).to eq(200)
41
+ expect(json_response["pages"]).to eq(0)
42
+ end
43
+
44
+ it "can view all credit cards for user" do
45
+ api_get :index, user_id: current_api_user.id
46
+
47
+ expect(response.status).to eq(200)
48
+ expect(json_response["pages"]).to eq(1)
49
+ expect(json_response["current_page"]).to eq(1)
50
+ expect(json_response["credit_cards"].length).to eq(1)
51
+ expect(json_response["credit_cards"].first["id"]).to eq(card.id)
52
+ end
53
+ end
54
+
55
+ context "calling user is not in admin role" do
56
+ let(:current_api_user) do
57
+ user = normal_user
58
+ user
59
+ end
60
+
61
+ let!(:card) { create(:credit_card, :user_id => normal_user.id, gateway_customer_profile_id: "random") }
62
+
63
+ it "can not view user" do
64
+ api_get :index, user_id: admin_user.id
65
+
66
+ expect(response.status).to eq(404)
67
+ end
68
+
69
+ it "can view own credit cards" do
70
+ api_get :index, user_id: normal_user.id
71
+
72
+ expect(response.status).to eq(200)
73
+ expect(json_response["pages"]).to eq(1)
74
+ expect(json_response["current_page"]).to eq(1)
75
+ expect(json_response["credit_cards"].length).to eq(1)
76
+ expect(json_response["credit_cards"].first["id"]).to eq(card.id)
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,93 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Spree::Api::ImagesController, :type => :controller do
5
+ render_views
6
+
7
+ let!(:product) { create(:product) }
8
+ let!(:attributes) { [:id, :position, :attachment_content_type,
9
+ :attachment_file_name, :type, :attachment_updated_at, :attachment_width,
10
+ :attachment_height, :alt] }
11
+
12
+ before do
13
+ stub_authentication!
14
+ end
15
+
16
+ context "as an admin" do
17
+ sign_in_as_admin!
18
+
19
+ it "can upload a new image for a variant" do
20
+ expect do
21
+ api_post :create,
22
+ :image => { :attachment => upload_image('thinking-cat.jpg'),
23
+ :viewable_type => 'Spree::Variant',
24
+ :viewable_id => product.master.to_param },
25
+ :product_id => product.id
26
+ expect(response.status).to eq(201)
27
+ expect(json_response).to have_attributes(attributes)
28
+ end.to change(Image, :count).by(1)
29
+ end
30
+
31
+ context "working with an existing image" do
32
+ let!(:product_image) { product.master.images.create!(:attachment => image('thinking-cat.jpg')) }
33
+
34
+ it "can get a single product image" do
35
+ api_get :show, :id => product_image.id, :product_id => product.id
36
+ expect(response.status).to eq(200)
37
+ expect(json_response).to have_attributes(attributes)
38
+ end
39
+
40
+ it "can get a single variant image" do
41
+ api_get :show, :id => product_image.id, :variant_id => product.master.id
42
+ expect(response.status).to eq(200)
43
+ expect(json_response).to have_attributes(attributes)
44
+ end
45
+
46
+ it "can get a list of product images" do
47
+ api_get :index, :product_id => product.id
48
+ expect(response.status).to eq(200)
49
+ expect(json_response).to have_key("images")
50
+ expect(json_response["images"].first).to have_attributes(attributes)
51
+ end
52
+
53
+ it "can get a list of variant images" do
54
+ api_get :index, :variant_id => product.master.id
55
+ expect(response.status).to eq(200)
56
+ expect(json_response).to have_key("images")
57
+ expect(json_response["images"].first).to have_attributes(attributes)
58
+ end
59
+
60
+ it "can update image data" do
61
+ expect(product_image.position).to eq(1)
62
+ api_post :update, :image => { :position => 2 }, :id => product_image.id, :product_id => product.id
63
+ expect(response.status).to eq(200)
64
+ expect(json_response).to have_attributes(attributes)
65
+ expect(product_image.reload.position).to eq(2)
66
+ end
67
+
68
+ it "can delete an image" do
69
+ api_delete :destroy, :id => product_image.id, :product_id => product.id
70
+ expect(response.status).to eq(204)
71
+ expect { product_image.reload }.to raise_error(ActiveRecord::RecordNotFound)
72
+ end
73
+ end
74
+ end
75
+
76
+ context "as a non-admin" do
77
+ it "cannot create an image" do
78
+ api_post :create, :product_id => product.id
79
+ assert_unauthorized!
80
+ end
81
+
82
+ it "cannot update an image" do
83
+ api_put :update, :id => 1, :product_id => product.id
84
+ assert_not_found!
85
+ end
86
+
87
+ it "cannot delete an image" do
88
+ api_delete :destroy, :id => 1, :product_id => product.id
89
+ assert_not_found!
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Api::InventoryUnitsController, :type => :controller do
5
+ render_views
6
+
7
+ before do
8
+ stub_authentication!
9
+ @inventory_unit = create(:inventory_unit)
10
+ end
11
+
12
+ context "as an admin" do
13
+ sign_in_as_admin!
14
+ let(:variant) { create(:variant) }
15
+
16
+ it "gets an inventory unit" do
17
+ api_get :show, :id => @inventory_unit.id
18
+ expect(json_response['state']).to eq @inventory_unit.state
19
+ end
20
+
21
+ it "updates an inventory unit" do
22
+ api_put :update, :id => @inventory_unit.id,
23
+ :inventory_unit => { variant_id: variant.id }
24
+ json_response['variant_id'].should eq variant.id
25
+ end
26
+
27
+ context 'fires state event' do
28
+ it 'if supplied with :fire param' do
29
+ api_put :update, :id => @inventory_unit.id,
30
+ :fire => 'ship',
31
+ :inventory_unit => { variant_id: variant.id }
32
+
33
+ expect(json_response['state']).to eq 'shipped'
34
+ end
35
+
36
+ it 'and returns exception if cannot fire' do
37
+ api_put :update, :id => @inventory_unit.id,
38
+ :fire => 'return'
39
+ expect(json_response['exception']).to match /cannot transition to return/
40
+ end
41
+
42
+ it 'and returns exception bad state' do
43
+ api_put :update, :id => @inventory_unit.id,
44
+ :fire => 'bad'
45
+ expect(json_response['exception']).to match /cannot transition to bad/
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,186 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ PermittedAttributes.module_eval do
5
+ mattr_writer :line_item_attributes
6
+ end
7
+
8
+ unless PermittedAttributes.line_item_attributes.include? :some_option
9
+ PermittedAttributes.line_item_attributes += [:some_option]
10
+ end
11
+
12
+ # This should go in an initializer
13
+ Spree::Api::LineItemsController.line_item_options += [:some_option]
14
+
15
+ describe Api::LineItemsController, :type => :controller do
16
+ render_views
17
+
18
+ let!(:order) { create(:order_with_line_items, line_items_count: 1) }
19
+
20
+ let(:product) { create(:product) }
21
+ let(:attributes) { [:id, :quantity, :price, :variant, :total, :display_amount, :single_display_amount] }
22
+ let(:resource_scoping) { { :order_id => order.to_param } }
23
+
24
+ before do
25
+ stub_authentication!
26
+ end
27
+
28
+ it "can learn how to create a new line item" do
29
+ api_get :new
30
+ expect(json_response["attributes"]).to eq(["quantity", "price", "variant_id"])
31
+ required_attributes = json_response["required_attributes"]
32
+ expect(required_attributes).to include("quantity", "variant_id")
33
+ end
34
+
35
+ context "authenticating with a token" do
36
+ it "can add a new line item to an existing order" do
37
+ api_post :create, :line_item => { :variant_id => product.master.to_param, :quantity => 1 }, :order_token => order.guest_token
38
+ expect(response.status).to eq(201)
39
+ expect(json_response).to have_attributes(attributes)
40
+ expect(json_response["variant"]["name"]).not_to be_blank
41
+ end
42
+
43
+ it "can add a new line item to an existing order with token in header" do
44
+ request.headers["X-Spree-Order-Token"] = order.guest_token
45
+ api_post :create, :line_item => { :variant_id => product.master.to_param, :quantity => 1 }
46
+ expect(response.status).to eq(201)
47
+ expect(json_response).to have_attributes(attributes)
48
+ expect(json_response["variant"]["name"]).not_to be_blank
49
+ end
50
+ end
51
+
52
+ context "as the order owner" do
53
+ before do
54
+ allow_any_instance_of(Order).to receive_messages :user => current_api_user
55
+ end
56
+
57
+ it "can add a new line item to an existing order" do
58
+ api_post :create, :line_item => { :variant_id => product.master.to_param, :quantity => 1 }
59
+ expect(response.status).to eq(201)
60
+ expect(json_response).to have_attributes(attributes)
61
+ expect(json_response["variant"]["name"]).not_to be_blank
62
+ end
63
+
64
+ it "can add a new line item to an existing order with options" do
65
+ expect_any_instance_of(LineItem).to receive(:some_option=).with(4)
66
+ api_post :create,
67
+ line_item: {
68
+ variant_id: product.master.to_param,
69
+ quantity: 1,
70
+ options: { some_option: 4 }
71
+ }
72
+ expect(response.status).to eq(201)
73
+ end
74
+
75
+ it "default quantity to 1 if none is given" do
76
+ api_post :create, :line_item => { :variant_id => product.master.to_param }
77
+ expect(response.status).to eq(201)
78
+ expect(json_response).to have_attributes(attributes)
79
+ expect(json_response[:quantity]).to eq 1
80
+ end
81
+
82
+ it "increases a line item's quantity if it exists already" do
83
+ order.line_items.create(:variant_id => product.master.id, :quantity => 10)
84
+ api_post :create, :line_item => { :variant_id => product.master.to_param, :quantity => 1 }
85
+ expect(response.status).to eq(201)
86
+ order.reload
87
+ expect(order.line_items.count).to eq(2) # 1 original due to factory, + 1 in this test
88
+ expect(json_response).to have_attributes(attributes)
89
+ expect(json_response["quantity"]).to eq(11)
90
+ end
91
+
92
+ it "can update a line item on the order" do
93
+ line_item = order.line_items.first
94
+ api_put :update, :id => line_item.id, :line_item => { :quantity => 101 }
95
+ expect(response.status).to eq(200)
96
+ order.reload
97
+ expect(order.total).to eq(1010) # 10 original due to factory, + 1000 in this test
98
+ expect(json_response).to have_attributes(attributes)
99
+ expect(json_response["quantity"]).to eq(101)
100
+ end
101
+
102
+ it "can update a line item's options on the order" do
103
+ expect_any_instance_of(LineItem).to receive(:some_option=).with(12)
104
+ line_item = order.line_items.first
105
+ api_put :update,
106
+ id: line_item.id,
107
+ line_item: { quantity: 1, options: { some_option: 12 } }
108
+ expect(response.status).to eq(200)
109
+ end
110
+
111
+ it "can delete a line item on the order" do
112
+ line_item = order.line_items.first
113
+ api_delete :destroy, :id => line_item.id
114
+ expect(response.status).to eq(204)
115
+ order.reload
116
+ expect(order.line_items.count).to eq(0) # 1 original due to factory, - 1 in this test
117
+ expect { line_item.reload }.to raise_error(ActiveRecord::RecordNotFound)
118
+ end
119
+
120
+ context "order contents changed after shipments were created" do
121
+ let!(:order) { Order.create }
122
+ let!(:line_item) { order.contents.add(product.master) }
123
+
124
+ before { order.create_proposed_shipments }
125
+
126
+ it "clear out shipments on create" do
127
+ expect(order.reload.shipments).not_to be_empty
128
+ api_post :create, :line_item => { :variant_id => product.master.to_param, :quantity => 1 }
129
+ expect(order.reload.shipments).to be_empty
130
+ end
131
+
132
+ it "clear out shipments on update" do
133
+ expect(order.reload.shipments).not_to be_empty
134
+ api_put :update, :id => line_item.id, :line_item => { :quantity => 1000 }
135
+ expect(order.reload.shipments).to be_empty
136
+ end
137
+
138
+ it "clear out shipments on delete" do
139
+ expect(order.reload.shipments).not_to be_empty
140
+ api_delete :destroy, :id => line_item.id
141
+ expect(order.reload.shipments).to be_empty
142
+ end
143
+
144
+ context "order is completed" do
145
+ before do
146
+ allow(order).to receive_messages completed?: true
147
+ allow(Order).to receive_message_chain :includes, find_by!: order
148
+ end
149
+
150
+ it "doesn't destroy shipments or restart checkout flow" do
151
+ expect(order.reload.shipments).not_to be_empty
152
+ api_post :create, :line_item => { :variant_id => product.master.to_param, :quantity => 1 }
153
+ expect(order.reload.shipments).not_to be_empty
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ context "as just another user" do
160
+ before do
161
+ user = create(:user)
162
+ allow(Spree.user_class).to receive(:find_by).
163
+ and_return(user)
164
+ end
165
+
166
+ it "cannot add a new line item to the order" do
167
+ api_post :create, :line_item => { :variant_id => product.master.to_param, :quantity => 1 }
168
+ assert_unauthorized!
169
+ end
170
+
171
+ it "cannot update a line item on the order" do
172
+ line_item = order.line_items.first
173
+ api_put :update, :id => line_item.id, :line_item => { :quantity => 1000 }
174
+ assert_unauthorized!
175
+ expect(line_item.reload.quantity).not_to eq(1000)
176
+ end
177
+
178
+ it "cannot delete a line item on the order" do
179
+ line_item = order.line_items.first
180
+ api_delete :destroy, :id => line_item.id
181
+ assert_unauthorized!
182
+ expect { line_item.reload }.not_to raise_error
183
+ end
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,116 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Api::OptionTypesController, :type => :controller do
5
+ render_views
6
+
7
+ let(:attributes) { [:id, :name, :position, :presentation] }
8
+ let!(:option_value) { create(:option_value) }
9
+ let!(:option_type) { option_value.option_type }
10
+
11
+ before do
12
+ stub_authentication!
13
+ end
14
+
15
+ def check_option_values(option_values)
16
+ expect(option_values.count).to eq(1)
17
+ expect(option_values.first).to have_attributes([:id, :name, :presentation,
18
+ :option_type_name, :option_type_id])
19
+ end
20
+
21
+ it "can list all option types" do
22
+ api_get :index
23
+ expect(json_response.count).to eq(1)
24
+ expect(json_response.first).to have_attributes(attributes)
25
+
26
+ check_option_values(json_response.first["option_values"])
27
+ end
28
+
29
+ it "can search for an option type" do
30
+ create(:option_type, :name => "buzz")
31
+ api_get :index, :q => { :name_cont => option_type.name }
32
+ expect(json_response.count).to eq(1)
33
+ expect(json_response.first).to have_attributes(attributes)
34
+ end
35
+
36
+ it "can retrieve a list of specific option types" do
37
+ option_type_1 = create(:option_type)
38
+ option_type_2 = create(:option_type)
39
+ api_get :index, :ids => "#{option_type.id},#{option_type_1.id}"
40
+ expect(json_response.count).to eq(2)
41
+
42
+ check_option_values(json_response.first["option_values"])
43
+ end
44
+
45
+ it "can list a single option type" do
46
+ api_get :show, :id => option_type.id
47
+ expect(json_response).to have_attributes(attributes)
48
+ check_option_values(json_response["option_values"])
49
+ end
50
+
51
+ it "cannot create a new option type" do
52
+ api_post :create, :option_type => {
53
+ :name => "Option Type",
54
+ :presentation => "Option Type"
55
+ }
56
+ assert_unauthorized!
57
+ end
58
+
59
+ it "cannot alter an option type" do
60
+ original_name = option_type.name
61
+ api_put :update, :id => option_type.id,
62
+ :option_type => {
63
+ :name => "Option Type"
64
+ }
65
+ assert_not_found!
66
+ expect(option_type.reload.name).to eq(original_name)
67
+ end
68
+
69
+ it "cannot delete an option type" do
70
+ api_delete :destroy, :id => option_type.id
71
+ assert_not_found!
72
+ expect { option_type.reload }.not_to raise_error
73
+ end
74
+
75
+ context "as an admin" do
76
+ sign_in_as_admin!
77
+
78
+ it "can create an option type" do
79
+ api_post :create, :option_type => {
80
+ :name => "Option Type",
81
+ :presentation => "Option Type"
82
+ }
83
+ expect(json_response).to have_attributes(attributes)
84
+ expect(response.status).to eq(201)
85
+ end
86
+
87
+ it "cannot create an option type with invalid attributes" do
88
+ api_post :create, :option_type => {}
89
+ expect(response.status).to eq(422)
90
+ end
91
+
92
+ it "can update an option type" do
93
+ original_name = option_type.name
94
+ api_put :update, :id => option_type.id, :option_type => {
95
+ :name => "Option Type",
96
+ }
97
+ expect(response.status).to eq(200)
98
+
99
+ option_type.reload
100
+ expect(option_type.name).to eq("Option Type")
101
+ end
102
+
103
+ it "cannot update an option type with invalid attributes" do
104
+ api_put :update, :id => option_type.id, :option_type => {
105
+ :name => ""
106
+ }
107
+ expect(response.status).to eq(422)
108
+ end
109
+
110
+ it "can delete an option type" do
111
+ api_delete :destroy, :id => option_type.id
112
+ expect(response.status).to eq(204)
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,135 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Api::OptionValuesController, :type => :controller do
5
+ render_views
6
+
7
+ let(:attributes) { [:id, :name, :presentation, :option_type_name, :option_type_name] }
8
+ let!(:option_value) { create(:option_value) }
9
+ let!(:option_type) { option_value.option_type }
10
+
11
+ before do
12
+ stub_authentication!
13
+ end
14
+
15
+ def check_option_values(option_values)
16
+ expect(option_values.count).to eq(1)
17
+ expect(option_values.first).to have_attributes([:id, :name, :presentation,
18
+ :option_type_name, :option_type_id])
19
+ end
20
+
21
+ context "without any option type scoping" do
22
+ before do
23
+ # Create another option value with a brand new option type
24
+ create(:option_value, :option_type => create(:option_type))
25
+ end
26
+
27
+ it "can retrieve a list of all option values" do
28
+ api_get :index
29
+ expect(json_response.count).to eq(2)
30
+ expect(json_response.first).to have_attributes(attributes)
31
+ end
32
+ end
33
+
34
+ context "for a particular option type" do
35
+ let(:resource_scoping) { { :option_type_id => option_type.id } }
36
+
37
+ it "can list all option values" do
38
+ api_get :index
39
+ expect(json_response.count).to eq(1)
40
+ expect(json_response.first).to have_attributes(attributes)
41
+ end
42
+
43
+ it "can search for an option type" do
44
+ create(:option_value, :name => "buzz")
45
+ api_get :index, :q => { :name_cont => option_value.name }
46
+ expect(json_response.count).to eq(1)
47
+ expect(json_response.first).to have_attributes(attributes)
48
+ end
49
+
50
+ it "can retrieve a list of option types" do
51
+ option_value_1 = create(:option_value, :option_type => option_type)
52
+ option_value_2 = create(:option_value, :option_type => option_type)
53
+ api_get :index, :ids => [option_value.id, option_value_1.id]
54
+ expect(json_response.count).to eq(2)
55
+ end
56
+
57
+ it "can list a single option value" do
58
+ api_get :show, :id => option_value.id
59
+ expect(json_response).to have_attributes(attributes)
60
+ end
61
+
62
+ it "cannot create a new option value" do
63
+ api_post :create, :option_value => {
64
+ :name => "Option Value",
65
+ :presentation => "Option Value"
66
+ }
67
+ assert_unauthorized!
68
+ end
69
+
70
+ it "cannot alter an option value" do
71
+ original_name = option_type.name
72
+ api_put :update, :id => option_type.id,
73
+ :option_value => {
74
+ :name => "Option Value"
75
+ }
76
+ assert_not_found!
77
+ expect(option_type.reload.name).to eq(original_name)
78
+ end
79
+
80
+ it "cannot delete an option value" do
81
+ api_delete :destroy, :id => option_type.id
82
+ assert_not_found!
83
+ expect { option_type.reload }.not_to raise_error
84
+ end
85
+
86
+ context "as an admin" do
87
+ sign_in_as_admin!
88
+
89
+ it "can create an option value" do
90
+ api_post :create, :option_value => {
91
+ :name => "Option Value",
92
+ :presentation => "Option Value"
93
+ }
94
+ expect(json_response).to have_attributes(attributes)
95
+ expect(response.status).to eq(201)
96
+ end
97
+
98
+ it "cannot create an option type with invalid attributes" do
99
+ api_post :create, :option_value => {}
100
+ expect(response.status).to eq(422)
101
+ end
102
+
103
+ it "can update an option value" do
104
+ original_name = option_value.name
105
+ api_put :update, :id => option_value.id, :option_value => {
106
+ :name => "Option Value",
107
+ }
108
+ expect(response.status).to eq(200)
109
+
110
+ option_value.reload
111
+ expect(option_value.name).to eq("Option Value")
112
+ end
113
+
114
+ it "permits the correct attributes" do
115
+ expect(controller).to receive(:permitted_option_value_attributes)
116
+ api_put :update, :id => option_value.id, :option_value => {
117
+ :name => ""
118
+ }
119
+ end
120
+
121
+ it "cannot update an option value with invalid attributes" do
122
+ api_put :update, :id => option_value.id, :option_value => {
123
+ :name => ""
124
+ }
125
+ expect(response.status).to eq(422)
126
+ end
127
+
128
+ it "can delete an option value" do
129
+ api_delete :destroy, :id => option_value.id
130
+ expect(response.status).to eq(204)
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end