spree_api 2.1.1 → 2.1.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.
- 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"
|