spree_api 2.3.1 → 2.3.2

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 (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