spree_api 2.0.7 → 2.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -8
- data/app/controllers/spree/api/products_controller.rb +27 -0
- data/app/views/spree/api/taxons/index.v1.rabl +4 -2
- data/spec/controllers/spree/api/checkouts_controller_spec.rb +1 -10
- data/spec/controllers/spree/api/products_controller_spec.rb +158 -3
- data/spec/controllers/spree/api/taxons_controller_spec.rb +44 -15
- data/spec/spec_helper.rb +7 -1
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f6416ddb13bbe8f04930a3af747fecd032eb9bfa
|
4
|
+
data.tar.gz: fda21f8c9d73dc334d9826e01d6e362da9dc3526
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a17ad20ff0392f2ae1ce3cf51baf5b7d224d6890e0d279d9dc77b46070b415ba71f40d04ec55352069c616c270eb2b99787685cc32cfea5f0e2d51f12e5b31e5
|
7
|
+
data.tar.gz: 132136db66a648b0457fe9c2063586c126f28654327441457da85b800cac154b2a694a622a15cb892450a7efb244534172f55d3aab85521c625bef696bebc1bf
|
data/CHANGELOG.md
CHANGED
@@ -1,17 +1,14 @@
|
|
1
|
-
## Spree 2.0.
|
1
|
+
## Spree 2.0.8 (unreleased) ##
|
2
2
|
|
3
|
-
*
|
4
|
-
|
5
|
-
* Admin users can set the order channel when importing orders. By sing the
|
6
|
-
channel attribute on Order model
|
3
|
+
* When line items are added after the delivery state, the shipments are now recreated. #3914
|
7
4
|
|
8
5
|
Washington Luiz
|
9
6
|
|
10
|
-
*
|
7
|
+
* State names are now persisted on addresses when using `ensure_state_from_api`, even if the state does not exist as a `Spree::State`. e976a3bbd603ea981499f440fa69f2e6d0d930d7
|
11
8
|
|
12
|
-
|
9
|
+
Washington Luiz
|
13
10
|
|
14
|
-
*
|
11
|
+
* Times are now returned with millisecond precision. (Note: this patch is not in the 2-1-stable or master branches because Rails 4 does this by default.)
|
15
12
|
|
16
13
|
Washington Luiz
|
17
14
|
|
@@ -26,9 +26,28 @@ module Spree
|
|
26
26
|
def create
|
27
27
|
authorize! :create, Product
|
28
28
|
params[:product][:available_on] ||= Time.now
|
29
|
+
|
30
|
+
variants_attributes = params[:product].delete(:variants_attributes) || []
|
31
|
+
option_type_attributes = params[:product].delete(:option_types) || []
|
32
|
+
set_up_shipping_category
|
33
|
+
|
29
34
|
@product = Product.new(params[:product])
|
30
35
|
begin
|
31
36
|
if @product.save
|
37
|
+
variants_attributes.each do |variant_attribute|
|
38
|
+
variant = @product.variants.new
|
39
|
+
variant.update_attributes(variant_attribute)
|
40
|
+
end
|
41
|
+
|
42
|
+
option_type_attributes.each do |name|
|
43
|
+
option_type = OptionType.where(name: name).first_or_initialize do |option_type|
|
44
|
+
option_type.presentation = name
|
45
|
+
option_type.save!
|
46
|
+
end
|
47
|
+
|
48
|
+
@product.option_types << option_type unless @product.option_types.include?(option_type)
|
49
|
+
end
|
50
|
+
|
32
51
|
respond_with(@product, :status => 201, :default_template => :show)
|
33
52
|
else
|
34
53
|
invalid_resource!(@product)
|
@@ -56,6 +75,14 @@ module Spree
|
|
56
75
|
@product.variants_including_master.update_all(:deleted_at => Time.now)
|
57
76
|
respond_with(@product, :status => 204)
|
58
77
|
end
|
78
|
+
|
79
|
+
private
|
80
|
+
def set_up_shipping_category
|
81
|
+
if shipping_category = params[:product].delete(:shipping_category)
|
82
|
+
id = ShippingCategory.find_or_create_by_name(shipping_category).id
|
83
|
+
params[:product][:shipping_category_id] = id
|
84
|
+
end
|
85
|
+
end
|
59
86
|
end
|
60
87
|
end
|
61
88
|
end
|
@@ -4,7 +4,9 @@ node(:total_count) { @taxons.total_count }
|
|
4
4
|
node(:current_page) { params[:page] ? params[:page].to_i : 1 }
|
5
5
|
node(:per_page) { params[:per_page] || Kaminari.config.default_per_page }
|
6
6
|
node(:pages) { @taxons.num_pages }
|
7
|
-
child
|
7
|
+
child @taxons => :taxons do
|
8
8
|
attributes *taxon_attributes
|
9
|
-
|
9
|
+
unless params[:without_children]
|
10
|
+
extends "spree/api/taxons/taxons"
|
11
|
+
end
|
10
12
|
end
|
@@ -44,16 +44,6 @@ module Spree
|
|
44
44
|
assert_unauthorized!
|
45
45
|
end
|
46
46
|
|
47
|
-
it "will return an error if the recently created order cannot transition from cart to address" do
|
48
|
-
order.state.should eq "cart"
|
49
|
-
order.update_column(:email, nil) # email is necessary to transition from cart to address
|
50
|
-
|
51
|
-
api_put :update, :id => order.to_param, :order_token => order.token
|
52
|
-
|
53
|
-
# Order has not transitioned
|
54
|
-
json_response['state'].should == 'cart'
|
55
|
-
end
|
56
|
-
|
57
47
|
it "should transition a recently created order from cart to address" do
|
58
48
|
order.state.should eq "cart"
|
59
49
|
order.email.should_not be_nil
|
@@ -220,6 +210,7 @@ module Spree
|
|
220
210
|
|
221
211
|
it "cannot transition if order email is blank" do
|
222
212
|
order.update_column(:email, nil)
|
213
|
+
order.update_column(:state, 'address')
|
223
214
|
|
224
215
|
api_put :next, :id => order.to_param, :order_token => order.token
|
225
216
|
response.status.should == 422
|
@@ -8,6 +8,11 @@ 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, :meta_description, :meta_keywords, :shipping_category_id, :taxon_ids] }
|
11
|
+
let(:product_hash) do
|
12
|
+
{ :name => "The Other Product",
|
13
|
+
:price => 19.99,
|
14
|
+
:shipping_category_id => create(:shipping_category).id }
|
15
|
+
end
|
11
16
|
|
12
17
|
before do
|
13
18
|
stub_authentication!
|
@@ -180,13 +185,163 @@ module Spree
|
|
180
185
|
end
|
181
186
|
|
182
187
|
it "can create a new product" do
|
183
|
-
api_post :create, :product =>
|
184
|
-
:price => 19.99,
|
185
|
-
:shipping_category_id => create(:shipping_category).id }
|
188
|
+
api_post :create, :product => product_hash
|
186
189
|
json_response.should have_attributes(attributes)
|
187
190
|
response.status.should == 201
|
188
191
|
end
|
189
192
|
|
193
|
+
describe "creating products with" do
|
194
|
+
it "embedded variants" do
|
195
|
+
def attributes_for_variant
|
196
|
+
h = attributes_for(:variant).except(:is_master, :product)
|
197
|
+
h.delete(:option_values)
|
198
|
+
h.merge({
|
199
|
+
options: [
|
200
|
+
{ name: "size", value: "small" },
|
201
|
+
{ name: "color", value: "black" }
|
202
|
+
]
|
203
|
+
})
|
204
|
+
end
|
205
|
+
|
206
|
+
attributes = product_hash
|
207
|
+
|
208
|
+
attributes.merge!({
|
209
|
+
shipping_category_id: 1,
|
210
|
+
|
211
|
+
option_types: ['size', 'color'],
|
212
|
+
|
213
|
+
variants_attributes: [
|
214
|
+
attributes_for_variant,
|
215
|
+
attributes_for_variant
|
216
|
+
]
|
217
|
+
})
|
218
|
+
|
219
|
+
api_post :create, :product => attributes
|
220
|
+
|
221
|
+
expect(json_response['variants'].count).to eq(3) # 1 master + 2 variants
|
222
|
+
expect(json_response['variants'][1]['option_values'][0]['name']).to eq('small')
|
223
|
+
expect(json_response['variants'][1]['option_values'][0]['option_type_name']).to eq('size')
|
224
|
+
|
225
|
+
expect(json_response['option_types'].count).to eq(2) # size, color
|
226
|
+
end
|
227
|
+
|
228
|
+
it "embedded product_properties" do
|
229
|
+
attributes = product_hash
|
230
|
+
|
231
|
+
attributes.merge!({
|
232
|
+
shipping_category_id: 1,
|
233
|
+
|
234
|
+
product_properties_attributes: [{
|
235
|
+
property_name: "fabric",
|
236
|
+
value: "cotton"
|
237
|
+
}]
|
238
|
+
})
|
239
|
+
|
240
|
+
api_post :create, :product => attributes
|
241
|
+
|
242
|
+
expect(json_response['product_properties'][0]['property_name']).to eq('fabric')
|
243
|
+
expect(json_response['product_properties'][0]['value']).to eq('cotton')
|
244
|
+
end
|
245
|
+
|
246
|
+
it "option_types even if without variants" do
|
247
|
+
attributes = product_hash
|
248
|
+
|
249
|
+
attributes.merge!({
|
250
|
+
shipping_category_id: 1,
|
251
|
+
|
252
|
+
option_types: ['size', 'color']
|
253
|
+
})
|
254
|
+
|
255
|
+
api_post :create, :product => attributes
|
256
|
+
|
257
|
+
expect(json_response['option_types'].count).to eq(2)
|
258
|
+
end
|
259
|
+
|
260
|
+
it "creates with shipping categories" do
|
261
|
+
hash = { :name => "The Other Product",
|
262
|
+
:price => 19.99,
|
263
|
+
:shipping_category => "Free Ships" }
|
264
|
+
|
265
|
+
api_post :create, :product => hash
|
266
|
+
expect(response.status).to eq 201
|
267
|
+
|
268
|
+
shipping_id = ShippingCategory.find_by_name("Free Ships").id
|
269
|
+
expect(json_response['shipping_category_id']).to eq shipping_id
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
describe "creating products with" do
|
274
|
+
it "embedded variants" do
|
275
|
+
def attributes_for_variant
|
276
|
+
h = attributes_for(:variant).except(:is_master, :product)
|
277
|
+
h.delete(:option_values)
|
278
|
+
h.merge({
|
279
|
+
options: [
|
280
|
+
{ name: "size", value: "small" },
|
281
|
+
{ name: "color", value: "black" }
|
282
|
+
]
|
283
|
+
})
|
284
|
+
end
|
285
|
+
|
286
|
+
product_hash.merge!({
|
287
|
+
variants_attributes: [
|
288
|
+
attributes_for_variant,
|
289
|
+
attributes_for_variant
|
290
|
+
]
|
291
|
+
})
|
292
|
+
|
293
|
+
api_post :create, :product => product_hash
|
294
|
+
expect(response.status).to eq 201
|
295
|
+
expect(json_response['variants'].count).to eq(3) # 1 master + 2 variants
|
296
|
+
|
297
|
+
variants = json_response['variants'].select { |v| !v['is_master'] }
|
298
|
+
expect(variants.first['option_values'][0]['name']).to eq('small')
|
299
|
+
expect(variants.first['option_values'][0]['option_type_name']).to eq('size')
|
300
|
+
|
301
|
+
expect(json_response['option_types'].count).to eq(2) # size, color
|
302
|
+
end
|
303
|
+
|
304
|
+
it "embedded product_properties" do
|
305
|
+
product_hash.merge!({
|
306
|
+
shipping_category_id: 1,
|
307
|
+
|
308
|
+
product_properties_attributes: [{
|
309
|
+
property_name: "fabric",
|
310
|
+
value: "cotton"
|
311
|
+
}]
|
312
|
+
})
|
313
|
+
|
314
|
+
api_post :create, :product => product_hash
|
315
|
+
|
316
|
+
expect(json_response['product_properties'][0]['property_name']).to eq('fabric')
|
317
|
+
expect(json_response['product_properties'][0]['value']).to eq('cotton')
|
318
|
+
end
|
319
|
+
|
320
|
+
it "option_types even if without variants" do
|
321
|
+
product_hash.merge!({
|
322
|
+
shipping_category_id: 1,
|
323
|
+
|
324
|
+
option_types: ['size', 'color']
|
325
|
+
})
|
326
|
+
|
327
|
+
api_post :create, :product => product_hash
|
328
|
+
|
329
|
+
expect(json_response['option_types'].count).to eq(2)
|
330
|
+
end
|
331
|
+
|
332
|
+
it "creates with shipping categories" do
|
333
|
+
hash = { :name => "The Other Product",
|
334
|
+
:price => 19.99,
|
335
|
+
:shipping_category => "Free Ships" }
|
336
|
+
|
337
|
+
api_post :create, :product => hash
|
338
|
+
expect(response.status).to eq 201
|
339
|
+
|
340
|
+
shipping_id = ShippingCategory.find_by_name("Free Ships").id
|
341
|
+
expect(json_response['shipping_category_id']).to eq shipping_id
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
190
345
|
# Regression test for #2140
|
191
346
|
context "with authentication_required set to false" do
|
192
347
|
before do
|
@@ -27,6 +27,14 @@ module Spree
|
|
27
27
|
children.first['taxons'].count.should eq 1
|
28
28
|
end
|
29
29
|
|
30
|
+
# Regression test for #4112
|
31
|
+
it "does not include children when asked not to" do
|
32
|
+
api_get :index, :taxonomy_id => taxonomy.id, :without_children => 1
|
33
|
+
|
34
|
+
json_response['taxons'].first['name'].should eq(taxon.name)
|
35
|
+
json_response['taxons'].first['taxons'].should be_nil
|
36
|
+
end
|
37
|
+
|
30
38
|
it "paginates through taxons" do
|
31
39
|
new_taxon = create(:taxon, :name => "Go", :taxonomy => taxonomy)
|
32
40
|
taxonomy.root.children << new_taxon
|
@@ -39,21 +47,42 @@ module Spree
|
|
39
47
|
expect(json_response["pages"]).to eql(2)
|
40
48
|
end
|
41
49
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
50
|
+
describe 'searching' do
|
51
|
+
context 'with a name' do
|
52
|
+
before do
|
53
|
+
api_get :index, :q => { :name_cont => name }
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'with one result' do
|
57
|
+
let(:name) { "Ruby" }
|
58
|
+
|
59
|
+
it "returns an array including the matching taxon" do
|
60
|
+
json_response['taxons'].count.should == 1
|
61
|
+
json_response['taxons'].first['name'].should eq "Ruby"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'with no results' do
|
66
|
+
let(:name) { "Imaginary" }
|
67
|
+
|
68
|
+
it 'returns an empty array of taxons' do
|
69
|
+
json_response.keys.should include('taxons')
|
70
|
+
json_response['taxons'].count.should == 0
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'with no filters' do
|
76
|
+
it "gets all taxons" do
|
77
|
+
api_get :index
|
78
|
+
|
79
|
+
json_response['taxons'].first['name'].should eq taxonomy.root.name
|
80
|
+
children = json_response['taxons'].first['taxons']
|
81
|
+
children.count.should eq 1
|
82
|
+
children.first['name'].should eq taxon.name
|
83
|
+
children.first['taxons'].count.should eq 1
|
84
|
+
end
|
85
|
+
end
|
57
86
|
end
|
58
87
|
|
59
88
|
it "gets a single taxon" do
|
data/spec/spec_helper.rb
CHANGED
@@ -13,7 +13,13 @@ end
|
|
13
13
|
|
14
14
|
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
15
15
|
ENV["RAILS_ENV"] ||= 'test'
|
16
|
-
|
16
|
+
|
17
|
+
begin
|
18
|
+
require File.expand_path("../dummy/config/environment", __FILE__)
|
19
|
+
rescue LoadError
|
20
|
+
puts "Could not load dummy application. Please ensure you have run `bundle exec rake test_app`"
|
21
|
+
end
|
22
|
+
|
17
23
|
require 'rspec/rails'
|
18
24
|
require 'rspec/autorun'
|
19
25
|
require 'database_cleaner'
|
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.0.
|
4
|
+
version: 2.0.8
|
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-22 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.0.
|
19
|
+
version: 2.0.8
|
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.0.
|
26
|
+
version: 2.0.8
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rabl
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,7 +59,7 @@ executables: []
|
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
|
-
- .gitignore
|
62
|
+
- ".gitignore"
|
63
63
|
- CHANGELOG.md
|
64
64
|
- Gemfile
|
65
65
|
- LICENSE
|
@@ -236,17 +236,17 @@ require_paths:
|
|
236
236
|
- lib
|
237
237
|
required_ruby_version: !ruby/object:Gem::Requirement
|
238
238
|
requirements:
|
239
|
-
- -
|
239
|
+
- - ">="
|
240
240
|
- !ruby/object:Gem::Version
|
241
241
|
version: '0'
|
242
242
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
243
243
|
requirements:
|
244
|
-
- -
|
244
|
+
- - ">="
|
245
245
|
- !ruby/object:Gem::Version
|
246
246
|
version: '0'
|
247
247
|
requirements: []
|
248
248
|
rubyforge_project:
|
249
|
-
rubygems_version: 2.
|
249
|
+
rubygems_version: 2.2.0
|
250
250
|
signing_key:
|
251
251
|
specification_version: 4
|
252
252
|
summary: Spree's API
|