spree_api 1.3.4 → 1.3.5
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/app/controllers/spree/api/orders_controller.rb +2 -0
- data/app/controllers/spree/api/products_controller.rb +18 -0
- data/app/helpers/spree/api/api_helpers.rb +1 -1
- data/app/models/spree/api_configuration.rb +1 -0
- data/app/models/spree/line_item_decorator.rb +1 -1
- data/app/models/spree/order_decorator.rb +23 -10
- data/db/migrate/20131017162334_add_index_to_user_spree_api_key.rb +7 -0
- data/spec/controllers/spree/api/orders_controller_spec.rb +54 -3
- data/spec/controllers/spree/api/products_controller_spec.rb +73 -2
- data/spec/models/spree/order_spec.rb +40 -13
- metadata +10 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f36fa5b9ac229e7e973c1c724fda3cf3e9cd50ad
|
4
|
+
data.tar.gz: 78a1596cc6c1ed5014fc22c65319c431cb6a08de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab336cf7a3b2b2c56070dd047fd1844c3abf8051431c8171d078534289f8274e323a9c6f85eae06132bf6427effc5fa67762b4c071660da4e7d02b552a2fc916
|
7
|
+
data.tar.gz: ec3c418cb4b1b6351d8cc879d27acab755e8c45f62900150203c8a6d7d8854507cc3199c63c210c47ee400553354556050c4aca371db63b3087f9f52a3d4aca7
|
@@ -56,6 +56,8 @@ module Spree
|
|
56
56
|
def sanitize_line_items(line_item_attributes)
|
57
57
|
return {} if line_item_attributes.blank?
|
58
58
|
line_item_attributes = line_item_attributes.map do |id, attributes|
|
59
|
+
attributes ||= id
|
60
|
+
|
59
61
|
# Faux Strong-Parameters code to strip price if user isn't an admin
|
60
62
|
if current_api_user.has_spree_role?("admin")
|
61
63
|
[id, attributes.slice(*Spree::LineItem.attr_accessible[:api])]
|
@@ -19,9 +19,27 @@ module Spree
|
|
19
19
|
def create
|
20
20
|
authorize! :create, Product
|
21
21
|
params[:product][:available_on] ||= Time.now
|
22
|
+
|
23
|
+
variants_attributes = params[:product].delete(:variants_attributes) || []
|
24
|
+
option_type_attributes = params[:product].delete(:option_types) || []
|
25
|
+
|
22
26
|
@product = Product.new(params[:product])
|
23
27
|
begin
|
24
28
|
if @product.save
|
29
|
+
variants_attributes.each do |variant_attribute|
|
30
|
+
variant = @product.variants.new
|
31
|
+
variant.update_attributes(variant_attribute)
|
32
|
+
end
|
33
|
+
|
34
|
+
option_type_attributes.each do |name|
|
35
|
+
option_type = OptionType.where(name: name).first_or_initialize do |option_type|
|
36
|
+
option_type.presentation = name
|
37
|
+
option_type.save!
|
38
|
+
end
|
39
|
+
|
40
|
+
@product.option_types << option_type unless @product.option_types.include?(option_type)
|
41
|
+
end
|
42
|
+
|
25
43
|
respond_with(@product, :status => 201, :default_template => :show)
|
26
44
|
else
|
27
45
|
invalid_resource!(@product)
|
@@ -33,7 +33,7 @@ module Spree
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def order_attributes
|
36
|
-
[:id, :number, :item_total, :total, :state, :adjustment_total, :user_id, :created_at, :updated_at, :completed_at, :payment_total, :shipment_state, :payment_state, :email, :special_instructions]
|
36
|
+
[:id, :number, :item_total, :total, :state, :adjustment_total, :user_id, :created_at, :updated_at, :completed_at, :payment_total, :shipment_state, :payment_state, :email, :special_instructions, :channel]
|
37
37
|
end
|
38
38
|
|
39
39
|
def line_item_attributes
|
@@ -1,4 +1,6 @@
|
|
1
1
|
Spree::Order.class_eval do
|
2
|
+
attr_accessible :channel, :as => :api_admin
|
3
|
+
|
2
4
|
def self.build_from_api(user, params)
|
3
5
|
begin
|
4
6
|
ensure_country_id_from_api params[:ship_address_attributes]
|
@@ -15,7 +17,12 @@ Spree::Order.class_eval do
|
|
15
17
|
order.complete_from_api params.delete(:completed_at)
|
16
18
|
|
17
19
|
destroy_automatic_taxes_on_import(order, params)
|
18
|
-
|
20
|
+
|
21
|
+
if user.has_spree_role? "admin"
|
22
|
+
order.update_attributes!(params, without_protection: true)
|
23
|
+
else
|
24
|
+
order.update_attributes!(params)
|
25
|
+
end
|
19
26
|
|
20
27
|
order.reload
|
21
28
|
rescue Exception => e
|
@@ -59,7 +66,7 @@ Spree::Order.class_eval do
|
|
59
66
|
shipment.adjustment.amount = s[:cost].to_f
|
60
67
|
shipment.adjustment.save
|
61
68
|
rescue Exception => e
|
62
|
-
raise "#{e.message} #{s}"
|
69
|
+
raise "Order import shipments: #{e.message} #{s}"
|
63
70
|
end
|
64
71
|
end
|
65
72
|
end
|
@@ -73,7 +80,7 @@ Spree::Order.class_eval do
|
|
73
80
|
payment.payment_method = Spree::PaymentMethod.find_by_name!(p[:payment_method])
|
74
81
|
payment.save!
|
75
82
|
rescue Exception => e
|
76
|
-
raise "#{e.message} #{p}"
|
83
|
+
raise "Order import payments: #{e.message} #{p}"
|
77
84
|
end
|
78
85
|
end
|
79
86
|
end
|
@@ -84,14 +91,14 @@ Spree::Order.class_eval do
|
|
84
91
|
line_item = line_items_hash[k]
|
85
92
|
self.class.ensure_variant_id_from_api(line_item)
|
86
93
|
|
87
|
-
item
|
94
|
+
item = self.add_variant(Spree::Variant.find(line_item[:variant_id]), line_item[:quantity].to_i)
|
88
95
|
|
89
96
|
if line_item.key? :price
|
90
97
|
item.price = line_item[:price]
|
91
98
|
item.save!
|
92
99
|
end
|
93
100
|
rescue Exception => e
|
94
|
-
raise "#{e.message} #{line_item}"
|
101
|
+
raise "Order import line items: #{e.message} #{line_item}"
|
95
102
|
end
|
96
103
|
end
|
97
104
|
end
|
@@ -104,7 +111,7 @@ Spree::Order.class_eval do
|
|
104
111
|
adjustment.locked = true
|
105
112
|
adjustment.save!
|
106
113
|
rescue Exception => e
|
107
|
-
raise "#{e.message} #{a}"
|
114
|
+
raise "Order import adjustments: #{e.message} #{a}"
|
108
115
|
end
|
109
116
|
end
|
110
117
|
end
|
@@ -116,7 +123,7 @@ Spree::Order.class_eval do
|
|
116
123
|
hash.delete(:sku)
|
117
124
|
end
|
118
125
|
rescue Exception => e
|
119
|
-
raise "#{e.message} #{hash}"
|
126
|
+
raise "Ensure order import variant: #{e.message} #{hash}"
|
120
127
|
end
|
121
128
|
end
|
122
129
|
|
@@ -139,7 +146,7 @@ Spree::Order.class_eval do
|
|
139
146
|
address[:country_id] = Spree::Country.where(search).first!.id
|
140
147
|
|
141
148
|
rescue Exception => e
|
142
|
-
raise "#{e.message} #{search}"
|
149
|
+
raise "Ensure order import address country: #{e.message} #{search}"
|
143
150
|
end
|
144
151
|
end
|
145
152
|
|
@@ -155,9 +162,15 @@ Spree::Order.class_eval do
|
|
155
162
|
end
|
156
163
|
|
157
164
|
address.delete(:state)
|
158
|
-
|
165
|
+
search[:country_id] = address[:country_id]
|
166
|
+
|
167
|
+
if state = Spree::State.where(search).first
|
168
|
+
address[:state_id] = state.id
|
169
|
+
else
|
170
|
+
address[:state_name] = search[:name] || search[:abbr]
|
171
|
+
end
|
159
172
|
rescue Exception => e
|
160
|
-
raise "#{e.message} #{search}"
|
173
|
+
raise "Ensure order import address state: #{e.message} #{search}"
|
161
174
|
end
|
162
175
|
end
|
163
176
|
end
|
@@ -11,10 +11,9 @@ module Spree
|
|
11
11
|
:completed_at, :payment_total, :shipment_state,
|
12
12
|
:payment_state, :email, :special_instructions] }
|
13
13
|
|
14
|
+
let(:variant) { create(:variant) }
|
14
15
|
|
15
|
-
before
|
16
|
-
stub_authentication!
|
17
|
-
end
|
16
|
+
before { stub_authentication! }
|
18
17
|
|
19
18
|
it "cannot view all orders" do
|
20
19
|
api_get :index
|
@@ -64,6 +63,50 @@ module Spree
|
|
64
63
|
json_response["state"].should == "cart"
|
65
64
|
end
|
66
65
|
|
66
|
+
context "import" do
|
67
|
+
let(:tax_rate) { create(:tax_rate, amount: 0.05, calculator: Calculator::DefaultTax.create) }
|
68
|
+
let(:other_variant) { create(:variant) }
|
69
|
+
|
70
|
+
# line items come in as an array when importing orders or when
|
71
|
+
# creating both an order an a line item at once
|
72
|
+
let(:order_params) do
|
73
|
+
{
|
74
|
+
:line_items => [
|
75
|
+
{ :variant_id => variant.to_param, :quantity => 5 },
|
76
|
+
{ :variant_id => other_variant.to_param, :quantity => 5 }
|
77
|
+
]
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
before do
|
82
|
+
Zone.stub default_tax: tax_rate.zone
|
83
|
+
current_api_user.stub has_spree_role?: true
|
84
|
+
end
|
85
|
+
|
86
|
+
it "sets channel" do
|
87
|
+
api_post :create, :order => { channel: "amazon" }
|
88
|
+
expect(json_response['channel']).to eq "amazon"
|
89
|
+
end
|
90
|
+
|
91
|
+
it "doesnt persist any automatic tax adjustment" do
|
92
|
+
expect {
|
93
|
+
api_post :create, :order => order_params.merge(:import => true)
|
94
|
+
}.not_to change { Adjustment.count }
|
95
|
+
expect(response.status).to eq 201
|
96
|
+
end
|
97
|
+
|
98
|
+
context "provides sku rather than variant id" do
|
99
|
+
let(:order_params) do
|
100
|
+
{ :line_items => [{ :sku => variant.sku, :quantity => 1 }] }
|
101
|
+
end
|
102
|
+
|
103
|
+
it "still finds the variant by sku and persist order" do
|
104
|
+
api_post :create, :order => order_params
|
105
|
+
expect(json_response['line_items'].count).to eq 1
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
67
110
|
it "can create an order without any parameters" do
|
68
111
|
lambda { api_post :create }.should_not raise_error(NoMethodError)
|
69
112
|
response.status.should == 201
|
@@ -210,6 +253,14 @@ module Spree
|
|
210
253
|
end
|
211
254
|
end
|
212
255
|
|
256
|
+
it "responds with orders updated_at with miliseconds precision" do
|
257
|
+
api_get :index
|
258
|
+
milisecond = order.updated_at.strftime("%L")
|
259
|
+
updated_at = json_response["orders"].first["updated_at"]
|
260
|
+
|
261
|
+
expect(updated_at.split("T").last).to have_content(milisecond)
|
262
|
+
end
|
263
|
+
|
213
264
|
context "with two orders" do
|
214
265
|
before { create(:order) }
|
215
266
|
|
@@ -8,6 +8,10 @@ module Spree
|
|
8
8
|
let!(:product) { create(:product) }
|
9
9
|
let!(:inactive_product) { create(:product, :available_on => Time.now.tomorrow, :name => "inactive") }
|
10
10
|
let(:attributes) { [:id, :name, :description, :price, :available_on, :permalink, :count_on_hand, :meta_description, :meta_keywords, :taxon_ids] }
|
11
|
+
let(:product_hash) do
|
12
|
+
{ :name => "The Other Product",
|
13
|
+
:price => 19.99 }
|
14
|
+
end
|
11
15
|
|
12
16
|
before do
|
13
17
|
stub_authentication!
|
@@ -157,12 +161,79 @@ module Spree
|
|
157
161
|
end
|
158
162
|
|
159
163
|
it "can create a new product" do
|
160
|
-
api_post :create, :product =>
|
161
|
-
:price => 19.99 }
|
164
|
+
api_post :create, :product => product_hash
|
162
165
|
json_response.should have_attributes(attributes)
|
163
166
|
response.status.should == 201
|
164
167
|
end
|
165
168
|
|
169
|
+
describe "creating products with" do
|
170
|
+
it "embedded variants" do
|
171
|
+
def attributes_for_variant
|
172
|
+
h = attributes_for(:variant).except(:is_master, :product)
|
173
|
+
h.delete(:option_values)
|
174
|
+
h.merge({
|
175
|
+
options: [
|
176
|
+
{ name: "size", value: "small" },
|
177
|
+
{ name: "color", value: "black" }
|
178
|
+
]
|
179
|
+
})
|
180
|
+
end
|
181
|
+
|
182
|
+
attributes = product_hash
|
183
|
+
|
184
|
+
attributes.merge!({
|
185
|
+
shipping_category_id: 1,
|
186
|
+
|
187
|
+
option_types: ['size', 'color'],
|
188
|
+
|
189
|
+
variants_attributes: [
|
190
|
+
attributes_for_variant,
|
191
|
+
attributes_for_variant
|
192
|
+
]
|
193
|
+
})
|
194
|
+
|
195
|
+
api_post :create, :product => attributes
|
196
|
+
|
197
|
+
expect(json_response['variants'].count).to eq(3) # 1 master + 2 variants
|
198
|
+
expect(json_response['variants'][1]['option_values'][0]['name']).to eq('small')
|
199
|
+
expect(json_response['variants'][1]['option_values'][0]['option_type_name']).to eq('size')
|
200
|
+
|
201
|
+
expect(json_response['option_types'].count).to eq(2) # size, color
|
202
|
+
end
|
203
|
+
|
204
|
+
it "embedded product_properties" do
|
205
|
+
attributes = product_hash
|
206
|
+
|
207
|
+
attributes.merge!({
|
208
|
+
shipping_category_id: 1,
|
209
|
+
|
210
|
+
product_properties_attributes: [{
|
211
|
+
property_name: "fabric",
|
212
|
+
value: "cotton"
|
213
|
+
}]
|
214
|
+
})
|
215
|
+
|
216
|
+
api_post :create, :product => attributes
|
217
|
+
|
218
|
+
expect(json_response['product_properties'][0]['property_name']).to eq('fabric')
|
219
|
+
expect(json_response['product_properties'][0]['value']).to eq('cotton')
|
220
|
+
end
|
221
|
+
|
222
|
+
it "option_types even if without variants" do
|
223
|
+
attributes = product_hash
|
224
|
+
|
225
|
+
attributes.merge!({
|
226
|
+
shipping_category_id: 1,
|
227
|
+
|
228
|
+
option_types: ['size', 'color']
|
229
|
+
})
|
230
|
+
|
231
|
+
api_post :create, :product => attributes
|
232
|
+
|
233
|
+
expect(json_response['option_types'].count).to eq(2)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
166
237
|
# Regression test for #2140
|
167
238
|
context "with authentication_required set to false" do
|
168
239
|
before do
|
@@ -62,6 +62,18 @@ module Spree
|
|
62
62
|
expect(line_item.variant_id).to eq attributes[:variant_id]
|
63
63
|
expect(line_item.price).to eq attributes[:price]
|
64
64
|
end
|
65
|
+
|
66
|
+
it "ensures quantity values are converted to integer" do
|
67
|
+
params = {
|
68
|
+
:line_items_attributes => {
|
69
|
+
"0" => { :variant_id => variant.id, :quantity => "5" },
|
70
|
+
"1" => { :variant_id => variant.id, :quantity => "5" }
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
order = Order.build_from_api(user, params)
|
75
|
+
expect(order.line_items.first.quantity).to eq 10
|
76
|
+
end
|
65
77
|
end
|
66
78
|
|
67
79
|
it 'uses line item price if present' do
|
@@ -133,7 +145,7 @@ module Spree
|
|
133
145
|
|
134
146
|
it 'can build an order from API with state attributes' do
|
135
147
|
ship_address.delete(:state_id)
|
136
|
-
ship_address[:state] = { 'name' =>
|
148
|
+
ship_address[:state] = { 'name' => state.name }
|
137
149
|
params = { :ship_address_attributes => ship_address,
|
138
150
|
:line_items_attributes => line_items }
|
139
151
|
|
@@ -141,15 +153,37 @@ module Spree
|
|
141
153
|
order.ship_address.state.name.should eq 'Alabama'
|
142
154
|
end
|
143
155
|
|
144
|
-
|
156
|
+
context "state passed is not associated with country" do
|
157
|
+
let(:params) do
|
158
|
+
params = { :ship_address_attributes => ship_address,
|
159
|
+
:line_items_attributes => line_items }
|
160
|
+
end
|
161
|
+
|
162
|
+
let(:other_state) { create(:state, name: "Uhuhuh", country: create(:country)) }
|
163
|
+
|
164
|
+
before do
|
165
|
+
country.states.destroy_all
|
166
|
+
|
167
|
+
ship_address.delete(:state_id)
|
168
|
+
ship_address[:state] = { 'name' => other_state.name }
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'sets states name instead of state id' do
|
172
|
+
order = Order.build_from_api(user, params)
|
173
|
+
expect(order.ship_address.state_name).to eq other_state.name
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'sets state name if state record not found' do
|
178
|
+
country.states.destroy_all
|
179
|
+
|
145
180
|
ship_address.delete(:state_id)
|
146
181
|
ship_address[:state] = { 'name' => 'XXX' }
|
147
182
|
params = { :ship_address_attributes => ship_address,
|
148
183
|
:line_items_attributes => line_items }
|
149
184
|
|
150
|
-
|
151
|
-
|
152
|
-
}.to raise_error /XXX/
|
185
|
+
order = Order.build_from_api(user, params)
|
186
|
+
expect(order.ship_address.state_name).to eq 'XXX'
|
153
187
|
end
|
154
188
|
|
155
189
|
context 'variant not deleted' do
|
@@ -187,19 +221,12 @@ module Spree
|
|
187
221
|
|
188
222
|
it 'ensures_state_id for state fields' do
|
189
223
|
[:name, :abbr].each do |field|
|
190
|
-
address = { :state => { field => state.send(field) }}
|
224
|
+
address = { country_id: country.id, :state => { field => state.send(field) }}
|
191
225
|
Order.ensure_state_id_from_api(address)
|
192
226
|
address[:state_id].should eq state.id
|
193
227
|
end
|
194
228
|
end
|
195
229
|
|
196
|
-
it "raises with proper message when cant find state" do
|
197
|
-
address = { :state => { "name" => "NoNoState" } }
|
198
|
-
expect {
|
199
|
-
Order.ensure_state_id_from_api(address)
|
200
|
-
}.to raise_error /NoNoState/
|
201
|
-
end
|
202
|
-
|
203
230
|
context "shippments" do
|
204
231
|
let(:params) do
|
205
232
|
{ :shipments_attributes => [
|
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: 1.3.
|
4
|
+
version: 1.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Bigg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-01-23 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: 1.3.
|
19
|
+
version: 1.3.5
|
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: 1.3.
|
26
|
+
version: 1.3.5
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: versioncake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -45,8 +45,8 @@ executables: []
|
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
|
-
- .gitignore
|
49
|
-
- .rspec
|
48
|
+
- ".gitignore"
|
49
|
+
- ".rspec"
|
50
50
|
- Gemfile
|
51
51
|
- LICENSE
|
52
52
|
- Rakefile
|
@@ -141,6 +141,7 @@ files:
|
|
141
141
|
- db/migrate/20100107141738_add_api_key_to_spree_users.rb
|
142
142
|
- db/migrate/20120411123334_resize_api_key_field.rb
|
143
143
|
- db/migrate/20120530054546_rename_api_key_to_spree_api_key.rb
|
144
|
+
- db/migrate/20131017162334_add_index_to_user_spree_api_key.rb
|
144
145
|
- lib/spree/api.rb
|
145
146
|
- lib/spree/api/controller_setup.rb
|
146
147
|
- lib/spree/api/engine.rb
|
@@ -188,17 +189,17 @@ require_paths:
|
|
188
189
|
- lib
|
189
190
|
required_ruby_version: !ruby/object:Gem::Requirement
|
190
191
|
requirements:
|
191
|
-
- -
|
192
|
+
- - ">="
|
192
193
|
- !ruby/object:Gem::Version
|
193
194
|
version: '0'
|
194
195
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
195
196
|
requirements:
|
196
|
-
- -
|
197
|
+
- - ">="
|
197
198
|
- !ruby/object:Gem::Version
|
198
199
|
version: '0'
|
199
200
|
requirements: []
|
200
201
|
rubyforge_project:
|
201
|
-
rubygems_version: 2.
|
202
|
+
rubygems_version: 2.2.0
|
202
203
|
signing_key:
|
203
204
|
specification_version: 4
|
204
205
|
summary: Spree's API
|