spree_api 2.1.4 → 2.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -29
- data/app/controllers/spree/api/base_controller.rb +6 -4
- data/app/controllers/spree/api/checkouts_controller.rb +6 -3
- data/app/controllers/spree/api/line_items_controller.rb +3 -1
- data/app/controllers/spree/api/orders_controller.rb +38 -3
- data/app/controllers/spree/api/products_controller.rb +24 -5
- data/app/helpers/spree/api/api_helpers.rb +1 -1
- data/app/models/spree/api_configuration.rb +1 -1
- data/app/models/spree/order_decorator.rb +3 -2
- data/app/views/spree/api/orders/apply_coupon_code.v1.rabl +7 -0
- data/app/views/spree/api/products/index.v1.rabl +1 -1
- data/app/views/spree/api/products/show.v1.rabl +1 -1
- data/app/views/spree/api/variants/big_variant.v1.rabl +3 -3
- data/config/routes.rb +4 -0
- data/spec/controllers/spree/api/line_items_controller_spec.rb +6 -0
- data/spec/controllers/spree/api/orders_controller_spec.rb +69 -1
- data/spec/controllers/spree/api/products_controller_spec.rb +56 -59
- data/spec/controllers/spree/api/return_authorizations_controller_spec.rb +1 -1
- data/spec/controllers/spree/api/variants_controller_spec.rb +1 -3
- data/spec/models/spree/order_spec.rb +4 -4
- data/spec/spec_helper.rb +1 -0
- data/spree_api.gemspec +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ec8d2a00aea7321fefad11982a2d8189dac5966
|
4
|
+
data.tar.gz: a623fd16b63b39761f6b84aead9790e95c163f74
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 07a0829cf7e00aaab18ef8d21f69f5e546b3f35b224008a38ef61d6b9517ad317184f9187a621b047192b41fb88726fbc48b1930ba2bbd923c89d39e9aaf80fc
|
7
|
+
data.tar.gz: 03e458073acca0d80cd9f34712d4b9aeb5b4ab077e285e4456ab3e07f9d692984f099ab3a7fd83fee881f688ac159fe2619cef88320ed8eb703616f3937f3d44
|
data/CHANGELOG.md
CHANGED
@@ -1,29 +1 @@
|
|
1
|
-
## Spree 2.1.
|
2
|
-
|
3
|
-
* Cached products/show template, which can lead to drastically (65x) faster loading times on product requests.
|
4
|
-
|
5
|
-
Ryan Bigg
|
6
|
-
|
7
|
-
* The parts that make up an order's response from /api/orders/:num are cached, which can lead to a 5x improvement of speed for this API endpoint. 00e92054caba9689c0f8ed913240668039b6e8de
|
8
|
-
|
9
|
-
Ryan Bigg
|
10
|
-
|
11
|
-
* Cached variant objects which can lead to slightly faster loading times (4x) for each variant.
|
12
|
-
|
13
|
-
Ryan Bigg
|
14
|
-
|
15
|
-
* Added a route to allow for /api/variants/:id requests
|
16
|
-
|
17
|
-
Ryan Bigg
|
18
|
-
|
19
|
-
* Taxons can now be gathered without their children with the `?without_children=1` query parameter. #4112
|
20
|
-
|
21
|
-
Ryan Bigg
|
22
|
-
|
23
|
-
* Orders on the `/api/orders/mine` endpoint can now be paginated and searched. #4099
|
24
|
-
|
25
|
-
Richard Nuno
|
26
|
-
|
27
|
-
* Order token can now be passed as a header: `X-Spree-Order-Token`. #4148
|
28
|
-
|
29
|
-
Lucjan Suski (methyl)
|
1
|
+
## Spree 2.1.5 (unreleased) ##
|
@@ -31,7 +31,7 @@ module Spree
|
|
31
31
|
|
32
32
|
def set_jsonp_format
|
33
33
|
if params[:callback] && request.get?
|
34
|
-
self.response_body = "#{params[:callback]}(#{
|
34
|
+
self.response_body = "#{params[:callback]}(#{response.body})"
|
35
35
|
headers["Content-Type"] = 'application/javascript'
|
36
36
|
end
|
37
37
|
end
|
@@ -131,19 +131,21 @@ module Spree
|
|
131
131
|
end
|
132
132
|
|
133
133
|
def product_scope
|
134
|
+
variants_associations = [{ option_values: :option_type }, :default_price, :prices, :images]
|
134
135
|
if current_api_user.has_spree_role?("admin")
|
135
136
|
scope = Product.with_deleted.accessible_by(current_ability, :read)
|
137
|
+
.includes(:product_properties, :option_types, variants_including_master: variants_associations)
|
138
|
+
|
136
139
|
unless params[:show_deleted]
|
137
140
|
scope = scope.not_deleted
|
138
141
|
end
|
139
142
|
else
|
140
143
|
scope = Product.accessible_by(current_ability, :read).active
|
144
|
+
.includes(:product_properties, :option_types, variants_including_master: variants_associations)
|
141
145
|
end
|
142
146
|
|
143
|
-
scope
|
147
|
+
scope
|
144
148
|
end
|
145
|
-
|
146
149
|
end
|
147
150
|
end
|
148
151
|
end
|
149
|
-
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module Spree
|
2
2
|
module Api
|
3
3
|
class CheckoutsController < Spree::Api::BaseController
|
4
|
-
before_filter :load_order, only: [:show, :update, :next, :advance]
|
5
4
|
before_filter :associate_user, only: :update
|
6
5
|
|
7
6
|
include Spree::Core::ControllerHelpers::Auth
|
@@ -16,6 +15,7 @@ module Spree
|
|
16
15
|
end
|
17
16
|
|
18
17
|
def next
|
18
|
+
load_order(true)
|
19
19
|
authorize! :update, @order, order_token
|
20
20
|
@order.next!
|
21
21
|
respond_with(@order, default_template: 'spree/api/orders/show', status: 200)
|
@@ -24,16 +24,19 @@ module Spree
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def advance
|
27
|
+
load_order(true)
|
27
28
|
authorize! :update, @order, order_token
|
28
29
|
while @order.next; end
|
29
30
|
respond_with(@order, default_template: 'spree/api/orders/show', status: 200)
|
30
31
|
end
|
31
32
|
|
32
33
|
def show
|
34
|
+
load_order
|
33
35
|
respond_with(@order, default_template: 'spree/api/orders/show', status: 200)
|
34
36
|
end
|
35
37
|
|
36
38
|
def update
|
39
|
+
load_order(true)
|
37
40
|
authorize! :update, @order, order_token
|
38
41
|
order_params = object_params
|
39
42
|
line_items = order_params.delete('line_items_attributes')
|
@@ -84,8 +87,8 @@ module Spree
|
|
84
87
|
false
|
85
88
|
end
|
86
89
|
|
87
|
-
def load_order
|
88
|
-
@order = Spree::Order.find_by!(number: params[:id])
|
90
|
+
def load_order(lock = false)
|
91
|
+
@order = Spree::Order.lock(lock).find_by!(number: params[:id])
|
89
92
|
raise_insufficient_quantity and return if @order.insufficient_stock_lines.present?
|
90
93
|
@order.state = params[:state] if params[:state]
|
91
94
|
state_callback(:before)
|
@@ -25,7 +25,9 @@ module Spree
|
|
25
25
|
|
26
26
|
def destroy
|
27
27
|
@line_item = order.line_items.find(params[:id])
|
28
|
-
@line_item.
|
28
|
+
variant = Spree::Variant.find(@line_item.variant_id)
|
29
|
+
@order.contents.remove(variant, @line_item.quantity)
|
30
|
+
@order.ensure_updated_shipments
|
29
31
|
respond_with(@line_item, status: 204)
|
30
32
|
end
|
31
33
|
|
@@ -2,6 +2,9 @@ module Spree
|
|
2
2
|
module Api
|
3
3
|
class OrdersController < Spree::Api::BaseController
|
4
4
|
|
5
|
+
skip_before_filter :check_for_user_or_api_key, only: :apply_coupon_code
|
6
|
+
skip_before_filter :authenticate_user, only: :apply_coupon_code
|
7
|
+
|
5
8
|
# Dynamically defines our stores checkout steps to ensure we check authorization on each step.
|
6
9
|
Order.checkout_steps.keys.each do |step|
|
7
10
|
define_method step do
|
@@ -44,7 +47,7 @@ module Spree
|
|
44
47
|
end
|
45
48
|
|
46
49
|
def update
|
47
|
-
find_order
|
50
|
+
find_order(true)
|
48
51
|
# Parsing line items through as an update_attributes call in the API will result in
|
49
52
|
# many line items for the same variant_id being created. We must be smarter about this,
|
50
53
|
# hence the use of the update_line_items method, defined within order_decorator.rb.
|
@@ -69,6 +72,38 @@ module Spree
|
|
69
72
|
end
|
70
73
|
end
|
71
74
|
|
75
|
+
##
|
76
|
+
# Applies a promotion code to the user's most recent order
|
77
|
+
# This is a temporary API method until we move to next Spree release which has this logic already in this commit.
|
78
|
+
#
|
79
|
+
# https://github.com/spree/spree/commit/72a5b74c47af975fc3492580415a4cdc2dc02c0c
|
80
|
+
#
|
81
|
+
# Source references:
|
82
|
+
#
|
83
|
+
# https://github.com/spree/spree/blob/master/frontend/app/controllers/spree/store_controller.rb#L13
|
84
|
+
# https://github.com/spree/spree/blob/2-1-stable/frontend/app/controllers/spree/orders_controller.rb#L100
|
85
|
+
def apply_coupon_code
|
86
|
+
find_order
|
87
|
+
@order.coupon_code = params[:coupon_code]
|
88
|
+
@order.save
|
89
|
+
|
90
|
+
# https://github.com/spree/spree/blob/2-1-stable/core/lib/spree/promo/coupon_applicator.rb
|
91
|
+
result = Spree::Promo::CouponApplicator.new(@order).apply
|
92
|
+
|
93
|
+
result[:coupon_applied?] ||= false
|
94
|
+
|
95
|
+
# Move flash.notice fields into success if applied
|
96
|
+
# An error message is in result[:error]
|
97
|
+
if result[:coupon_applied?] && result[:notice]
|
98
|
+
result[:success] = result[:notice]
|
99
|
+
end
|
100
|
+
|
101
|
+
# Need to turn hash result into object for RABL
|
102
|
+
# https://github.com/nesquena/rabl/wiki/Rendering-hash-objects-in-rabl
|
103
|
+
@coupon_result = OpenStruct.new(result)
|
104
|
+
render status: @coupon_result.coupon_applied? ? 200 : 422
|
105
|
+
end
|
106
|
+
|
72
107
|
private
|
73
108
|
def deal_with_line_items
|
74
109
|
line_item_attributes = params[:order][:line_items]
|
@@ -125,8 +160,8 @@ module Spree
|
|
125
160
|
end
|
126
161
|
end
|
127
162
|
|
128
|
-
def find_order
|
129
|
-
@order = Spree::Order.find_by!(number: params[:id])
|
163
|
+
def find_order(lock = false)
|
164
|
+
@order = Spree::Order.lock(lock).find_by!(number: params[:id])
|
130
165
|
authorize! :update, @order, order_token
|
131
166
|
end
|
132
167
|
|
@@ -42,7 +42,7 @@ module Spree
|
|
42
42
|
# ...
|
43
43
|
# option_types: ['size', 'color']
|
44
44
|
# }
|
45
|
-
#
|
45
|
+
#
|
46
46
|
# By passing the shipping category name you can fetch or create that
|
47
47
|
# shipping category on the fly. e.g.
|
48
48
|
#
|
@@ -55,7 +55,7 @@ module Spree
|
|
55
55
|
authorize! :create, Product
|
56
56
|
params[:product][:available_on] ||= Time.now
|
57
57
|
set_up_shipping_category
|
58
|
-
|
58
|
+
|
59
59
|
begin
|
60
60
|
@product = Product.new(product_params)
|
61
61
|
if @product.save
|
@@ -86,9 +86,28 @@ module Spree
|
|
86
86
|
def update
|
87
87
|
@product = find_product(params[:id])
|
88
88
|
authorize! :update, @product
|
89
|
-
|
89
|
+
|
90
90
|
if @product.update_attributes(product_params)
|
91
|
-
|
91
|
+
variants_params.each do |variant_attribute|
|
92
|
+
# update the variant if the id is present in the payload
|
93
|
+
if variant_attribute['id'].present?
|
94
|
+
@product.variants.find(variant_attribute['id'].to_i).update_attributes(variant_attribute)
|
95
|
+
else
|
96
|
+
# make sure the product is assigned before the options=
|
97
|
+
@product.variants.create({ product: @product }.merge(variant_attribute))
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
option_types_params.each do |name|
|
102
|
+
option_type = OptionType.where(name: name).first_or_initialize do |option_type|
|
103
|
+
option_type.presentation = name
|
104
|
+
option_type.save!
|
105
|
+
end
|
106
|
+
|
107
|
+
@product.option_types << option_type unless @product.option_types.include?(option_type)
|
108
|
+
end
|
109
|
+
|
110
|
+
respond_with(@product.reload, :status => 200, :default_template => :show)
|
92
111
|
else
|
93
112
|
invalid_resource!(@product)
|
94
113
|
end
|
@@ -119,7 +138,7 @@ module Spree
|
|
119
138
|
end
|
120
139
|
|
121
140
|
params.require(:product).permit(
|
122
|
-
variants_key => permitted_variant_attributes,
|
141
|
+
variants_key => [permitted_variant_attributes, :id],
|
123
142
|
).delete(variants_key) || []
|
124
143
|
end
|
125
144
|
|
@@ -97,8 +97,9 @@ Spree::Order.class_eval do
|
|
97
97
|
def create_adjustments_from_api(adjustments)
|
98
98
|
adjustments.each do |a|
|
99
99
|
begin
|
100
|
-
|
101
|
-
|
100
|
+
a.symbolize_keys! # For backwards compatibility sake (before it acccessed string keys)
|
101
|
+
adjustment = self.adjustments.build(:amount => a[:amount].to_f,
|
102
|
+
:label => a[:label])
|
102
103
|
adjustment.save!
|
103
104
|
adjustment.finalize!
|
104
105
|
rescue Exception => e
|
@@ -0,0 +1,7 @@
|
|
1
|
+
object @coupon_result
|
2
|
+
|
3
|
+
# Mimic of eventual payload in Spree Core to keep contract the same when we upgrade.
|
4
|
+
# https://github.com/spree/spree/blob/master/api/app/views/spree/api/promotions/handler.v1.rabl
|
5
|
+
node(:success) { @coupon_result.success }
|
6
|
+
node(:error) { @coupon_result.error }
|
7
|
+
node(:successful) { @coupon_result.coupon_applied? }
|
@@ -4,6 +4,6 @@ node(:total_count) { @products.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) { @products.num_pages }
|
7
|
-
child(@products) do
|
7
|
+
child(@products => :products) do
|
8
8
|
extends "spree/api/products/show"
|
9
9
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
object @variant
|
2
2
|
cache @variant
|
3
|
-
attributes *variant_attributes
|
4
3
|
extends "spree/api/variants/variant"
|
4
|
+
|
5
5
|
child(:images => :images) do
|
6
6
|
attributes *image_attributes
|
7
7
|
code(:urls) do |v|
|
@@ -9,11 +9,11 @@ child(:images => :images) do
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
child(:stock_items) do
|
12
|
+
child(:stock_items => :stock_items) do
|
13
13
|
attributes :id, :count_on_hand, :stock_location_id, :backorderable
|
14
14
|
attribute :available? => :available
|
15
15
|
|
16
16
|
glue(:stock_location) do
|
17
17
|
attribute :name => :stock_location_name
|
18
18
|
end
|
19
|
-
end
|
19
|
+
end
|
data/config/routes.rb
CHANGED
@@ -31,6 +31,10 @@ Spree::Core::Engine.add_routes do
|
|
31
31
|
get '/orders/mine', :to => 'orders#mine', :as => 'my_orders'
|
32
32
|
|
33
33
|
resources :orders do
|
34
|
+
member do
|
35
|
+
put :apply_coupon_code
|
36
|
+
end
|
37
|
+
|
34
38
|
resources :addresses, :only => [:show, :update]
|
35
39
|
|
36
40
|
resources :return_authorizations do
|
@@ -91,6 +91,12 @@ module Spree
|
|
91
91
|
api_put :update, :id => line_item.id, :line_item => { :quantity => 1000 }
|
92
92
|
expect(order.reload.shipments).to be_empty
|
93
93
|
end
|
94
|
+
|
95
|
+
it "clear out shipments on delete" do
|
96
|
+
expect(order.reload.shipments).not_to be_empty
|
97
|
+
api_delete :destroy, :id => line_item.id
|
98
|
+
expect(order.reload.shipments).to be_empty
|
99
|
+
end
|
94
100
|
end
|
95
101
|
end
|
96
102
|
|
@@ -467,10 +467,13 @@ module Spree
|
|
467
467
|
end
|
468
468
|
|
469
469
|
it "responds with orders updated_at with miliseconds precision" do
|
470
|
+
if ActiveRecord::Base.connection.adapter_name == "Mysql2"
|
471
|
+
pending "MySQL does not support millisecond timestamps."
|
472
|
+
end
|
473
|
+
|
470
474
|
api_get :index
|
471
475
|
milisecond = order.updated_at.strftime("%L")
|
472
476
|
updated_at = json_response["orders"].first["updated_at"]
|
473
|
-
|
474
477
|
expect(updated_at.split("T").last).to have_content(milisecond)
|
475
478
|
end
|
476
479
|
|
@@ -546,6 +549,71 @@ module Spree
|
|
546
549
|
end
|
547
550
|
end
|
548
551
|
end
|
552
|
+
|
553
|
+
describe 'apply_promo_code' do
|
554
|
+
# Borrowed from:
|
555
|
+
# https://github.com/spree/spree/blob/master/api/spec/controllers/spree/api/promotion_application_spec.rb
|
556
|
+
|
557
|
+
let(:order) do
|
558
|
+
order = create(
|
559
|
+
:order_with_line_items,
|
560
|
+
state: 'payment',
|
561
|
+
user: current_api_user,
|
562
|
+
line_items_count: 1
|
563
|
+
)
|
564
|
+
end
|
565
|
+
|
566
|
+
subject do
|
567
|
+
api_put :apply_coupon_code, id: order.to_param, coupon_code: coupon_code, :order_token => order.token
|
568
|
+
end
|
569
|
+
|
570
|
+
context 'when valid promo code' do
|
571
|
+
let(:coupon_code) { 'some_code' }
|
572
|
+
|
573
|
+
# Create a promotion for testing.
|
574
|
+
# https://github.com/spree/spree/blob/2-1-stable/core/spec/lib/spree/promo/coupon_applicator_spec.rb
|
575
|
+
before(:each) do
|
576
|
+
flat_percent_calc = Spree::Calculator::FlatPercentItemTotal.create(:preferred_flat_percent => "10")
|
577
|
+
promo = Spree::Promotion.create(:name => "Discount", :event_name => "spree.checkout.coupon_code_added", :code => coupon_code, :usage_limit => "10", :starts_at => DateTime.yesterday, :expires_at => DateTime.tomorrow)
|
578
|
+
promo_rule = Spree::Promotion::Rules::ItemTotal.create(:preferred_operator => "gt", :preferred_amount => "1")
|
579
|
+
promo_rule.update_attribute(:activator_id, promo.id)
|
580
|
+
promo_action = Spree::Promotion::Actions::CreateAdjustment.create(:calculator_type => "Spree::Calculator::FlatPercentItemTotal")
|
581
|
+
promo_action.update_attribute(:activator_id, promo.id)
|
582
|
+
flat_percent_calc.update_attribute(:calculable_id, promo.id)
|
583
|
+
Spree::Order.any_instance.stub(:payment_required? => false)
|
584
|
+
Spree::Adjustment.any_instance.stub(:eligible => true)
|
585
|
+
end
|
586
|
+
|
587
|
+
it 'should should be_ok' do
|
588
|
+
subject
|
589
|
+
response.should be_ok
|
590
|
+
end
|
591
|
+
|
592
|
+
it 'should have success JSON' do
|
593
|
+
subject
|
594
|
+
result = JSON.parse(response.body)
|
595
|
+
result['successful'].should be_true
|
596
|
+
result['success'].should == "The coupon code was successfully applied to your order."
|
597
|
+
result['error'].should be_nil
|
598
|
+
end
|
599
|
+
end
|
600
|
+
|
601
|
+
context 'when invalid promo code' do
|
602
|
+
let(:coupon_code) { 'xxxxx' }
|
603
|
+
it 'should should be_ok ' do
|
604
|
+
subject
|
605
|
+
response.code.to_i.should == 422
|
606
|
+
end
|
607
|
+
|
608
|
+
it 'should have error JSON' do
|
609
|
+
subject
|
610
|
+
result = JSON.parse(response.body)
|
611
|
+
result['successful'].should be_false
|
612
|
+
result['error'].should == "The coupon code you entered doesn't exist. Please try again."
|
613
|
+
result['success'].should be_nil
|
614
|
+
end
|
615
|
+
end
|
616
|
+
end
|
549
617
|
end
|
550
618
|
end
|
551
619
|
|
@@ -13,6 +13,15 @@ module Spree
|
|
13
13
|
price: 19.99,
|
14
14
|
shipping_category_id: create(:shipping_category).id }
|
15
15
|
end
|
16
|
+
let(:attributes_for_variant) do
|
17
|
+
h = attributes_for(:variant).except(:option_values, :product)
|
18
|
+
h.merge({
|
19
|
+
options: [
|
20
|
+
{ name: "size", value: "small" },
|
21
|
+
{ name: "color", value: "black" }
|
22
|
+
]
|
23
|
+
})
|
24
|
+
end
|
16
25
|
|
17
26
|
before do
|
18
27
|
stub_authentication!
|
@@ -84,6 +93,13 @@ module Spree
|
|
84
93
|
response.body.should =~ /^callback\(.*\)$/
|
85
94
|
response.header['Content-Type'].should include('application/javascript')
|
86
95
|
end
|
96
|
+
|
97
|
+
# Regression test for #4332
|
98
|
+
it "does not escape quotes" do
|
99
|
+
api_get :index, {:callback => 'callback'}
|
100
|
+
response.body.should =~ /^callback\({"count":1,"total_count":1/
|
101
|
+
response.header['Content-Type'].should include('application/javascript')
|
102
|
+
end
|
87
103
|
end
|
88
104
|
|
89
105
|
it "can search for products" do
|
@@ -200,16 +216,6 @@ module Spree
|
|
200
216
|
end
|
201
217
|
|
202
218
|
it "creates with embedded variants" do
|
203
|
-
def attributes_for_variant
|
204
|
-
h = attributes_for(:variant).except(:option_values, :product)
|
205
|
-
h.merge({
|
206
|
-
options: [
|
207
|
-
{ name: "size", value: "small" },
|
208
|
-
{ name: "color", value: "black" }
|
209
|
-
]
|
210
|
-
})
|
211
|
-
end
|
212
|
-
|
213
219
|
product_data.merge!({
|
214
220
|
variants: [attributes_for_variant, attributes_for_variant]
|
215
221
|
})
|
@@ -256,55 +262,6 @@ module Spree
|
|
256
262
|
response.status.should == 201
|
257
263
|
end
|
258
264
|
|
259
|
-
it "creates with embedded variants" do
|
260
|
-
def attributes_for_variant
|
261
|
-
h = attributes_for(:variant).except(:option_values, :product)
|
262
|
-
h.merge({
|
263
|
-
options: [
|
264
|
-
{ name: "size", value: "small" },
|
265
|
-
{ name: "color", value: "black" }
|
266
|
-
]
|
267
|
-
})
|
268
|
-
end
|
269
|
-
|
270
|
-
product_data.merge!({
|
271
|
-
variants: [attributes_for_variant, attributes_for_variant]
|
272
|
-
})
|
273
|
-
|
274
|
-
api_post :create, :product => product_data
|
275
|
-
expect(response.status).to eq 201
|
276
|
-
expect(json_response['variants'].count).to eq(3) # 1 master + 2 variants
|
277
|
-
|
278
|
-
variants = json_response['variants'].select { |v| !v['is_master'] }
|
279
|
-
expect(variants.last['option_values'][0]['name']).to eq('small')
|
280
|
-
expect(variants.last['option_values'][0]['option_type_name']).to eq('size')
|
281
|
-
|
282
|
-
expect(json_response['option_types'].count).to eq(2) # size, color
|
283
|
-
end
|
284
|
-
|
285
|
-
it "can create a new product with embedded product_properties" do
|
286
|
-
product_data.merge!({
|
287
|
-
product_properties_attributes: [{
|
288
|
-
property_name: "fabric",
|
289
|
-
value: "cotton"
|
290
|
-
}]
|
291
|
-
})
|
292
|
-
|
293
|
-
api_post :create, :product => product_data
|
294
|
-
|
295
|
-
expect(json_response['product_properties'][0]['property_name']).to eq('fabric')
|
296
|
-
expect(json_response['product_properties'][0]['value']).to eq('cotton')
|
297
|
-
end
|
298
|
-
|
299
|
-
it "can create a new product with option_types" do
|
300
|
-
product_data.merge!({
|
301
|
-
option_types: ['size', 'color']
|
302
|
-
})
|
303
|
-
|
304
|
-
api_post :create, :product => product_data
|
305
|
-
expect(json_response['option_types'].count).to eq(2)
|
306
|
-
end
|
307
|
-
|
308
265
|
it "creates with shipping categories" do
|
309
266
|
hash = { :name => "The Other Product",
|
310
267
|
:price => 19.99,
|
@@ -363,6 +320,46 @@ module Spree
|
|
363
320
|
response.status.should == 200
|
364
321
|
end
|
365
322
|
|
323
|
+
it "can create new option types on a product" do
|
324
|
+
api_put :update, :id => product.to_param, :product => { :option_types => ['shape', 'color'] }
|
325
|
+
expect(json_response['option_types'].count).to eq(2)
|
326
|
+
end
|
327
|
+
|
328
|
+
it "can create new variants on a product" do
|
329
|
+
api_put :update, :id => product.to_param, :product => { :variants => [attributes_for_variant, attributes_for_variant] }
|
330
|
+
expect(response.status).to eq 200
|
331
|
+
expect(json_response['variants'].count).to eq(3) # 1 master + 2 variants
|
332
|
+
|
333
|
+
variants = json_response['variants'].select { |v| !v['is_master'] }
|
334
|
+
expect(variants.last['option_values'][0]['name']).to eq('small')
|
335
|
+
expect(variants.last['option_values'][0]['option_type_name']).to eq('size')
|
336
|
+
|
337
|
+
expect(json_response['option_types'].count).to eq(2) # size, color
|
338
|
+
end
|
339
|
+
|
340
|
+
it "can update an existing variant on a product" do
|
341
|
+
variant_hash = {
|
342
|
+
:sku => '123', :price => 19.99, :options => [{:name => "size", :value => "small"}]
|
343
|
+
}
|
344
|
+
variant_id = product.variants.create!({ product: product }.merge(variant_hash)).id
|
345
|
+
|
346
|
+
api_put :update, :id => product.to_param, :product => {
|
347
|
+
:variants => [
|
348
|
+
variant_hash.merge(
|
349
|
+
:id => variant_id.to_s,
|
350
|
+
:sku => '456',
|
351
|
+
:options => [{:name => "size", :value => "large" }]
|
352
|
+
)
|
353
|
+
]
|
354
|
+
}
|
355
|
+
|
356
|
+
expect(json_response['variants'].count).to eq(2) # 1 master + 1 variants
|
357
|
+
variants = json_response['variants'].select { |v| !v['is_master'] }
|
358
|
+
expect(variants.last['option_values'][0]['name']).to eq('large')
|
359
|
+
expect(variants.last['sku']).to eq('456')
|
360
|
+
expect(variants.count).to eq(1)
|
361
|
+
end
|
362
|
+
|
366
363
|
it "cannot update a product with an invalid attribute" do
|
367
364
|
api_put :update, :id => product.to_param, :product => { :name => "" }
|
368
365
|
response.status.should == 422
|
@@ -118,7 +118,7 @@ module Spree
|
|
118
118
|
end
|
119
119
|
|
120
120
|
it "can mark a return authorization as received on the order with an inventory unit" do
|
121
|
-
FactoryGirl.create(:new_return_authorization, :order => order)
|
121
|
+
FactoryGirl.create(:new_return_authorization, :order => order, :stock_location_id => order.shipments.first.stock_location.id)
|
122
122
|
return_authorization = order.return_authorizations.first
|
123
123
|
return_authorization.state.should == "authorized"
|
124
124
|
|
@@ -10,9 +10,7 @@ module Spree
|
|
10
10
|
variant.option_values << create(:option_value)
|
11
11
|
variant
|
12
12
|
end
|
13
|
-
let!(:attributes) {
|
14
|
-
:width, :depth, :is_master, :cost_price,
|
15
|
-
:permalink, :description] }
|
13
|
+
let!(:attributes) { Api::ApiHelpers.variant_attributes }
|
16
14
|
|
17
15
|
before do
|
18
16
|
stub_authentication!
|
@@ -254,8 +254,8 @@ module Spree
|
|
254
254
|
|
255
255
|
it 'adds adjustments' do
|
256
256
|
params = { :adjustments_attributes => [
|
257
|
-
{
|
258
|
-
{
|
257
|
+
{ label: 'Shipping Discount', amount: -4.99 },
|
258
|
+
{ label: 'Promotion Discount', amount: -3.00 }] }
|
259
259
|
|
260
260
|
order = Order.build_from_api(user, params)
|
261
261
|
order.adjustments.all?(&:finalized?).should be_true
|
@@ -265,8 +265,8 @@ module Spree
|
|
265
265
|
|
266
266
|
it 'handles adjustment building exceptions' do
|
267
267
|
params = { :adjustments_attributes => [
|
268
|
-
{
|
269
|
-
{
|
268
|
+
{ amount: 'XXX' },
|
269
|
+
{ label: 'Promotion Discount', amount: '-3.00' }] }
|
270
270
|
|
271
271
|
expect {
|
272
272
|
order = Order.build_from_api(user, params)
|
data/spec/spec_helper.rb
CHANGED
data/spree_api.gemspec
CHANGED
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.1.
|
4
|
+
version: 2.1.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: 2014-
|
11
|
+
date: 2014-02-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: spree_core
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.1.
|
19
|
+
version: 2.1.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: 2.1.
|
26
|
+
version: 2.1.5
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rabl
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.9.3
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 0.9.3
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: versioncake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,6 +119,7 @@ files:
|
|
119
119
|
- app/views/spree/api/option_values/index.v1.rabl
|
120
120
|
- app/views/spree/api/option_values/show.v1.rabl
|
121
121
|
- app/views/spree/api/orders/address.v1.rabl
|
122
|
+
- app/views/spree/api/orders/apply_coupon_code.v1.rabl
|
122
123
|
- app/views/spree/api/orders/canceled.v1.rabl
|
123
124
|
- app/views/spree/api/orders/cart.v1.rabl
|
124
125
|
- app/views/spree/api/orders/complete.v1.rabl
|