spree_api 2.1.1 → 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/app/controllers/spree/api/base_controller.rb +10 -1
- data/app/controllers/spree/api/countries_controller.rb +2 -0
- data/app/controllers/spree/api/orders_controller.rb +9 -2
- data/app/controllers/spree/api/payments_controller.rb +13 -2
- data/app/controllers/spree/api/states_controller.rb +2 -0
- data/app/controllers/spree/api/stock_items_controller.rb +2 -1
- data/app/controllers/spree/api/stock_locations_controller.rb +1 -0
- data/app/controllers/spree/api/stock_movements_controller.rb +1 -0
- data/app/helpers/spree/api/api_helpers.rb +2 -3
- data/app/models/spree/option_value_decorator.rb +4 -0
- data/app/models/spree/order_decorator.rb +25 -18
- data/app/views/spree/api/payments/credit_over_limit.v1.rabl +1 -1
- data/app/views/spree/api/payments/new.v1.rabl +0 -1
- data/app/views/spree/api/payments/update_forbidden.v1.rabl +2 -0
- data/config/locales/en.yml +3 -1
- data/config/routes.rb +1 -1
- data/lib/spree/api/responders/rabl_template.rb +1 -1
- data/spec/controllers/spree/api/base_controller_spec.rb +1 -1
- data/spec/controllers/spree/api/checkouts_controller_spec.rb +14 -0
- data/spec/controllers/spree/api/orders_controller_spec.rb +84 -17
- data/spec/controllers/spree/api/payments_controller_spec.rb +118 -77
- data/spec/controllers/spree/api/stock_items_controller_spec.rb +62 -26
- data/spec/controllers/spree/api/stock_locations_controller_spec.rb +56 -29
- data/spec/controllers/spree/api/stock_movements_controller_spec.rb +51 -27
- data/spec/controllers/spree/api/zones_controller_spec.rb +2 -2
- data/spec/models/spree/order_spec.rb +71 -4
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b88f0bb66f6241fa750c60df09e559515380ff9
|
4
|
+
data.tar.gz: c8c8111f3b16f720c3219105faf7d5a912dc5c45
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c330a76aaf9c02fdfc52aa1c5da7cec9e1d20bd4eb607ae622dd7b9c3898a389b9f6955c8b0d0f52fda7ae02c3e052e100863fcd5535a80d98897b2cd9753e9
|
7
|
+
data.tar.gz: 9676ad30355100421c95579e8089ef471f0bd267327887ab9582f081ea5731ca0c7034cb68d37139528e5325bb03419b02f3eb8fbf1b14153de34935a4cd72ff
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
## Spree 2.1.2 ##
|
2
|
+
|
3
|
+
* States and countries endpoints now do not require authentication, even if it is forced with the `requires_authentication` setting. This is so the frontend's checkout address page can still work.
|
4
|
+
|
5
|
+
*Ryan Bigg*
|
6
|
+
|
7
|
+
* You can now assign a location to a shipment when creating it through the orders API. f3ef2e1d46bc972442acbbcaae928e6ef2dc0eb5
|
8
|
+
|
9
|
+
*Washington Luiz*
|
10
|
+
|
11
|
+
* Stock Items, Stock Movements and Stock Locations are now invisible to non-admin users.
|
12
|
+
|
13
|
+
*Ryan Bigg*
|
14
|
+
|
15
|
+
* Fixed issue where X-Spree-Token header was being ignored. #3798
|
16
|
+
|
17
|
+
*Washington Luiz*
|
18
|
+
|
1
19
|
## Spree 2.1.0 ##
|
2
20
|
|
3
21
|
* The Products API endpoint now returns an additional key called `shipping_category_id`, and also requires `shipping_category_id` on create.
|
@@ -45,6 +45,15 @@ module Spree
|
|
45
45
|
end.with_indifferent_access
|
46
46
|
end
|
47
47
|
|
48
|
+
# users should be able to set price when importing orders via api
|
49
|
+
def permitted_line_item_attributes
|
50
|
+
if current_api_user.has_spree_role?("admin")
|
51
|
+
super << [:price]
|
52
|
+
else
|
53
|
+
super
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
48
57
|
private
|
49
58
|
|
50
59
|
def set_content_type
|
@@ -109,7 +118,7 @@ module Spree
|
|
109
118
|
end
|
110
119
|
|
111
120
|
def api_key
|
112
|
-
request.headers
|
121
|
+
request.headers["X-Spree-Token"] || params[:token]
|
113
122
|
end
|
114
123
|
helper_method :api_key
|
115
124
|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Spree
|
2
2
|
module Api
|
3
3
|
class CountriesController < Spree::Api::BaseController
|
4
|
+
skip_before_filter :check_for_user_or_api_key
|
5
|
+
skip_before_filter :authenticate_user
|
4
6
|
|
5
7
|
def index
|
6
8
|
@countries = Country.accessible_by(current_ability, :read).ransack(params[:q]).result.
|
@@ -50,7 +50,11 @@ module Spree
|
|
50
50
|
# hence the use of the update_line_items method, defined within order_decorator.rb.
|
51
51
|
order_params.delete("line_items_attributes")
|
52
52
|
if @order.update_attributes(order_params)
|
53
|
-
|
53
|
+
line_item_attributes = params[:order][:line_items].map do |id, attributes|
|
54
|
+
[id, attributes.slice(*permitted_line_item_attributes)]
|
55
|
+
end
|
56
|
+
line_item_attributes = Hash[line_item_attributes].delete_if { |k,v| v.empty? }
|
57
|
+
@order.update_line_items(line_item_attributes)
|
54
58
|
@order.line_items.reload
|
55
59
|
@order.update!
|
56
60
|
respond_with(@order, default_template: :show)
|
@@ -72,6 +76,10 @@ module Spree
|
|
72
76
|
end
|
73
77
|
end
|
74
78
|
|
79
|
+
def permitted_order_attributes
|
80
|
+
super << [:import]
|
81
|
+
end
|
82
|
+
|
75
83
|
def next!(options={})
|
76
84
|
if @order.valid? && @order.next
|
77
85
|
render :show, status: options[:status] || 200
|
@@ -88,7 +96,6 @@ module Spree
|
|
88
96
|
def before_delivery
|
89
97
|
@order.create_proposed_shipments
|
90
98
|
end
|
91
|
-
|
92
99
|
end
|
93
100
|
end
|
94
101
|
end
|
@@ -3,7 +3,7 @@ module Spree
|
|
3
3
|
class PaymentsController < Spree::Api::BaseController
|
4
4
|
|
5
5
|
before_filter :find_order
|
6
|
-
before_filter :find_payment, only: [:show, :authorize, :purchase, :capture, :void, :credit]
|
6
|
+
before_filter :find_payment, only: [:update, :show, :authorize, :purchase, :capture, :void, :credit]
|
7
7
|
|
8
8
|
def index
|
9
9
|
@payments = @order.payments.ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
|
@@ -24,6 +24,17 @@ module Spree
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
def update
|
28
|
+
authorize! params[:action], @payment
|
29
|
+
if ! @payment.pending?
|
30
|
+
render 'update_forbidden', status: 403
|
31
|
+
elsif @payment.update_attributes(payment_params)
|
32
|
+
respond_with(@payment, default_template: :show)
|
33
|
+
else
|
34
|
+
invalid_resource!(@payment)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
27
38
|
def show
|
28
39
|
respond_with(@payment)
|
29
40
|
end
|
@@ -46,7 +57,7 @@ module Spree
|
|
46
57
|
|
47
58
|
def credit
|
48
59
|
if params[:amount].to_f > @payment.credit_allowed
|
49
|
-
render '
|
60
|
+
render 'credit_over_limit', status: 422
|
50
61
|
else
|
51
62
|
perform_payment_action(:credit, params[:amount])
|
52
63
|
end
|
@@ -63,7 +63,8 @@ module Spree
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def scope
|
66
|
-
|
66
|
+
includes = {:variant => [{ :option_values => :option_type }, :product] }
|
67
|
+
@stock_location.stock_items.accessible_by(current_ability, :read).includes(includes)
|
67
68
|
end
|
68
69
|
|
69
70
|
def stock_item_params
|
@@ -2,6 +2,7 @@ module Spree
|
|
2
2
|
module Api
|
3
3
|
class StockLocationsController < Spree::Api::BaseController
|
4
4
|
def index
|
5
|
+
authorize! :read, StockLocation
|
5
6
|
@stock_locations = StockLocation.accessible_by(current_ability, :read).order('name ASC').ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
|
6
7
|
respond_with(@stock_locations)
|
7
8
|
end
|
@@ -28,7 +28,7 @@ module Spree
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def option_value_attributes
|
31
|
-
[:id, :name, :presentation, :option_type_name, :option_type_id]
|
31
|
+
[:id, :name, :presentation, :option_type_name, :option_type_id, :option_type_presentation]
|
32
32
|
end
|
33
33
|
|
34
34
|
def order_attributes
|
@@ -44,7 +44,7 @@ module Spree
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def payment_attributes
|
47
|
-
[:id, :source_type, :source_id, :amount, :payment_method_id, :response_code, :state, :avs_response, :created_at, :updated_at]
|
47
|
+
[:id, :source_type, :source_id, :amount, :display_amount, :payment_method_id, :response_code, :state, :avs_response, :created_at, :updated_at]
|
48
48
|
end
|
49
49
|
|
50
50
|
def payment_method_attributes
|
@@ -113,4 +113,3 @@ module Spree
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
end
|
116
|
-
|
@@ -1,28 +1,34 @@
|
|
1
1
|
Spree::Order.class_eval do
|
2
2
|
def self.build_from_api(user, params)
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
begin
|
4
|
+
ensure_country_id_from_api params[:ship_address_attributes]
|
5
|
+
ensure_state_id_from_api params[:ship_address_attributes]
|
6
|
+
ensure_country_id_from_api params[:bill_address_attributes]
|
7
|
+
ensure_state_id_from_api params[:bill_address_attributes]
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
order = create!
|
10
|
+
order.associate_user!(user)
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
order.create_shipments_from_api params.delete(:shipments_attributes) || []
|
13
|
+
order.create_line_items_from_api params.delete(:line_items_attributes) || {}
|
14
|
+
order.create_adjustments_from_api params.delete(:adjustments_attributes) || []
|
15
|
+
order.create_payments_from_api params.delete(:payments_attributes) || []
|
16
|
+
order.complete_from_api params.delete(:completed_at)
|
14
17
|
|
15
|
-
|
16
|
-
|
18
|
+
destroy_automatic_taxes_on_import(order, params)
|
19
|
+
order.update_attributes!(params)
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
order.reload
|
22
|
+
rescue Exception => e
|
23
|
+
order.destroy if order && order.persisted?
|
24
|
+
raise e.message
|
25
|
+
end
|
26
|
+
end
|
23
27
|
|
24
|
-
|
25
|
-
|
28
|
+
def self.destroy_automatic_taxes_on_import(order, params)
|
29
|
+
if params.delete :import
|
30
|
+
order.adjustments.tax.destroy_all
|
31
|
+
end
|
26
32
|
end
|
27
33
|
|
28
34
|
def complete_from_api(completed_at)
|
@@ -37,6 +43,7 @@ Spree::Order.class_eval do
|
|
37
43
|
begin
|
38
44
|
shipment = shipments.build
|
39
45
|
shipment.tracking = s[:tracking]
|
46
|
+
shipment.stock_location = Spree::StockLocation.find_by_name!(s[:stock_location])
|
40
47
|
|
41
48
|
inventory_units = s[:inventory_units] || []
|
42
49
|
inventory_units.each do |iu|
|
@@ -1,2 +1,2 @@
|
|
1
1
|
object false
|
2
|
-
node(:error) { I18n.t(:credit_over_limit, :limit => @payment.credit_allowed, :scope => 'spree.api') }
|
2
|
+
node(:error) { I18n.t(:credit_over_limit, :limit => @payment.credit_allowed, :scope => 'spree.api.payment') }
|
data/config/locales/en.yml
CHANGED
@@ -7,7 +7,6 @@ en:
|
|
7
7
|
invalid_resource: "Invalid resource. Please fix errors and try again."
|
8
8
|
resource_not_found: "The resource you were looking for could not be found."
|
9
9
|
gateway_error: "There was a problem with the payment gateway: %{text}"
|
10
|
-
credit_over_limit: "This payment can only be credited up to %{limit}. Please specify an amount less than or equal to this number."
|
11
10
|
access: "API Access"
|
12
11
|
key: "Key"
|
13
12
|
clear_key: "Clear key"
|
@@ -19,6 +18,9 @@ en:
|
|
19
18
|
order:
|
20
19
|
could_not_transition: "The order could not be transitioned. Please fix the errors and try again."
|
21
20
|
invalid_shipping_method: "Invalid shipping method specified."
|
21
|
+
payment:
|
22
|
+
credit_over_limit: "This payment can only be credited up to %{limit}. Please specify an amount less than or equal to this number."
|
23
|
+
update_forbidden: "This payment cannot be updated because it is %{state}."
|
22
24
|
shipment:
|
23
25
|
cannot_ready: "Cannot ready shipment."
|
24
26
|
stock_location_required: "A stock_location_id parameter must be provided in order to retrieve stock movements."
|
data/config/routes.rb
CHANGED
@@ -14,7 +14,7 @@ module Spree
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def template
|
17
|
-
request.headers
|
17
|
+
request.headers['X-Spree-Template'] || controller.params[:template] || options[:default_template]
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -29,7 +29,7 @@ describe Spree::Api::BaseController do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
it "with an invalid API key" do
|
32
|
-
request.
|
32
|
+
request.headers["X-Spree-Token"] = "fake_key"
|
33
33
|
get :index, {}
|
34
34
|
json_response.should == { "error" => "Invalid API key (fake_key) specified." }
|
35
35
|
response.status.should == 401
|
@@ -29,6 +29,12 @@ module Spree
|
|
29
29
|
json_response['number'].should be_present
|
30
30
|
response.status.should == 201
|
31
31
|
end
|
32
|
+
|
33
|
+
it "assigns email when creating a new order" do
|
34
|
+
api_post :create, :order => { :email => "guest@spreecommerce.com" }
|
35
|
+
expect(json_response['email']).not_to eq controller.current_api_user
|
36
|
+
expect(json_response['email']).to eq "guest@spreecommerce.com"
|
37
|
+
end
|
32
38
|
end
|
33
39
|
|
34
40
|
context "PUT 'update'" do
|
@@ -176,6 +182,14 @@ module Spree
|
|
176
182
|
response.status.should == 200
|
177
183
|
end
|
178
184
|
|
185
|
+
# Regression test for #3784
|
186
|
+
it "can update the special instructions for an order" do
|
187
|
+
instructions = "Don't drop it. (Please)"
|
188
|
+
api_put :update, :id => order.to_param, :order_token => order.token,
|
189
|
+
:order => { :special_instructions => instructions }
|
190
|
+
expect(json_response['special_instructions']).to eql(instructions)
|
191
|
+
end
|
192
|
+
|
179
193
|
context "as an admin" do
|
180
194
|
sign_in_as_admin!
|
181
195
|
it "can assign a user to the order" do
|
@@ -5,6 +5,8 @@ module Spree
|
|
5
5
|
render_views
|
6
6
|
|
7
7
|
let!(:order) { create(:order) }
|
8
|
+
let(:variant) { create(:variant) }
|
9
|
+
|
8
10
|
let(:attributes) { [:number, :item_total, :display_total, :total,
|
9
11
|
:state, :adjustment_total,
|
10
12
|
:user_id, :created_at, :updated_at,
|
@@ -12,6 +14,23 @@ module Spree
|
|
12
14
|
:payment_state, :email, :special_instructions,
|
13
15
|
:total_quantity, :display_item_total] }
|
14
16
|
|
17
|
+
let(:address_params) { { :country_id => Country.first.id, :state_id => State.first.id } }
|
18
|
+
|
19
|
+
let(:billing_address) { { :firstname => "Tiago", :lastname => "Motta", :address1 => "Av Paulista",
|
20
|
+
:city => "Sao Paulo", :zipcode => "1234567", :phone => "12345678",
|
21
|
+
:country_id => Country.first.id, :state_id => State.first.id} }
|
22
|
+
|
23
|
+
let(:shipping_address) { { :firstname => "Tiago", :lastname => "Motta", :address1 => "Av Paulista",
|
24
|
+
:city => "Sao Paulo", :zipcode => "1234567", :phone => "12345678",
|
25
|
+
:country_id => Country.first.id, :state_id => State.first.id} }
|
26
|
+
|
27
|
+
let!(:payment_method) { create(:payment_method) }
|
28
|
+
|
29
|
+
let(:current_api_user) do
|
30
|
+
user = Spree.user_class.new(:email => "spree@example.com")
|
31
|
+
user.generate_spree_api_key!
|
32
|
+
user
|
33
|
+
end
|
15
34
|
|
16
35
|
before do
|
17
36
|
stub_authentication!
|
@@ -68,22 +87,7 @@ module Spree
|
|
68
87
|
assert_unauthorized!
|
69
88
|
end
|
70
89
|
|
71
|
-
let(:address_params) { { :country_id => Country.first.id, :state_id => State.first.id } }
|
72
|
-
let(:billing_address) { { :firstname => "Tiago", :lastname => "Motta", :address1 => "Av Paulista",
|
73
|
-
:city => "Sao Paulo", :zipcode => "1234567", :phone => "12345678",
|
74
|
-
:country_id => Country.first.id, :state_id => State.first.id} }
|
75
|
-
let(:shipping_address) { { :firstname => "Tiago", :lastname => "Motta", :address1 => "Av Paulista",
|
76
|
-
:city => "Sao Paulo", :zipcode => "1234567", :phone => "12345678",
|
77
|
-
:country_id => Country.first.id, :state_id => State.first.id} }
|
78
|
-
let!(:payment_method) { create(:payment_method) }
|
79
|
-
let(:current_api_user) do
|
80
|
-
user = Spree.user_class.new(:email => "spree@example.com")
|
81
|
-
user.generate_spree_api_key!
|
82
|
-
user
|
83
|
-
end
|
84
|
-
|
85
90
|
it "can create an order" do
|
86
|
-
variant = create(:variant)
|
87
91
|
api_post :create, :order => { :line_items => { "0" => { :variant_id => variant.to_param, :quantity => 5 } } }
|
88
92
|
response.status.should == 201
|
89
93
|
order = Order.last
|
@@ -99,7 +103,6 @@ module Spree
|
|
99
103
|
|
100
104
|
# Regression test for #3404
|
101
105
|
it "can specify additional parameters for a line item" do
|
102
|
-
variant = create(:variant)
|
103
106
|
Order.should_receive(:create!).and_return(order = Spree::Order.new)
|
104
107
|
order.stub(:associate_user!)
|
105
108
|
order.stub_chain(:contents, :add).and_return(line_item = double('LineItem'))
|
@@ -116,9 +119,45 @@ module Spree
|
|
116
119
|
response.status.should == 201
|
117
120
|
end
|
118
121
|
|
122
|
+
it "cannot arbitrarily set the line items price" do
|
123
|
+
api_post :create, :order => {
|
124
|
+
:line_items => {
|
125
|
+
"0" => {
|
126
|
+
:price => 33.0, :variant_id => variant.to_param, :quantity => 5
|
127
|
+
}
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
expect(response.status).to eq 201
|
132
|
+
expect(Order.last.line_items.first.price.to_f).to eq(variant.price)
|
133
|
+
end
|
134
|
+
|
135
|
+
context "import" do
|
136
|
+
let(:tax_rate) { create(:tax_rate, amount: 0.05, calculator: Calculator::DefaultTax.create) }
|
137
|
+
let(:other_variant) { create(:variant) }
|
138
|
+
|
139
|
+
let(:order_params) do
|
140
|
+
{
|
141
|
+
:line_items => {
|
142
|
+
"0" => { :variant_id => variant.to_param, :quantity => 5 },
|
143
|
+
"1" => { :variant_id => other_variant.to_param, :quantity => 5 }
|
144
|
+
}
|
145
|
+
}
|
146
|
+
end
|
147
|
+
|
148
|
+
before { Zone.stub default_tax: tax_rate.zone }
|
149
|
+
|
150
|
+
it "doesnt persist any automatic tax adjustment" do
|
151
|
+
expect {
|
152
|
+
api_post :create, :order => order_params.merge(:import => true)
|
153
|
+
}.not_to change { Adjustment.count }
|
154
|
+
|
155
|
+
expect(response.status).to eq 201
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
119
159
|
# Regression test for #3404
|
120
160
|
it "does not update line item needlessly" do
|
121
|
-
variant = create(:variant)
|
122
161
|
Order.should_receive(:create!).and_return(order = Spree::Order.new)
|
123
162
|
order.stub(:associate_user!)
|
124
163
|
order.stub_chain(:contents, :add).and_return(line_item = double('LineItem'))
|
@@ -180,6 +219,19 @@ module Spree
|
|
180
219
|
json_response['line_items'].first['quantity'].should == 10
|
181
220
|
end
|
182
221
|
|
222
|
+
it "cannot change the price of an existing line item" do
|
223
|
+
api_put :update, :id => order.to_param, :order => {
|
224
|
+
:line_items => {
|
225
|
+
line_item.id => { :price => 0 }
|
226
|
+
}
|
227
|
+
}
|
228
|
+
|
229
|
+
response.status.should == 200
|
230
|
+
json_response['line_items'].count.should == 1
|
231
|
+
expect(json_response['line_items'].first['price'].to_f).to_not eq(0)
|
232
|
+
expect(json_response['line_items'].first['price'].to_f).to eq(line_item.variant.price)
|
233
|
+
end
|
234
|
+
|
183
235
|
it "can add billing address" do
|
184
236
|
api_put :update, :id => order.to_param, :order => { :bill_address_attributes => billing_address }
|
185
237
|
|
@@ -357,6 +409,21 @@ module Spree
|
|
357
409
|
end
|
358
410
|
end
|
359
411
|
|
412
|
+
context "creation" do
|
413
|
+
it "can arbitrarily set the line items price" do
|
414
|
+
api_post :create, :order => {
|
415
|
+
:line_items => {
|
416
|
+
"0" => {
|
417
|
+
:price => 33.0, :variant_id => variant.to_param, :quantity => 5
|
418
|
+
}
|
419
|
+
}
|
420
|
+
}
|
421
|
+
|
422
|
+
expect(response.status).to eq 201
|
423
|
+
expect(Order.last.line_items.first.price.to_f).to eq(33.0)
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
360
427
|
context "can cancel an order" do
|
361
428
|
before do
|
362
429
|
Spree::Config[:mails_from] = "spree@example.com"
|