spree_api 2.3.1 → 2.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -1
  3. data/app/controllers/spree/api/base_controller.rb +33 -12
  4. data/app/controllers/spree/api/credit_cards_controller.rb +25 -0
  5. data/app/controllers/spree/api/inventory_units_controller.rb +1 -0
  6. data/app/controllers/spree/api/line_items_controller.rb +0 -2
  7. data/app/controllers/spree/api/orders_controller.rb +24 -37
  8. data/app/controllers/spree/api/payments_controller.rb +3 -9
  9. data/app/controllers/spree/api/products_controller.rb +2 -0
  10. data/app/controllers/spree/api/shipments_controller.rb +4 -4
  11. data/app/controllers/spree/api/users_controller.rb +4 -1
  12. data/app/views/spree/api/credit_cards/index.v1.rabl +7 -0
  13. data/app/views/spree/api/errors/gateway_error.v1.rabl +1 -1
  14. data/app/views/spree/api/orders/show.v1.rabl +6 -1
  15. data/config/routes.rb +5 -1
  16. data/lib/spree/api/testing_support/setup.rb +1 -0
  17. data/spec/controllers/spree/api/base_controller_spec.rb +9 -3
  18. data/spec/controllers/spree/api/checkouts_controller_spec.rb +11 -0
  19. data/spec/controllers/spree/api/credit_cards_controller_spec.rb +80 -0
  20. data/spec/controllers/spree/api/orders_controller_spec.rb +55 -9
  21. data/spec/controllers/spree/api/payments_controller_spec.rb +17 -13
  22. data/spec/controllers/spree/api/products_controller_spec.rb +30 -2
  23. data/spec/controllers/spree/api/shipments_controller_spec.rb +10 -1
  24. data/spec/controllers/spree/api/stock_items_controller_spec.rb +1 -2
  25. data/spec/controllers/spree/api/users_controller_spec.rb +27 -2
  26. data/spec/controllers/spree/api/variants_controller_spec.rb +0 -1
  27. metadata +8 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d63d55d5121200876df8441e8498fdd5abd71033
4
- data.tar.gz: a7374c7a17909ed7c20d2608b09ccfedc2b1680c
3
+ metadata.gz: 1c3d7994fdc3ab159cb6c5c25c3df0328bdb7d09
4
+ data.tar.gz: 8ed983dd2706eacfa4081f2cb2509685f1e4e565
5
5
  SHA512:
6
- metadata.gz: e55d6044251f2e29f9435f8fd4fb87ac1b5c490dbfaef5626c35b35c23a1f9876e69d7e04df7ce07c7c4986fa795a0bfc20122b8fc7597c0e929abac64ca754d
7
- data.tar.gz: c4a666c49960624a58447d866cde2befd6212b5adcae341ba7fe8f26eb06a45a2881c9e9118f87a5d6199e762b4357b1156be5f57021cb09fc3bab1730f7f95e
6
+ metadata.gz: fd18911bd56574872239ba21ed83030ec250bfaf3d339b05be20d7195bf4a03f27f3fa915b947e09284d01514445e81ae07ef5ef765e5cce971ee8ac69452175
7
+ data.tar.gz: b82a4694d499d371a463583ae30a7b414576cfca8b0430610b2c4191f42f823341c70cdf4f291a4fe856e46c18778d5a71ac69b7eff0058dd6247b4b9f0eaba8
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ## Spree 2.3.0 (unreleased) ##
1
+ ## Spree 2.3.2 (unreleased) ##
2
2
 
3
3
  * Support existing credit card feature on checkout.
4
4
 
@@ -14,11 +14,14 @@ module Spree
14
14
  before_filter :load_user
15
15
  before_filter :authorize_for_order, :if => Proc.new { order_token.present? }
16
16
  before_filter :authenticate_user
17
+ before_filter :load_user_roles
18
+
17
19
  after_filter :set_jsonp_format
18
20
 
19
- rescue_from Exception, :with => :error_during_processing
20
- rescue_from CanCan::AccessDenied, :with => :unauthorized
21
- rescue_from ActiveRecord::RecordNotFound, :with => :not_found
21
+ rescue_from Exception, with: :error_during_processing
22
+ rescue_from ActiveRecord::RecordNotFound, with: :not_found
23
+ rescue_from CanCan::AccessDenied, with: :unauthorized
24
+ rescue_from Spree::Core::GatewayError, with: :gateway_error
22
25
 
23
26
  helper Spree::Api::ApiHelpers
24
27
 
@@ -42,7 +45,7 @@ module Spree
42
45
 
43
46
  # users should be able to set price when importing orders via api
44
47
  def permitted_line_item_attributes
45
- if current_api_user.has_spree_role?("admin")
48
+ if @current_user_roles.include?("admin")
46
49
  super << [:price, :variant_id, :sku]
47
50
  else
48
51
  super
@@ -78,8 +81,16 @@ module Spree
78
81
  end
79
82
  end
80
83
 
84
+ def load_user_roles
85
+ @current_user_roles = if @current_api_user
86
+ @current_api_user.spree_roles.pluck(:name)
87
+ else
88
+ []
89
+ end
90
+ end
91
+
81
92
  def unauthorized
82
- render "spree/api/errors/unauthorized", :status => 401 and return
93
+ render "spree/api/errors/unauthorized", status: 401 and return
83
94
  end
84
95
 
85
96
  def error_during_processing(exception)
@@ -90,12 +101,17 @@ module Spree
90
101
  :status => 422 and return
91
102
  end
92
103
 
104
+ def gateway_error(exception)
105
+ @order.errors.add(:base, exception.message)
106
+ invalid_resource!(@order)
107
+ end
108
+
93
109
  def requires_authentication?
94
110
  Spree::Api::Config[:requires_authentication]
95
111
  end
96
112
 
97
113
  def not_found
98
- render "spree/api/errors/not_found", :status => 404 and return
114
+ render "spree/api/errors/not_found", status: 404 and return
99
115
  end
100
116
 
101
117
  def current_ability
@@ -130,22 +146,27 @@ module Spree
130
146
  end
131
147
 
132
148
  def product_scope
133
- variants_associations = [{ option_values: :option_type }, :default_price, :prices, :images]
134
- if current_api_user.has_spree_role?("admin")
135
- scope = Product.with_deleted.accessible_by(current_ability, :read)
136
- .includes(:properties, :option_types, variants: variants_associations, master: variants_associations)
149
+ if @current_user_roles.include?("admin")
150
+ scope = Product.with_deleted.accessible_by(current_ability, :read).includes(*product_includes)
137
151
 
138
152
  unless params[:show_deleted]
139
153
  scope = scope.not_deleted
140
154
  end
141
155
  else
142
- scope = Product.accessible_by(current_ability, :read).active
143
- .includes(:properties, :option_types, variants: variants_associations, master: variants_associations)
156
+ scope = Product.accessible_by(current_ability, :read).active.includes(*product_includes)
144
157
  end
145
158
 
146
159
  scope
147
160
  end
148
161
 
162
+ def variants_associations
163
+ [{ option_values: :option_type }, :default_price, :images]
164
+ end
165
+
166
+ def product_includes
167
+ [ :option_types, variants: variants_associations, master: variants_associations ]
168
+ end
169
+
149
170
  def order_id
150
171
  params[:order_id] || params[:checkout_id] || params[:order_number]
151
172
  end
@@ -0,0 +1,25 @@
1
+ module Spree
2
+ module Api
3
+ class CreditCardsController < Spree::Api::BaseController
4
+ before_filter :user
5
+
6
+ def index
7
+ @credit_cards = user
8
+ .credit_cards
9
+ .accessible_by(current_ability, :read)
10
+ .with_payment_profile
11
+ .ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
12
+ respond_with(@credit_cards)
13
+ end
14
+
15
+ private
16
+
17
+ def user
18
+ if params[:user_id].present?
19
+ @user ||= Spree::user_class.accessible_by(current_ability, :read).find(params[:user_id])
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -5,6 +5,7 @@ module Spree
5
5
 
6
6
  def show
7
7
  @inventory_unit = inventory_unit
8
+ respond_with(@inventory_unit)
8
9
  end
9
10
 
10
11
  def update
@@ -6,7 +6,6 @@ module Spree
6
6
  @line_item = order.contents.add(variant, params[:line_item][:quantity] || 1)
7
7
 
8
8
  if @line_item.errors.empty?
9
- @order.ensure_updated_shipments
10
9
  respond_with(@line_item, status: 201, default_template: :show)
11
10
  else
12
11
  invalid_resource!(@line_item)
@@ -27,7 +26,6 @@ module Spree
27
26
  @line_item = find_line_item
28
27
  variant = Spree::Variant.find(@line_item.variant_id)
29
28
  @order.contents.remove(variant, @line_item.quantity)
30
- @order.ensure_updated_shipments
31
29
  respond_with(@line_item, status: 204)
32
30
  end
33
31
 
@@ -1,6 +1,8 @@
1
1
  module Spree
2
2
  module Api
3
3
  class OrdersController < Spree::Api::BaseController
4
+ wrap_parameters false
5
+
4
6
  skip_before_filter :check_for_user_or_api_key, only: :apply_coupon_code
5
7
  skip_before_filter :authenticate_user, only: :apply_coupon_code
6
8
 
@@ -17,12 +19,24 @@ module Spree
17
19
  def cancel
18
20
  authorize! :update, @order, params[:token]
19
21
  @order.cancel!
20
- render :show
22
+ respond_with(@order, :default_template => :show)
21
23
  end
22
24
 
23
25
  def create
24
26
  authorize! :create, Order
25
- @order = Spree::Core::Importer::Order.import(current_api_user, order_params)
27
+ order_user = if @current_user_roles.include?('admin') && order_params[:user_id]
28
+ Spree.user_class.find(order_params[:user_id])
29
+ else
30
+ current_api_user
31
+ end
32
+
33
+ import_params = if @current_user_roles.include?("admin")
34
+ params[:order].present? ? params[:order].permit! : {}
35
+ else
36
+ order_params
37
+ end
38
+
39
+ @order = Spree::Core::Importer::Order.import(order_user, import_params)
26
40
  respond_with(@order, default_template: :show, status: 201)
27
41
  end
28
42
 
@@ -40,8 +54,6 @@ module Spree
40
54
 
41
55
  def show
42
56
  authorize! :show, @order, order_token
43
- method = "before_#{@order.state}"
44
- send(method) if respond_to?(method, true)
45
57
  respond_with(@order)
46
58
  end
47
59
 
@@ -62,7 +74,7 @@ module Spree
62
74
 
63
75
  def mine
64
76
  if current_api_user.persisted?
65
- @orders = current_api_user.orders.ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
77
+ @orders = current_api_user.orders.reverse_chronological.ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
66
78
  else
67
79
  render "spree/api/errors/unauthorized", status: :unauthorized
68
80
  end
@@ -80,50 +92,25 @@ module Spree
80
92
  private
81
93
  def order_params
82
94
  if params[:order]
83
- params[:order][:payments_attributes] = params[:order][:payments] if params[:order][:payments]
84
- params[:order][:shipments_attributes] = params[:order][:shipments] if params[:order][:shipments]
85
- params[:order][:line_items_attributes] = params[:order][:line_items] if params[:order][:line_items]
86
- params[:order][:ship_address_attributes] = params[:order][:ship_address] if params[:order][:ship_address]
87
- params[:order][:bill_address_attributes] = params[:order][:bill_address] if params[:order][:bill_address]
88
-
95
+ normalize_params
89
96
  params.require(:order).permit(permitted_order_attributes)
90
97
  else
91
98
  {}
92
99
  end
93
100
  end
94
101
 
95
- def permitted_order_attributes
96
- if current_api_user.has_spree_role? "admin"
97
- super << admin_order_attributes
98
- else
99
- super
100
- end
101
- end
102
-
103
- def permitted_shipment_attributes
104
- if current_api_user.has_spree_role? "admin"
105
- super << admin_shipment_attributes
106
- else
107
- super
108
- end
109
- end
110
-
111
- def admin_shipment_attributes
112
- [:shipping_method, :stock_location, :inventory_units => [:variant_id, :sku]]
113
- end
114
-
115
- def admin_order_attributes
116
- [:import, :number, :completed_at, :locked_at, :channel]
102
+ def normalize_params
103
+ params[:order][:payments_attributes] = params[:order].delete(:payments) if params[:order][:payments]
104
+ params[:order][:shipments_attributes] = params[:order].delete(:shipments) if params[:order][:shipments]
105
+ params[:order][:line_items_attributes] = params[:order].delete(:line_items) if params[:order][:line_items]
106
+ params[:order][:ship_address_attributes] = params[:order].delete(:ship_address) if params[:order][:ship_address]
107
+ params[:order][:bill_address_attributes] = params[:order].delete(:bill_address) if params[:order][:bill_address]
117
108
  end
118
109
 
119
110
  def find_order(lock = false)
120
111
  @order = Spree::Order.lock(lock).find_by!(number: params[:id])
121
112
  end
122
113
 
123
- def before_delivery
124
- @order.create_proposed_shipments
125
- end
126
-
127
114
  def order_id
128
115
  super || params[:id]
129
116
  end
@@ -11,7 +11,7 @@ module Spree
11
11
  end
12
12
 
13
13
  def new
14
- @payment_methods = Spree::PaymentMethod.where(environment: Rails.env)
14
+ @payment_methods = Spree::PaymentMethod.available
15
15
  respond_with(@payment_method)
16
16
  end
17
17
 
@@ -76,14 +76,8 @@ module Spree
76
76
 
77
77
  def perform_payment_action(action, *args)
78
78
  authorize! action, Payment
79
-
80
- begin
81
- @payment.send("#{action}!", *args)
82
- respond_with(@payment, :default_template => :show)
83
- rescue Spree::Core::GatewayError => e
84
- @error = e.message
85
- render 'spree/api/errors/gateway_error', status: 422
86
- end
79
+ @payment.send("#{action}!", *args)
80
+ respond_with(@payment, default_template: :show)
87
81
  end
88
82
 
89
83
  def payment_params
@@ -12,6 +12,7 @@ module Spree
12
12
  @products = @products.distinct.page(params[:page]).per(params[:per_page])
13
13
  expires_in 15.minutes, :public => true
14
14
  headers['Surrogate-Control'] = "max-age=#{15.minutes}"
15
+ respond_with(@products)
15
16
  end
16
17
 
17
18
  def show
@@ -19,6 +20,7 @@ module Spree
19
20
  expires_in 15.minutes, :public => true
20
21
  headers['Surrogate-Control'] = "max-age=#{15.minutes}"
21
22
  headers['Surrogate-Key'] = "product_id=1"
23
+ respond_with(@product)
22
24
  end
23
25
 
24
26
  # Takes besides the products attributes either an array of variants or
@@ -8,12 +8,10 @@ module Spree
8
8
  @order = Spree::Order.find_by!(number: params[:shipment][:order_id])
9
9
  authorize! :read, @order
10
10
  authorize! :create, Shipment
11
- variant = Spree::Variant.find(params[:variant_id])
12
11
  quantity = params[:quantity].to_i
13
12
  @shipment = @order.shipments.create(stock_location_id: params[:stock_location_id])
14
13
  @order.contents.add(variant, quantity, nil, @shipment)
15
14
 
16
- @shipment.refresh_rates
17
15
  @shipment.save!
18
16
 
19
17
  respond_with(@shipment.reload, default_template: :show)
@@ -45,7 +43,6 @@ module Spree
45
43
  end
46
44
 
47
45
  def add
48
- variant = Spree::Variant.find(params[:variant_id])
49
46
  quantity = params[:quantity].to_i
50
47
 
51
48
  @shipment.order.contents.add(variant, quantity, nil, @shipment)
@@ -54,7 +51,6 @@ module Spree
54
51
  end
55
52
 
56
53
  def remove
57
- variant = Spree::Variant.find(params[:variant_id])
58
54
  quantity = params[:quantity].to_i
59
55
 
60
56
  @shipment.order.contents.remove(variant, quantity, @shipment)
@@ -77,6 +73,10 @@ module Spree
77
73
  {}
78
74
  end
79
75
  end
76
+
77
+ def variant
78
+ @variant ||= Spree::Variant.unscoped.find(params.fetch(:variant_id))
79
+ end
80
80
  end
81
81
  end
82
82
  end
@@ -46,8 +46,11 @@ module Spree
46
46
  end
47
47
 
48
48
  def user_params
49
- params.require(:user).permit(permitted_user_attributes)
49
+ params.require(:user).permit(PermittedAttributes.user_attributes |
50
+ [bill_address_attributes: PermittedAttributes.address_attributes,
51
+ ship_address_attributes: PermittedAttributes.address_attributes])
50
52
  end
53
+
51
54
  end
52
55
  end
53
56
  end
@@ -0,0 +1,7 @@
1
+ object false
2
+ child(@credit_cards => :credit_cards) do
3
+ extends "spree/api/credit_cards/show"
4
+ end
5
+ node(:count) { @credit_cards.count }
6
+ node(:current_page) { params[:page] || 1 }
7
+ node(:pages) { @credit_cards.total_pages }
@@ -1,2 +1,2 @@
1
1
  object false
2
- node(:error) { I18n.t(:gateway_error, :scope => "spree.api", :text => @error) }
2
+ node(:error) { I18n.t(:gateway_error, scope: "spree.api", text: @error) }
@@ -26,6 +26,11 @@ child :payments => :payments do
26
26
 
27
27
  child :source => :source do
28
28
  attributes *payment_source_attributes
29
+ if @current_user_roles.include?('admin')
30
+ attributes *payment_source_attributes.concat([:gateway_customer_profile_id, :gateway_payment_profile_id])
31
+ else
32
+ attributes *payment_source_attributes
33
+ end
29
34
  end
30
35
  end
31
36
 
@@ -40,4 +45,4 @@ end
40
45
  # Necessary for backend's order interface
41
46
  node :permissions do
42
47
  { can_update: current_ability.can?(:update, root_object) }
43
- end
48
+ end
data/config/routes.rb CHANGED
@@ -92,7 +92,11 @@ Spree::Core::Engine.add_routes do
92
92
  resources :taxons, only: [:index]
93
93
 
94
94
  resources :inventory_units, only: [:show, :update]
95
- resources :users
95
+
96
+ resources :users do
97
+ resources :credit_cards, only: [:index]
98
+ end
99
+
96
100
  resources :properties
97
101
  resources :stock_locations do
98
102
  resources :stock_movements
@@ -5,6 +5,7 @@ module Spree
5
5
  def sign_in_as_admin!
6
6
  let!(:current_api_user) do
7
7
  user = stub_model(Spree::LegacyUser)
8
+ user.stub_chain(:spree_roles, :pluck).and_return(["admin"])
8
9
  user.stub(:has_spree_role?).with("admin").and_return(true)
9
10
  user
10
11
  end
@@ -10,8 +10,9 @@ describe Spree::Api::BaseController do
10
10
 
11
11
  context "signed in as a user using an authentication extension" do
12
12
  before do
13
- controller.stub :try_spree_current_user => double(:email => "spree@example.com")
14
- Spree::Api::Config[:requires_authentication] = true
13
+ user = double(:email => "spree@example.com")
14
+ user.stub_chain :spree_roles, pluck: []
15
+ controller.stub :try_spree_current_user => user
15
16
  end
16
17
 
17
18
  it "can make a request" do
@@ -66,12 +67,13 @@ describe Spree::Api::BaseController do
66
67
 
67
68
  it 'handles exceptions' do
68
69
  subject.should_receive(:authenticate_user).and_return(true)
70
+ subject.should_receive(:load_user_roles).and_return(true)
69
71
  subject.should_receive(:index).and_raise(Exception.new("no joy"))
70
72
  get :index, :token => "fake_key"
71
73
  json_response.should == { "exception" => "no joy" }
72
74
  end
73
75
 
74
- it "maps symantec keys to nested_attributes keys" do
76
+ it "maps semantic keys to nested_attributes keys" do
75
77
  klass = double(:nested_attributes_options => { :line_items => {},
76
78
  :bill_address => {} })
77
79
  attributes = { 'line_items' => { :id => 1 },
@@ -82,4 +84,8 @@ describe Spree::Api::BaseController do
82
84
  mapped.has_key?('line_items_attributes').should be_true
83
85
  mapped.has_key?('name').should be_true
84
86
  end
87
+
88
+ it "lets a subclass override the product associations that are eager-loaded" do
89
+ controller.respond_to?(:product_includes, true).should be
90
+ end
85
91
  end
@@ -186,6 +186,17 @@ module Spree
186
186
  cc_errors.should include("Verification Value can't be blank")
187
187
  end
188
188
 
189
+ it "allow users to reuse a credit card" do
190
+ order.update_column(:state, "payment")
191
+ credit_card = create(:credit_card, user_id: order.user_id, payment_method_id: @payment_method.id)
192
+
193
+ api_put :update, :id => order.to_param, :order_token => order.guest_token,
194
+ :order => { :existing_card => credit_card.id }
195
+
196
+ expect(response.status).to eq 200
197
+ expect(order.credit_cards).to match_array [credit_card]
198
+ end
199
+
189
200
  it "can transition from confirm to complete" do
190
201
  order.update_column(:state, "confirm")
191
202
  Spree::Order.any_instance.stub(:payment_required? => false)
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Api::CreditCardsController 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
+ user.stub(: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
+ response.status.should == 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
+ response.status.should == 200
41
+ json_response["pages"].should == 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
+ response.status.should == 200
48
+ json_response["pages"].should == 1
49
+ json_response["current_page"].should == 1
50
+ json_response["credit_cards"].length.should == 1
51
+ json_response["credit_cards"].first["id"].should == 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
+ response.status.should == 404
67
+ end
68
+
69
+ it "can view own credit cards" do
70
+ api_get :index, user_id: normal_user.id
71
+
72
+ response.status.should == 200
73
+ json_response["pages"].should == 1
74
+ json_response["current_page"].should == 1
75
+ json_response["credit_cards"].length.should == 1
76
+ json_response["credit_cards"].first["id"].should == card.id
77
+ end
78
+ end
79
+ end
80
+ end
@@ -42,11 +42,10 @@ module Spree
42
42
  end
43
43
 
44
44
  context "the current api user is not persisted" do
45
- let(:current_api_user) { double(persisted?: false) }
45
+ let(:current_api_user) { Spree.user_class.new }
46
46
 
47
47
  it "returns a 401" do
48
48
  api_get :mine
49
-
50
49
  response.status.should == 401
51
50
  end
52
51
  end
@@ -73,6 +72,18 @@ module Spree
73
72
  response.status.should == 200
74
73
  json_response["orders"].length.should == 0
75
74
  end
75
+
76
+ it "returns orders in reverse chronological order" do
77
+ order2 = create(:order, line_items: [line_item], user: order.user)
78
+ order2.created_at.should > order.created_at
79
+
80
+ api_get :mine
81
+ response.status.should == 200
82
+ json_response["pages"].should == 1
83
+ json_response["orders"].length.should == 2
84
+ json_response["orders"][0]["number"].should == order2.number
85
+ json_response["orders"][1]["number"].should == order.number
86
+ end
76
87
  end
77
88
 
78
89
  it "can view their own order" do
@@ -120,6 +131,7 @@ module Spree
120
131
 
121
132
  it "can view an order" do
122
133
  user = mock_model(Spree::LegacyUser)
134
+ user.stub_chain(:spree_roles, :pluck).and_return(["bar"])
123
135
  user.stub(:has_spree_role?).with('bar').and_return(true)
124
136
  user.stub(:has_spree_role?).with('admin').and_return(false)
125
137
  controller.stub try_spree_current_user: user
@@ -195,11 +207,15 @@ module Spree
195
207
  end
196
208
 
197
209
  context "admin user imports order" do
198
- before { current_api_user.stub has_spree_role?: true }
210
+ before do
211
+ current_api_user.stub has_spree_role?: true
212
+ current_api_user.stub_chain :spree_roles, pluck: ["admin"]
213
+ end
199
214
 
200
- it "sets channel" do
201
- api_post :create, :order => { channel: "amazon" }
202
- expect(json_response['channel']).to eq "amazon"
215
+ it "is able to set any default unpermitted attribute" do
216
+ api_post :create, :order => { number: "WOW" }
217
+ expect(response.status).to eq 201
218
+ expect(json_response['number']).to eq "WOW"
203
219
  end
204
220
  end
205
221
 
@@ -414,7 +430,7 @@ module Spree
414
430
  adjustment['amount'].should == "5.0"
415
431
  end
416
432
 
417
- it "lists payments source" do
433
+ it "lists payments source without gateway info" do
418
434
  order.payments.push payment = create(:payment)
419
435
  api_get :show, :id => order.to_param
420
436
 
@@ -424,6 +440,8 @@ module Spree
424
440
  expect(source[:last_digits]).to eq payment.source.last_digits
425
441
  expect(source[:month].to_i).to eq payment.source.month
426
442
  expect(source[:year].to_i).to eq payment.source.year
443
+ expect(source.has_key?(:gateway_customer_profile_id)).to be false
444
+ expect(source.has_key?(:gateway_payment_profile_id)).to be false
427
445
  end
428
446
 
429
447
  context "when in delivery" do
@@ -435,8 +453,9 @@ module Spree
435
453
  end
436
454
 
437
455
  before do
456
+ order.bill_address = FactoryGirl.create(:address)
438
457
  order.ship_address = FactoryGirl.create(:address)
439
- order.state = 'delivery'
458
+ order.next!
440
459
  order.save
441
460
  end
442
461
 
@@ -520,6 +539,20 @@ module Spree
520
539
  after { ActionController::Base.perform_caching = false }
521
540
  end
522
541
 
542
+ it "lists payments source with gateway info" do
543
+ order.payments.push payment = create(:payment)
544
+ api_get :show, :id => order.to_param
545
+
546
+ source = json_response[:payments].first[:source]
547
+ expect(source[:name]).to eq payment.source.name
548
+ expect(source[:cc_type]).to eq payment.source.cc_type
549
+ expect(source[:last_digits]).to eq payment.source.last_digits
550
+ expect(source[:month].to_i).to eq payment.source.month
551
+ expect(source[:year].to_i).to eq payment.source.year
552
+ expect(source[:gateway_customer_profile_id]).to eq payment.source.gateway_customer_profile_id
553
+ expect(source[:gateway_payment_profile_id]).to eq payment.source.gateway_payment_profile_id
554
+ end
555
+
523
556
  context "with two orders" do
524
557
  before { create(:order) }
525
558
 
@@ -562,6 +595,13 @@ module Spree
562
595
  end
563
596
 
564
597
  context "creation" do
598
+ it "can create an order without any parameters" do
599
+ lambda { api_post :create }.should_not raise_error
600
+ response.status.should == 201
601
+ order = Order.last
602
+ json_response["state"].should == "cart"
603
+ end
604
+
565
605
  it "can arbitrarily set the line items price" do
566
606
  api_post :create, :order => {
567
607
  :line_items => {
@@ -570,10 +610,16 @@ module Spree
570
610
  }
571
611
  }
572
612
  }
573
-
574
613
  expect(response.status).to eq 201
575
614
  expect(Order.last.line_items.first.price.to_f).to eq(33.0)
576
615
  end
616
+
617
+ it "can set the user_id for the order" do
618
+ user = Spree.user_class.create
619
+ api_post :create, :order => { user_id: user.id }
620
+ expect(response.status).to eq 201
621
+ json_response["user_id"].should == user.id
622
+ end
577
623
  end
578
624
 
579
625
  context "updating" do
@@ -140,7 +140,8 @@ module Spree
140
140
 
141
141
  it "returns a 422 status" do
142
142
  response.status.should == 422
143
- json_response["error"].should == "There was a problem with the payment gateway: Could not authorize card"
143
+ expect(json_response["error"]).to eq "Invalid resource. Please fix errors and try again."
144
+ expect(json_response["errors"]["base"][0]).to eq "Could not authorize card"
144
145
  end
145
146
 
146
147
  it "does not raise a stack level error" do
@@ -166,7 +167,8 @@ module Spree
166
167
  it "returns a 422 status" do
167
168
  api_put :capture, :id => payment.to_param
168
169
  response.status.should == 422
169
- json_response["error"].should == "There was a problem with the payment gateway: Insufficient funds"
170
+ expect(json_response["error"]).to eq "Invalid resource. Please fix errors and try again."
171
+ expect(json_response["errors"]["base"][0]).to eq "Insufficient funds"
170
172
  end
171
173
  end
172
174
  end
@@ -187,30 +189,31 @@ module Spree
187
189
  it "returns a 422 status" do
188
190
  api_put :purchase, :id => payment.to_param
189
191
  response.status.should == 422
190
- json_response["error"].should == "There was a problem with the payment gateway: Insufficient funds"
192
+ expect(json_response["error"]).to eq "Invalid resource. Please fix errors and try again."
193
+ expect(json_response["errors"]["base"][0]).to eq "Insufficient funds"
191
194
  end
192
195
  end
193
196
  end
194
197
 
195
198
  context "voiding" do
196
199
  it "can void" do
197
- api_put :void, :id => payment.to_param
198
- response.status.should == 200
199
- payment.reload.state.should == "void"
200
+ api_put :void, id: payment.to_param
201
+ expect(response.status).to eq 200
202
+ expect(payment.reload.state).to eq "void"
200
203
  end
201
204
 
202
205
  context "voiding fails" do
203
206
  before do
204
- fake_response = double(:success? => false, :to_s => "NO REFUNDS")
207
+ fake_response = double(success?: false, to_s: "NO REFUNDS")
205
208
  Spree::Gateway::Bogus.any_instance.should_receive(:void).and_return(fake_response)
206
209
  end
207
210
 
208
211
  it "returns a 422 status" do
209
- api_put :void, :id => payment.to_param
210
- response.status.should == 422
211
- json_response["error"].should == "There was a problem with the payment gateway: NO REFUNDS"
212
-
213
- payment.reload.state.should == "checkout"
212
+ api_put :void, id: payment.to_param
213
+ expect(response.status).to eq 422
214
+ expect(json_response["error"]).to eq "Invalid resource. Please fix errors and try again."
215
+ expect(json_response["errors"]["base"][0]).to eq "NO REFUNDS"
216
+ expect(payment.reload.state).to eq "checkout"
214
217
  end
215
218
  end
216
219
  end
@@ -236,7 +239,8 @@ module Spree
236
239
  Spree::Gateway::Bogus.any_instance.should_receive(:credit).and_return(fake_response)
237
240
  api_put :credit, :id => payment.to_param
238
241
  response.status.should == 422
239
- json_response["error"].should == "There was a problem with the payment gateway: NO CREDIT FOR YOU"
242
+ expect(json_response["error"]).to eq "Invalid resource. Please fix errors and try again."
243
+ expect(json_response["errors"]["base"][0]).to eq "NO CREDIT FOR YOU"
240
244
  end
241
245
 
242
246
  it "cannot credit over credit_allowed limit" do
@@ -6,7 +6,7 @@ module Spree
6
6
  render_views
7
7
 
8
8
  let!(:product) { create(:product) }
9
- let!(:inactive_product) { create(:product, :available_on => Time.now.tomorrow, :name => "inactive") }
9
+ let!(:inactive_product) { create(:product, available_on: Time.now.tomorrow, name: "inactive") }
10
10
  let(:base_attributes) { Api::ApiHelpers.product_attributes }
11
11
  let(:show_attributes) { base_attributes.dup.push(:has_variants) }
12
12
  let(:new_attributes) { base_attributes }
@@ -67,6 +67,34 @@ module Spree
67
67
  json_response["per_page"].should == Kaminari.config.default_per_page
68
68
  end
69
69
 
70
+ context "specifying a rabl template for a custom action" do
71
+ before do
72
+ Spree::Api::ProductsController.class_eval do
73
+ def custom_show
74
+ @product = find_product(params[:id])
75
+ respond_with(@product)
76
+ end
77
+ end
78
+ end
79
+
80
+ it "uses the specified custom template through the request header" do
81
+ request.headers['X-Spree-Template'] = 'show'
82
+ api_get :custom_show, :id => product.id
83
+ response.should render_template('spree/api/products/show')
84
+ end
85
+
86
+ it "uses the specified custom template through the template URL parameter" do
87
+ api_get :custom_show, :id => product.id, :template => 'show'
88
+ response.should render_template('spree/api/products/show')
89
+ end
90
+
91
+ it "falls back to the default template if the specified template does not exist" do
92
+ request.headers['X-Spree-Template'] = 'invoice'
93
+ api_get :show, :id => product.id
94
+ response.should render_template('spree/api/products/show')
95
+ end
96
+ end
97
+
70
98
  context "product has more than one price" do
71
99
  before { product.master.prices.create currency: "EUR", amount: 22 }
72
100
 
@@ -360,7 +388,7 @@ module Spree
360
388
  end
361
389
 
362
390
  it "can create new variants on a product" do
363
- api_put :update, :id => product.to_param, :product => { :variants => [attributes_for_variant, attributes_for_variant] }
391
+ api_put :update, :id => product.to_param, :product => { :variants => [attributes_for_variant, attributes_for_variant.merge(sku: "ABC-#{Kernel.rand(9999)}")] }
364
392
  expect(response.status).to eq 200
365
393
  expect(json_response['variants'].count).to eq(2) # 2 variants
366
394
 
@@ -84,7 +84,16 @@ describe Spree::Api::ShipmentsController do
84
84
  api_put :remove, { variant_id: variant.to_param, quantity: 1 }
85
85
  response.status.should == 200
86
86
  json_response['manifest'].detect { |h| h['variant']['id'] == variant.id }["quantity"].should == 1
87
- end
87
+ end
88
+
89
+ it 'removes a destroyed variant from a shipment' do
90
+ order.contents.add(variant, 2)
91
+ variant.destroy
92
+
93
+ api_put :remove, { variant_id: variant.to_param, quantity: 1 }
94
+ response.status.should == 200
95
+ json_response['manifest'].detect { |h| h['variant']['id'] == variant.id }["quantity"].should == 1
96
+ end
88
97
  end
89
98
 
90
99
  context "can transition a shipment from ready to ship" do
@@ -55,7 +55,7 @@ module Spree
55
55
  it 'cannot list of stock items' do
56
56
  api_get :index, stock_location_id: stock_location.to_param
57
57
  json_response['stock_items'].first.should have_attributes(attributes)
58
- json_response['stock_items'].first['variant']['sku'].should eq 'ABC'
58
+ json_response['stock_items'].first['variant']['sku'].should include 'ABC'
59
59
  end
60
60
 
61
61
  it 'requires a stock_location_id to be passed as a parameter' do
@@ -139,4 +139,3 @@ module Spree
139
139
  end
140
140
  end
141
141
  end
142
-
@@ -46,8 +46,33 @@ module Spree
46
46
  end
47
47
 
48
48
  it "can update own details" do
49
- api_put :update, :id => user.id, :user => { :email => "mine@example.com" }
50
- json_response['email'].should eq 'mine@example.com'
49
+ country = create(:country)
50
+ api_put :update, id: user.id, user: {
51
+ email: "mine@example.com",
52
+ bill_address_attributes: {
53
+ first_name: 'First',
54
+ last_name: 'Last',
55
+ address1: '1 Test Rd',
56
+ city: 'City',
57
+ country_id: country.id,
58
+ state_id: 1,
59
+ zipcode: '55555',
60
+ phone: '5555555555'
61
+ },
62
+ ship_address_attributes: {
63
+ first_name: 'First',
64
+ last_name: 'Last',
65
+ address1: '1 Test Rd',
66
+ city: 'City',
67
+ country_id: country.id,
68
+ state_id: 1,
69
+ zipcode: '55555',
70
+ phone: '5555555555'
71
+ }
72
+ }
73
+ expect(json_response['email']).to eq 'mine@example.com'
74
+ expect(json_response['bill_address']).to_not be_nil
75
+ expect(json_response['ship_address']).to_not be_nil
51
76
  end
52
77
 
53
78
  it "cannot update other users details" do
@@ -180,6 +180,5 @@ module Spree
180
180
  lambda { Spree::Variant.find(variant.id) }.should raise_error(ActiveRecord::RecordNotFound)
181
181
  end
182
182
  end
183
-
184
183
  end
185
184
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 2.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Bigg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-01 00:00:00.000000000 Z
11
+ date: 2014-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: spree_core
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 2.3.1
19
+ version: 2.3.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 2.3.1
26
+ version: 2.3.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rabl
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -70,6 +70,7 @@ files:
70
70
  - app/controllers/spree/api/classifications_controller.rb
71
71
  - app/controllers/spree/api/config_controller.rb
72
72
  - app/controllers/spree/api/countries_controller.rb
73
+ - app/controllers/spree/api/credit_cards_controller.rb
73
74
  - app/controllers/spree/api/images_controller.rb
74
75
  - app/controllers/spree/api/inventory_units_controller.rb
75
76
  - app/controllers/spree/api/line_items_controller.rb
@@ -100,6 +101,7 @@ files:
100
101
  - app/views/spree/api/config/show.v1.rabl
101
102
  - app/views/spree/api/countries/index.v1.rabl
102
103
  - app/views/spree/api/countries/show.v1.rabl
104
+ - app/views/spree/api/credit_cards/index.v1.rabl
103
105
  - app/views/spree/api/credit_cards/show.v1.rabl
104
106
  - app/views/spree/api/errors/gateway_error.v1.rabl
105
107
  - app/views/spree/api/errors/invalid_api_key.v1.rabl
@@ -202,6 +204,7 @@ files:
202
204
  - spec/controllers/spree/api/classifications_controller_spec.rb
203
205
  - spec/controllers/spree/api/config_controller_spec.rb
204
206
  - spec/controllers/spree/api/countries_controller_spec.rb
207
+ - spec/controllers/spree/api/credit_cards_controller_spec.rb
205
208
  - spec/controllers/spree/api/images_controller_spec.rb
206
209
  - spec/controllers/spree/api/inventory_units_controller_spec.rb
207
210
  - spec/controllers/spree/api/line_items_controller_spec.rb
@@ -264,6 +267,7 @@ test_files:
264
267
  - spec/controllers/spree/api/classifications_controller_spec.rb
265
268
  - spec/controllers/spree/api/config_controller_spec.rb
266
269
  - spec/controllers/spree/api/countries_controller_spec.rb
270
+ - spec/controllers/spree/api/credit_cards_controller_spec.rb
267
271
  - spec/controllers/spree/api/images_controller_spec.rb
268
272
  - spec/controllers/spree/api/inventory_units_controller_spec.rb
269
273
  - spec/controllers/spree/api/line_items_controller_spec.rb