spree_api 2.1.4 → 2.1.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/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
|