solidus_api 1.0.7 → 1.1.0.beta1

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.

Potentially problematic release.


This version of solidus_api might be problematic. Click here for more details.

Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/spree/api/address_books_controller.rb +38 -0
  3. data/app/controllers/spree/api/addresses_controller.rb +19 -15
  4. data/app/controllers/spree/api/base_controller.rb +7 -28
  5. data/app/controllers/spree/api/checkouts_controller.rb +17 -8
  6. data/app/controllers/spree/api/option_values_controller.rb +1 -1
  7. data/app/controllers/spree/api/orders_controller.rb +13 -18
  8. data/app/controllers/spree/api/payments_controller.rb +0 -1
  9. data/app/controllers/spree/api/resource_controller.rb +75 -0
  10. data/app/controllers/spree/api/shipments_controller.rb +1 -0
  11. data/app/controllers/spree/api/stock_items_controller.rb +1 -3
  12. data/app/controllers/spree/api/stock_transfers_controller.rb +1 -0
  13. data/app/controllers/spree/api/users_controller.rb +13 -49
  14. data/app/controllers/spree/api/zones_controller.rb +7 -3
  15. data/app/helpers/spree/api/api_helpers.rb +9 -4
  16. data/app/views/spree/api/address_books/show.v1.rabl +4 -0
  17. data/app/views/spree/api/orders/show.v1.rabl +2 -2
  18. data/app/views/spree/api/variants/big.v1.rabl +3 -0
  19. data/config/locales/en.yml +0 -1
  20. data/config/routes.rb +3 -0
  21. data/lib/spree/api/testing_support/helpers.rb +1 -1
  22. data/lib/spree/api/testing_support/setup.rb +1 -4
  23. data/spec/controllers/spree/api/address_books_controller_spec.rb +60 -0
  24. data/spec/controllers/spree/api/addresses_controller_spec.rb +22 -9
  25. data/spec/controllers/spree/api/base_controller_spec.rb +0 -12
  26. data/spec/controllers/spree/api/checkouts_controller_spec.rb +107 -45
  27. data/spec/controllers/spree/api/credit_cards_controller_spec.rb +4 -11
  28. data/spec/controllers/spree/api/orders_controller_spec.rb +75 -105
  29. data/spec/controllers/spree/api/payments_controller_spec.rb +0 -11
  30. data/spec/controllers/spree/api/products_controller_spec.rb +2 -2
  31. data/spec/controllers/spree/api/resource_controller_spec.rb +157 -0
  32. data/spec/controllers/spree/api/shipments_controller_spec.rb +12 -13
  33. data/spec/controllers/spree/api/stock_items_controller_spec.rb +2 -2
  34. data/spec/controllers/spree/api/users_controller_spec.rb +2 -2
  35. data/spec/controllers/spree/api/variants_controller_spec.rb +32 -3
  36. data/spec/models/spree/legacy_user_spec.rb +8 -2
  37. data/spec/spec_helper.rb +8 -3
  38. data/spec/test_views/spree/api/widgets/index.v1.rabl +7 -0
  39. data/spec/test_views/spree/api/widgets/new.v1.rabl +2 -0
  40. data/spec/test_views/spree/api/widgets/show.v1.rabl +2 -0
  41. metadata +20 -9
  42. data/CHANGELOG.md +0 -1
  43. data/app/views/spree/api/shared/stock_location_required.v1.rabl +0 -2
@@ -7,6 +7,7 @@ module Spree
7
7
  variant = Spree::Variant.accessible_by(current_ability, :show).find(params[:variant_id])
8
8
  @transfer_item = @stock_transfer.transfer_items.find_by(variant: variant)
9
9
  if @transfer_item.nil?
10
+ logger.error("variant_not_in_stock_transfer")
10
11
  render "spree/api/errors/variant_not_in_stock_transfer", status: 422
11
12
  elsif @transfer_item.update_attributes(received_quantity: @transfer_item.received_quantity + 1)
12
13
  render 'spree/api/stock_transfers/receive', status: 200
@@ -1,56 +1,20 @@
1
- module Spree
2
- module Api
3
- class UsersController < Spree::Api::BaseController
1
+ class Spree::Api::UsersController < Spree::Api::ResourceController
4
2
 
5
- def index
6
- @users = Spree.user_class.accessible_by(current_ability,:read).ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
7
- respond_with(@users)
8
- end
3
+ private
9
4
 
10
- def show
11
- respond_with(user)
12
- end
13
-
14
- def new
15
- end
16
-
17
- def create
18
- authorize! :create, Spree.user_class
19
- @user = Spree.user_class.new(user_params)
20
- if @user.save
21
- respond_with(@user, :status => 201, :default_template => :show)
22
- else
23
- invalid_resource!(@user)
24
- end
25
- end
26
-
27
- def update
28
- authorize! :update, user
29
- if user.update_attributes(user_params)
30
- respond_with(user, :status => 200, :default_template => :show)
31
- else
32
- invalid_resource!(user)
33
- end
34
- end
35
-
36
- def destroy
37
- authorize! :destroy, user
38
- user.destroy
39
- respond_with(user, :status => 204)
40
- end
41
-
42
- private
5
+ def user
6
+ @user
7
+ end
43
8
 
44
- def user
45
- @user ||= Spree.user_class.accessible_by(current_ability, :read).find(params[:id])
46
- end
9
+ def model_class
10
+ Spree.user_class
11
+ end
47
12
 
48
- def user_params
49
- params.require(:user).permit(permitted_user_attributes |
50
- [bill_address_attributes: permitted_address_attributes,
51
- ship_address_attributes: permitted_address_attributes])
52
- end
13
+ def user_params
14
+ permitted_resource_params
15
+ end
53
16
 
54
- end
17
+ def permitted_resource_attributes
18
+ super | [bill_address_attributes: permitted_address_attributes, ship_address_attributes: permitted_address_attributes]
55
19
  end
56
20
  end
@@ -4,7 +4,7 @@ module Spree
4
4
 
5
5
  def create
6
6
  authorize! :create, Zone
7
- @zone = Zone.new(map_nested_attributes_keys(Spree::Zone, zone_params))
7
+ @zone = Zone.new(zone_params)
8
8
  if @zone.save
9
9
  respond_with(@zone, :status => 201, :default_template => :show)
10
10
  else
@@ -29,7 +29,7 @@ module Spree
29
29
 
30
30
  def update
31
31
  authorize! :update, zone
32
- if zone.update_attributes(map_nested_attributes_keys(Spree::Zone, zone_params))
32
+ if zone.update_attributes(zone_params)
33
33
  respond_with(zone, :status => 200, :default_template => :show)
34
34
  else
35
35
  invalid_resource!(zone)
@@ -39,7 +39,11 @@ module Spree
39
39
  private
40
40
 
41
41
  def zone_params
42
- params.require(:zone).permit!
42
+ attrs = params.require(:zone).permit!
43
+ if attrs[:zone_members]
44
+ attrs[:zone_members_attributes] = attrs.delete(:zone_members)
45
+ end
46
+ attrs
43
47
  end
44
48
 
45
49
  def zone
@@ -33,7 +33,8 @@ module Spree
33
33
  :store_credit_history_attributes,
34
34
  :stock_transfer_attributes,
35
35
  :transfer_item_attributes,
36
- :transfer_item_variant_attributes
36
+ :transfer_item_variant_attributes,
37
+ :variant_property_attributes
37
38
  ]
38
39
 
39
40
  mattr_reader *ATTRIBUTES
@@ -65,6 +66,10 @@ module Spree
65
66
  :slug, :description, :track_inventory
66
67
  ]
67
68
 
69
+ @@variant_property_attributes = [
70
+ :id, :property_id, :value, :property_name
71
+ ]
72
+
68
73
  @@image_attributes = [
69
74
  :id, :position, :attachment_content_type, :attachment_file_name, :type,
70
75
  :attachment_updated_at, :attachment_width, :attachment_height, :alt
@@ -119,8 +124,8 @@ module Spree
119
124
 
120
125
  @@address_attributes = [
121
126
  :id, :firstname, :lastname, :full_name, :address1, :address2, :city,
122
- :zipcode, :phone, :company, :alternative_phone, :country_id, :state_id,
123
- :state_name, :state_text
127
+ :zipcode, :phone, :company, :alternative_phone, :country_id, :country_iso,
128
+ :state_id, :state_name, :state_text
124
129
  ]
125
130
 
126
131
  @@country_attributes = [:id, :iso_name, :iso, :iso3, :name, :numcode]
@@ -129,7 +134,7 @@ module Spree
129
134
 
130
135
  @@adjustment_attributes = [
131
136
  :id, :source_type, :source_id, :adjustable_type, :adjustable_id,
132
- :originator_type, :originator_id, :amount, :label, :mandatory, :promotion_code,
137
+ :originator_type, :originator_id, :amount, :label, :promotion_code,
133
138
  :locked, :eligible, :created_at, :updated_at
134
139
  ]
135
140
 
@@ -0,0 +1,4 @@
1
+ collection @user_addresses
2
+ node do |user_address|
3
+ partial("spree/api/addresses/show", object: user_address.address).merge(default: user_address.default)
4
+ end
@@ -2,7 +2,7 @@ object @order
2
2
  extends "spree/api/orders/order"
3
3
 
4
4
  child :available_payment_methods => :payment_methods do
5
- attributes :id, :name, :environment, :method_type
5
+ attributes :id, :name, :method_type
6
6
  end
7
7
 
8
8
  child :billing_address => :bill_address do
@@ -21,7 +21,7 @@ child :payments => :payments do
21
21
  attributes *payment_attributes
22
22
 
23
23
  child :payment_method => :payment_method do
24
- attributes :id, :name, :environment
24
+ attributes :id, :name
25
25
  end
26
26
 
27
27
  child :source => :source do
@@ -9,6 +9,9 @@ node :total_on_hand do
9
9
  root_object.total_on_hand
10
10
  end
11
11
 
12
+ child :variant_properties => :variant_properties do
13
+ attributes *variant_property_attributes
14
+ end
12
15
 
13
16
  child(root_object.stock_items.accessible_by(current_ability) => :stock_items) do
14
17
  attributes :id, :count_on_hand, :stock_location_id, :backorderable
@@ -25,5 +25,4 @@ en:
25
25
  update_forbidden: "This payment cannot be updated because it is %{state}."
26
26
  shipment:
27
27
  cannot_ready: "Cannot ready shipment."
28
- stock_location_required: "A stock_location_id parameter must be provided in order to retrieve stock movements."
29
28
  invalid_taxonomy_id: "Invalid taxonomy id."
@@ -61,6 +61,7 @@ Spree::Core::Engine.add_routes do
61
61
  resources :option_types do
62
62
  resources :option_values
63
63
  end
64
+ resources :option_values
64
65
 
65
66
  resources :option_values, only: :index
66
67
  get '/orders/mine', to: 'orders#mine', as: 'my_orders'
@@ -133,6 +134,8 @@ Spree::Core::Engine.add_routes do
133
134
  end
134
135
  end
135
136
 
137
+ resource :address_book, only: [:show, :update, :destroy]
138
+
136
139
  get '/config/money', to: 'config#money'
137
140
  get '/config', to: 'config#show'
138
141
  put '/classifications', to: 'classifications#update', as: :classifications
@@ -28,7 +28,7 @@ module Spree
28
28
  # This method can be overriden (with a let block) inside a context
29
29
  # For instance, if you wanted to have an admin user instead.
30
30
  def current_api_user
31
- @current_api_user ||= stub_model(Spree::LegacyUser, email: "spree@example.com")
31
+ @current_api_user ||= stub_model(Spree::LegacyUser, email: "spree@example.com", spree_roles: [])
32
32
  end
33
33
 
34
34
  def image(filename)
@@ -4,10 +4,7 @@ module Spree
4
4
  module Setup
5
5
  def sign_in_as_admin!
6
6
  let!(:current_api_user) do
7
- user = stub_model(Spree::LegacyUser)
8
- allow(user).to receive_message_chain(:spree_roles, :pluck).and_return(["admin"])
9
- allow(user).to receive(:has_spree_role?).with("admin").and_return(true)
10
- user
7
+ stub_model(Spree::LegacyUser, spree_roles: [Spree::Role.new(name: 'admin')])
11
8
  end
12
9
  end
13
10
  end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Api::AddressBooksController, :type => :controller do
5
+ render_views
6
+
7
+ context "unauthorized user" do
8
+ it "get 401 on /show" do
9
+ api_get :show
10
+ expect(response.status).to eq 401
11
+ end
12
+
13
+ it "get 401 on /update" do
14
+ api_put :update
15
+ expect(response.status).to eq 401
16
+ end
17
+
18
+ it "get 401 on /destroy" do
19
+ api_delete :destroy, address_id: 1
20
+ expect(response.status).to eq 401
21
+ end
22
+ end
23
+
24
+ context "authorized user with addresses" do
25
+ let(:address1) { create(:address) }
26
+ let(:address2) { create(:address, firstname: "Different") }
27
+
28
+ before do
29
+ stub_authentication!
30
+ current_api_user.save_in_address_book(address1.attributes, true)
31
+ current_api_user.save_in_address_book(address2.attributes, false)
32
+ end
33
+
34
+ it "gets their address book" do
35
+ api_get :show
36
+ expect(json_response.length).to eq 2
37
+ end
38
+
39
+ it "the first one is default" do
40
+ api_get :show
41
+ first, second = *json_response
42
+ expect(first["default"]).to be true
43
+ expect(second["default"]).to be false
44
+ end
45
+
46
+ it "can remove an address" do
47
+ api_delete :destroy, address_id: address1.id
48
+ expect(json_response.length).to eq 1
49
+ end
50
+
51
+ it "can update an address" do
52
+ updated_params = address2.attributes
53
+ updated_params[:firstname] = "Johnny"
54
+ updated_params[:default] = true
55
+ api_put :update, address_book: updated_params
56
+ expect(json_response.first["firstname"]).to eq "Johnny"
57
+ end
58
+ end
59
+ end
60
+ end
@@ -10,20 +10,33 @@ module Spree
10
10
  @order = create(:order, :bill_address => @address)
11
11
  end
12
12
 
13
- context "with their own address" do
13
+ context "with order" do
14
14
  before do
15
15
  allow_any_instance_of(Order).to receive_messages :user => current_api_user
16
16
  end
17
17
 
18
- it "gets an address" do
19
- api_get :show, :id => @address.id, :order_id => @order.number
20
- expect(json_response['address1']).to eq @address.address1
21
- end
18
+ context "with their own address" do
22
19
 
23
- it "updates an address" do
24
- api_put :update, :id => @address.id, :order_id => @order.number,
25
- :address => { :address1 => "123 Test Lane" }
26
- expect(json_response['address1']).to eq '123 Test Lane'
20
+ it "gets an address" do
21
+ api_get :show, :id => @address.id, :order_id => @order.number
22
+ expect(json_response['address1']).to eq @address.address1
23
+ end
24
+
25
+ it "update replaces the readonly Address associated to the Order" do
26
+ api_put :update, :id => @address.id, :order_id => @order.number,
27
+ :address => { :address1 => "123 Test Lane" }
28
+ expect(Order.find(@order.id).bill_address_id).not_to eq @address.id
29
+ expect(json_response['address1']).to eq '123 Test Lane'
30
+ end
31
+
32
+ it "receives the errors object if address is invalid" do
33
+ api_put :update, :id => @address.id, :order_id => @order.number,
34
+ :address => { :address1 => "" }
35
+
36
+ expect(json_response['error']).not_to be_nil
37
+ expect(json_response['errors']).not_to be_nil
38
+ expect(json_response['errors']['address1'].first).to eq "can't be blank"
39
+ end
27
40
  end
28
41
 
29
42
  it "receives the errors object if address is invalid" do
@@ -79,18 +79,6 @@ describe Spree::Api::BaseController, :type => :controller do
79
79
  }.to raise_error(Exception, "no joy")
80
80
  end
81
81
 
82
- it "maps semantic keys to nested_attributes keys" do
83
- klass = double(:nested_attributes_options => { :line_items => {},
84
- :bill_address => {} })
85
- attributes = { 'line_items' => { :id => 1 },
86
- 'bill_address' => { :id => 2 },
87
- 'name' => 'test order' }
88
-
89
- mapped = subject.map_nested_attributes_keys(klass, attributes)
90
- expect(mapped.has_key?('line_items_attributes')).to be true
91
- expect(mapped.has_key?('name')).to be true
92
- end
93
-
94
82
  it "lets a subclass override the product associations that are eager-loaded" do
95
83
  expect(controller.respond_to?(:product_includes, true)).to be
96
84
  end
@@ -31,7 +31,6 @@ module Spree
31
31
  end
32
32
 
33
33
  before(:each) do
34
- allow_any_instance_of(Order).to receive_messages(confirmation_required?: true)
35
34
  allow_any_instance_of(Order).to receive_messages(payment_required?: true)
36
35
  end
37
36
 
@@ -164,19 +163,6 @@ module Spree
164
163
  expect(response.status).to eq(200)
165
164
  end
166
165
 
167
- context "with disallowed payment method" do
168
- it "returns not found" do
169
- order.update_column(:state, "payment")
170
- allow_any_instance_of(Spree::Gateway::Bogus).to receive(:source_required?).and_return(false)
171
- @payment_method.update!(display_on: "back_end")
172
- expect {
173
- api_put :update, id: order.to_param, order_token: order.guest_token, order: { payments_attributes: [{ payment_method_id: @payment_method.id }] }
174
- }.not_to change { Spree::Payment.count }
175
- expect(response.status).to eq(404)
176
- end
177
- end
178
-
179
-
180
166
  it "returns errors when source is required and missing" do
181
167
  order.update_column(:state, "payment")
182
168
  api_put :update, :id => order.to_param, :order_token => order.guest_token,
@@ -186,40 +172,118 @@ module Spree
186
172
  expect(source_errors).to include("can't be blank")
187
173
  end
188
174
 
189
- it "can update payment method with source and transition from payment to confirm" do
190
- order.update_column(:state, "payment")
191
- source_attributes = {
192
- number: "4111111111111111",
193
- month: 1.month.from_now.month,
194
- year: 1.month.from_now.year,
195
- verification_value: "123",
196
- name: "Spree Commerce"
197
- }
175
+ describe 'payment method with source and transition from payment to confirm' do
176
+ before do
177
+ order.update_column(:state, "payment")
178
+ end
198
179
 
199
- api_put :update, id: order.to_param, order_token: order.guest_token,
200
- order: { payments_attributes: [{ payment_method_id: @payment_method.id.to_s }]},
201
- payment_source: { @payment_method.id.to_s => source_attributes }
202
- expect(json_response['payments'][0]['payment_method']['name']).to eq(@payment_method.name)
203
- expect(json_response['payments'][0]['amount']).to eq(order.total.to_s)
204
- expect(response.status).to eq(200)
180
+ let(:params) do
181
+ {
182
+ id: order.to_param,
183
+ order_token: order.guest_token,
184
+ order: {
185
+ payments_attributes: [
186
+ {
187
+ payment_method_id: @payment_method.id.to_s,
188
+ source_attributes: attributes_for(:credit_card),
189
+ },
190
+ ],
191
+ },
192
+ }
193
+ end
194
+
195
+ it 'succeeds' do
196
+ api_put(:update, params)
197
+ expect(response.status).to eq(200)
198
+ expect(json_response['payments'][0]['payment_method']['name']).to eq(@payment_method.name)
199
+ expect(json_response['payments'][0]['amount']).to eq(order.total.to_s)
200
+ end
201
+
202
+ context 'with deprecated payment_source parameters' do
203
+ let(:params) do
204
+ {
205
+ id: order.to_param,
206
+ order_token: order.guest_token,
207
+ order: {
208
+ payments_attributes: [
209
+ { payment_method_id: @payment_method.id.to_s },
210
+ ],
211
+ },
212
+ payment_source: { @payment_method.id.to_s => attributes_for(:credit_card) },
213
+ }
214
+ end
215
+
216
+ it "succeeds" do
217
+ ActiveSupport::Deprecation.silence do
218
+ api_put(:update, params)
219
+ end
220
+ expect(response.status).to eq(200)
221
+ expect(json_response['payments'][0]['payment_method']['name']).to eq(@payment_method.name)
222
+ expect(json_response['payments'][0]['amount']).to eq(order.total.to_s)
223
+ end
224
+ end
205
225
  end
206
226
 
207
- it "returns errors when source is missing attributes" do
208
- order.update_column(:state, "payment")
209
- api_put :update, id: order.to_param, order_token: order.guest_token,
210
- order: {
211
- payments_attributes: [{ payment_method_id: @payment_method.id }]
212
- },
213
- payment_source: {
214
- @payment_method.id.to_s => { name: "Spree" }
227
+ context 'when source is missing attributes' do
228
+ before do
229
+ order.update_column(:state, "payment")
230
+ end
231
+
232
+ let(:params) do
233
+ {
234
+ id: order.to_param,
235
+ order_token: order.guest_token,
236
+ order: {
237
+ payments_attributes: [
238
+ {
239
+ payment_method_id: @payment_method.id.to_s,
240
+ source_attributes: {name: "Spree"},
241
+ },
242
+ ],
243
+ },
215
244
  }
245
+ end
216
246
 
217
- expect(response.status).to eq(422)
218
- cc_errors = json_response['errors']['payments.Credit Card']
219
- expect(cc_errors).to include("Number can't be blank")
220
- expect(cc_errors).to include("Month is not a number")
221
- expect(cc_errors).to include("Year is not a number")
222
- expect(cc_errors).to include("Verification Value can't be blank")
247
+ it 'returns errors' do
248
+ api_put(:update, params)
249
+
250
+ expect(response.status).to eq(422)
251
+ cc_errors = json_response['errors']['payments.Credit Card']
252
+ expect(cc_errors).to include("Number can't be blank")
253
+ expect(cc_errors).to include("Month is not a number")
254
+ expect(cc_errors).to include("Year is not a number")
255
+ expect(cc_errors).to include("Verification Value can't be blank")
256
+ end
257
+
258
+ context 'with deprecated payment_source parameters' do
259
+ let(:params) do
260
+ {
261
+ id: order.to_param,
262
+ order_token: order.guest_token,
263
+ order: {
264
+ payments_attributes: [
265
+ {payment_method_id: @payment_method.id.to_s},
266
+ ],
267
+ },
268
+ payment_source: {
269
+ @payment_method.id.to_s => {name: "Spree"},
270
+ },
271
+ }
272
+ end
273
+
274
+ it 'returns errors' do
275
+ ActiveSupport::Deprecation.silence do
276
+ api_put(:update, params)
277
+ end
278
+
279
+ expect(response.status).to eq(422)
280
+ cc_errors = json_response['errors']['payments.Credit Card']
281
+ expect(cc_errors).to include("Number can't be blank")
282
+ expect(cc_errors).to include("Month is not a number")
283
+ expect(cc_errors).to include("Year is not a number")
284
+ expect(cc_errors).to include("Verification Value can't be blank")
285
+ end
286
+ end
223
287
  end
224
288
 
225
289
  it "allow users to reuse a credit card" do
@@ -276,8 +340,6 @@ module Spree
276
340
  end
277
341
 
278
342
  it "can apply a coupon code to an order" do
279
- skip "ensure that the order totals are properly updated, see frontend orders_controller or checkout_controller as example"
280
-
281
343
  order.update_column(:state, "payment")
282
344
  expect(PromotionHandler::Coupon).to receive(:new).with(order).and_call_original
283
345
  expect_any_instance_of(PromotionHandler::Coupon).to receive(:apply).and_return({ coupon_applied?: true })