spree_api 2.1.3 → 2.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -11
  3. data/app/controllers/spree/api/addresses_controller.rb +6 -2
  4. data/app/controllers/spree/api/checkouts_controller.rb +7 -3
  5. data/app/controllers/spree/api/line_items_controller.rb +5 -1
  6. data/app/controllers/spree/api/orders_controller.rb +17 -4
  7. data/app/controllers/spree/api/products_controller.rb +78 -4
  8. data/app/controllers/spree/api/properties_controller.rb +9 -3
  9. data/app/helpers/spree/api/api_helpers.rb +2 -4
  10. data/app/models/spree/order_decorator.rb +6 -2
  11. data/app/views/spree/api/addresses/show.v1.rabl +1 -0
  12. data/app/views/spree/api/adjustments/show.v1.rabl +1 -0
  13. data/app/views/spree/api/credit_cards/show.v1.rabl +1 -0
  14. data/app/views/spree/api/line_items/show.v1.rabl +1 -0
  15. data/app/views/spree/api/orders/mine.v1.rabl +9 -0
  16. data/app/views/spree/api/orders/order.v1.rabl +4 -1
  17. data/app/views/spree/api/orders/show.v1.rabl +2 -2
  18. data/app/views/spree/api/products/show.v1.rabl +3 -6
  19. data/app/views/spree/api/shipments/show.v1.rabl +1 -0
  20. data/app/views/spree/api/taxons/index.v1.rabl +4 -2
  21. data/app/views/spree/api/variants/big_variant.v1.rabl +19 -0
  22. data/app/views/spree/api/variants/index.v1.rabl +1 -17
  23. data/app/views/spree/api/variants/show.v1.rabl +1 -0
  24. data/config/routes.rb +3 -1
  25. data/spec/controllers/spree/api/checkouts_controller_spec.rb +13 -12
  26. data/spec/controllers/spree/api/line_items_controller_spec.rb +8 -0
  27. data/spec/controllers/spree/api/orders_controller_spec.rb +76 -5
  28. data/spec/controllers/spree/api/products_controller_spec.rb +185 -33
  29. data/spec/controllers/spree/api/properties_controller_spec.rb +13 -0
  30. data/spec/controllers/spree/api/taxons_controller_spec.rb +52 -17
  31. data/spec/spec_helper.rb +7 -1
  32. metadata +12 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 40032b519232965869e9496c081b35073f3befff
4
- data.tar.gz: 27e40bed61616ece0b4b48f569296a878d855549
3
+ metadata.gz: da64860eaa54da1c5ba845f1fd54be3ec32e8448
4
+ data.tar.gz: 57c74349900a703c6cd975f8122f737f94445eb4
5
5
  SHA512:
6
- metadata.gz: 328477374d05ceee8eaa930ffe6cce7cf379c61cf7398a1655c3e2c82d8647a40984862e7f436ad3456742cdbca0f43cd5f02b9dadb52a197e602b9f1d30748f
7
- data.tar.gz: e82687169737c1f7c6de712fc5bd9076bc894caa961d474972021b1748e5d07e9dcfb5c2d476abbfed69f9ec73a082dd9fd7c93194e92d57b0f1ada388ed2a73
6
+ metadata.gz: 12207992e0a6c2e32c9abdee96f73c730d7458c7cf1deb093ad4c9afb8375fd32d25722c21810e439a5a5e8fdfbe0823d4860599e615e391f525d2bd1ff33041
7
+ data.tar.gz: 70ddcff216eb03cabeb859c3a20f606241885424c54ce8c4608999e34cb5db9db0b14ce768181f4e8224005ac4d05b52f03811dd2f7e4479bd3f35853cd3c581
@@ -1,18 +1,29 @@
1
- ## Spree 2.1.3 ##
1
+ ## Spree 2.1.4 (unreleased) ##
2
2
 
3
- * ApiHelpers attributes can now be extended without overriding instance
4
- methods. By using the same approach in PermittedAttributes. e.g.
3
+ * Cached products/show template, which can lead to drastically (65x) faster loading times on product requests.
5
4
 
6
- Spree::Api::ApiHelpers.order_attributes.push :locked_at
7
-
8
- Washington Luiz
5
+ Ryan Bigg
9
6
 
10
- * Admin users can set the order channel when importing orders. By sing the
11
- channel attribute on Order model
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
12
8
 
13
- Washington Luiz
9
+ Ryan Bigg
14
10
 
15
- * An order's shipments are now destroyed (to be recreated) when an order is assigned a new line item through the API. #3914
11
+ * Cached variant objects which can lead to slightly faster loading times (4x) for each variant.
16
12
 
17
- Washington Luiz
13
+ Ryan Bigg
18
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)
@@ -4,13 +4,13 @@ module Spree
4
4
  before_filter :find_order
5
5
 
6
6
  def show
7
- authorize! :read, @order, params[:order_token]
7
+ authorize! :read, @order, order_token
8
8
  find_address
9
9
  respond_with(@address)
10
10
  end
11
11
 
12
12
  def update
13
- authorize! :update, @order, params[:order_token]
13
+ authorize! :update, @order, order_token
14
14
  find_address
15
15
 
16
16
  if @address.update_attributes(address_params)
@@ -38,6 +38,10 @@ module Spree
38
38
  raise CanCan::AccessDenied
39
39
  end
40
40
  end
41
+
42
+ def order_token
43
+ request.headers["X-Spree-Order-Token"] || params[:order_token]
44
+ end
41
45
  end
42
46
  end
43
47
  end
@@ -16,7 +16,7 @@ module Spree
16
16
  end
17
17
 
18
18
  def next
19
- authorize! :update, @order, params[:order_token]
19
+ authorize! :update, @order, order_token
20
20
  @order.next!
21
21
  respond_with(@order, default_template: 'spree/api/orders/show', status: 200)
22
22
  rescue StateMachine::InvalidTransition
@@ -24,7 +24,7 @@ module Spree
24
24
  end
25
25
 
26
26
  def advance
27
- authorize! :update, @order, params[:order_token]
27
+ authorize! :update, @order, order_token
28
28
  while @order.next; end
29
29
  respond_with(@order, default_template: 'spree/api/orders/show', status: 200)
30
30
  end
@@ -34,7 +34,7 @@ module Spree
34
34
  end
35
35
 
36
36
  def update
37
- authorize! :update, @order, params[:order_token]
37
+ authorize! :update, @order, order_token
38
38
  order_params = object_params
39
39
  line_items = order_params.delete('line_items_attributes')
40
40
  if @order.update_attributes(order_params)
@@ -131,6 +131,10 @@ module Spree
131
131
  end
132
132
  false
133
133
  end
134
+
135
+ def order_token
136
+ request.headers["X-Spree-Order-Token"] || params[:order_token]
137
+ end
134
138
  end
135
139
  end
136
140
  end
@@ -33,12 +33,16 @@ module Spree
33
33
 
34
34
  def order
35
35
  @order ||= Spree::Order.find_by!(number: params[:order_id])
36
- authorize! :update, @order, params[:order_token]
36
+ authorize! :update, @order, order_token
37
37
  end
38
38
 
39
39
  def line_item_params
40
40
  params.require(:line_item).permit(:quantity, :variant_id)
41
41
  end
42
+
43
+ def order_token
44
+ request.headers["X-Spree-Order-Token"] || params[:order_token]
45
+ end
42
46
  end
43
47
  end
44
48
  end
@@ -60,13 +60,22 @@ module Spree
60
60
  invalid_resource!(@order)
61
61
  end
62
62
  end
63
+
64
+ def mine
65
+ if current_api_user.persisted?
66
+ @orders = current_api_user.orders.ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
67
+ else
68
+ render "spree/api/errors/unauthorized", status: :unauthorized
69
+ end
70
+ end
63
71
 
64
72
  private
65
73
  def deal_with_line_items
66
- line_item_attributes = params[:order][:line_items].map do |id, attributes|
67
- [id, attributes.slice(*permitted_line_item_attributes)]
74
+ line_item_attributes = params[:order][:line_items]
75
+ line_item_attributes.each_key do |key|
76
+ # need to call .to_hash to make sure Rails 4's strong parameters don't bite
77
+ line_item_attributes[key] = line_item_attributes[key].slice(*permitted_line_item_attributes).to_hash
68
78
  end
69
- line_item_attributes = Hash[line_item_attributes].delete_if { |k,v| v.empty? }
70
79
  @order.update_line_items(line_item_attributes)
71
80
  end
72
81
 
@@ -118,12 +127,16 @@ module Spree
118
127
 
119
128
  def find_order
120
129
  @order = Spree::Order.find_by!(number: params[:id])
121
- authorize! :update, @order, params[:order_token]
130
+ authorize! :update, @order, order_token
122
131
  end
123
132
 
124
133
  def before_delivery
125
134
  @order.create_proposed_shipments
126
135
  end
136
+
137
+ def order_token
138
+ request.headers["X-Spree-Order-Token"] || params[:order_token]
139
+ end
127
140
  end
128
141
  end
129
142
  end
@@ -18,15 +18,61 @@ module Spree
18
18
  respond_with(@product)
19
19
  end
20
20
 
21
- def new
22
- end
23
-
21
+ # Takes besides the products attributes either an array of variants or
22
+ # an array of option types.
23
+ #
24
+ # By submitting an array of variants the option types will be created
25
+ # using the *name* key in options hash. e.g
26
+ #
27
+ # product: {
28
+ # ...
29
+ # variants: {
30
+ # price: 19.99,
31
+ # sku: "hey_you",
32
+ # options: [
33
+ # { name: "size", value: "small" },
34
+ # { name: "color", value: "black" }
35
+ # ]
36
+ # }
37
+ # }
38
+ #
39
+ # Or just pass in the option types hash:
40
+ #
41
+ # product: {
42
+ # ...
43
+ # option_types: ['size', 'color']
44
+ # }
45
+ #
46
+ # By passing the shipping category name you can fetch or create that
47
+ # shipping category on the fly. e.g.
48
+ #
49
+ # product: {
50
+ # ...
51
+ # shipping_category: "Free Shipping Items"
52
+ # }
53
+ #
24
54
  def create
25
55
  authorize! :create, Product
26
56
  params[:product][:available_on] ||= Time.now
57
+ set_up_shipping_category
58
+
27
59
  begin
28
60
  @product = Product.new(product_params)
29
61
  if @product.save
62
+ variants_params.each do |variant_attribute|
63
+ # make sure the product is assigned before the options=
64
+ @product.variants.create({ product: @product }.merge(variant_attribute))
65
+ end
66
+
67
+ option_types_params.each do |name|
68
+ option_type = OptionType.where(name: name).first_or_initialize do |option_type|
69
+ option_type.presentation = name
70
+ option_type.save!
71
+ end
72
+
73
+ @product.option_types << option_type unless @product.option_types.include?(option_type)
74
+ end
75
+
30
76
  respond_with(@product, :status => 201, :default_template => :show)
31
77
  else
32
78
  invalid_resource!(@product)
@@ -40,6 +86,7 @@ module Spree
40
86
  def update
41
87
  @product = find_product(params[:id])
42
88
  authorize! :update, @product
89
+
43
90
  if @product.update_attributes(product_params)
44
91
  respond_with(@product, :status => 200, :default_template => :show)
45
92
  else
@@ -57,7 +104,34 @@ module Spree
57
104
 
58
105
  private
59
106
  def product_params
60
- params.require(:product).permit(permitted_product_attributes)
107
+ product_params = params.require(:product).permit(permitted_product_attributes)
108
+ if product_params[:taxon_ids].present?
109
+ product_params[:taxon_ids] = product_params[:taxon_ids].split(',')
110
+ end
111
+ product_params
112
+ end
113
+
114
+ def variants_params
115
+ variants_key = if params[:product].has_key? :variants
116
+ :variants
117
+ else
118
+ :variants_attributes
119
+ end
120
+
121
+ params.require(:product).permit(
122
+ variants_key => permitted_variant_attributes,
123
+ ).delete(variants_key) || []
124
+ end
125
+
126
+ def option_types_params
127
+ params[:product].fetch(:option_types, [])
128
+ end
129
+
130
+ def set_up_shipping_category
131
+ if shipping_category = params[:product].delete(:shipping_category)
132
+ id = ShippingCategory.find_or_create_by(name: shipping_category).id
133
+ params[:product][:shipping_category_id] = id
134
+ end
61
135
  end
62
136
  end
63
137
  end
@@ -5,9 +5,15 @@ module Spree
5
5
  before_filter :find_property, only: [:show, :update, :destroy]
6
6
 
7
7
  def index
8
- @properties = Spree::Property.accessible_by(current_ability, :read).
9
- ransack(params[:q]).result.
10
- page(params[:page]).per(params[:per_page])
8
+ @properties = Spree::Property.accessible_by(current_ability, :read)
9
+
10
+ if params[:ids]
11
+ @properties = @properties.where(:id => params[:ids].split(","))
12
+ else
13
+ @properties = @properties.ransack(params[:q]).result
14
+ end
15
+
16
+ @properties = @properties.page(params[:page]).per(params[:per_page])
11
17
  respond_with(@properties)
12
18
  end
13
19
 
@@ -21,10 +21,8 @@ module Spree
21
21
  :country_attributes,
22
22
  :state_attributes,
23
23
  :adjustment_attributes,
24
- :taxon_attributes,
25
24
  :inventory_unit_attributes,
26
25
  :return_authorization_attributes,
27
- :adjustment_attributes,
28
26
  :creditcard_attributes,
29
27
  :user_attributes,
30
28
  :property_attributes,
@@ -73,7 +71,7 @@ module Spree
73
71
  @@order_attributes = [
74
72
  :id, :number, :item_total, :total, :ship_total, :state, :adjustment_total,
75
73
  :user_id, :created_at, :updated_at, :completed_at, :payment_total,
76
- :shipment_state, :payment_state, :email, :special_instructions, :channel
74
+ :shipment_state, :payment_state, :email, :special_instructions, :channel, :tax_total
77
75
  ]
78
76
 
79
77
  @@line_item_attributes = [:id, :quantity, :price, :variant_id]
@@ -93,7 +91,7 @@ module Spree
93
91
  @@taxonomy_attributes = [:id, :name]
94
92
 
95
93
  @@taxon_attributes = [
96
- :id, :name, :pretty_name, :permalink, :position, :parent_id,
94
+ :id, :name, :pretty_name, :permalink, :parent_id,
97
95
  :taxonomy_id
98
96
  ]
99
97
 
@@ -167,8 +167,12 @@ Spree::Order.class_eval do
167
167
 
168
168
  def update_line_items(line_item_params)
169
169
  return if line_item_params.blank?
170
- line_item_params.each do |id, attributes|
171
- self.line_items.find(id).update_attributes!(attributes)
170
+ line_item_params.each_value do |attributes|
171
+ if attributes[:id].present?
172
+ self.line_items.find(attributes[:id]).update_attributes!(attributes)
173
+ else
174
+ self.line_items.create!(attributes)
175
+ end
172
176
  end
173
177
  self.ensure_updated_shipments
174
178
  end
@@ -1,4 +1,5 @@
1
1
  object @address
2
+ cache @address
2
3
  attributes *address_attributes
3
4
 
4
5
  child(:country) do |address|
@@ -1,3 +1,4 @@
1
1
  object @adjustment
2
+ cache @adjustment
2
3
  attributes *adjustment_attributes
3
4
  node(:display_amount) { |a| a.display_amount.to_s }
@@ -1,2 +1,3 @@
1
1
  object @credit_card
2
+ cache @credit_card
2
3
  attributes *creditcard_attributes
@@ -1,4 +1,5 @@
1
1
  object @line_item
2
+ cache @line_item
2
3
  attributes *line_item_attributes
3
4
  node(:single_display_amount) { |li| li.single_display_amount.to_s }
4
5
  node(:display_amount) { |li| li.display_amount.to_s }
@@ -0,0 +1,9 @@
1
+ object false
2
+
3
+ child(@orders => :orders) do
4
+ extends "spree/api/orders/show"
5
+ end
6
+
7
+ node(:count) { @orders.count }
8
+ node(:current_page) { params[:page] || 1 }
9
+ node(:pages) { @orders.num_pages }
@@ -1,6 +1,9 @@
1
+ cache @order
1
2
  attributes *order_attributes
2
3
  node(:display_item_total) { |o| o.display_item_total.to_s }
3
4
  node(:total_quantity) { |o| o.line_items.sum(:quantity) }
5
+ node(:display_tax_total) { |o| o.display_tax_total }
4
6
  node(:display_total) { |o| o.display_total.to_s }
7
+ node(:display_ship_total) { |o| o.display_ship_total }
5
8
  node(:token) { |o| o.token }
6
- node(:checkout_steps) { |o| o.checkout_steps }
9
+ node(:checkout_steps) { |o| o.checkout_steps }
@@ -1,8 +1,8 @@
1
1
  object @order
2
2
  extends "spree/api/orders/order"
3
3
 
4
- if lookup_context.find_all("spree/api/orders/#{@order.state}").present?
5
- extends "spree/api/orders/#{@order.state}"
4
+ if lookup_context.find_all("spree/api/orders/#{root_object.state}").present?
5
+ extends "spree/api/orders/#{root_object.state}"
6
6
  end
7
7
 
8
8
  child :billing_address => :bill_address do
@@ -1,11 +1,12 @@
1
1
  object @product
2
+ cache @product
2
3
  attributes *product_attributes
3
4
  node(:display_price) { |p| p.display_price.to_s }
4
5
  child :variants_including_master => :variants do
5
6
  attributes *variant_attributes
6
7
 
7
8
  child :option_values => :option_values do
8
- attributes *option_value_attributes
9
+ extends "spree/api/option_values/show"
9
10
  end
10
11
 
11
12
  child :images => :images do
@@ -14,11 +15,7 @@ child :variants_including_master => :variants do
14
15
  end
15
16
 
16
17
  child :option_types => :option_types do
17
- attributes *option_type_attributes
18
-
19
- child :option_values => :option_values do
20
- attributes *option_value_attributes
21
- end
18
+ extends "spree/api/option_types/show"
22
19
  end
23
20
 
24
21
  child :product_properties => :product_properties do
@@ -1,4 +1,5 @@
1
1
  object @shipment
2
+ cache @shipment
2
3
  attributes *shipment_attributes
3
4
  node(:order_id) { |shipment| shipment.order.number }
4
5
  node(:stock_location_name) { |shipment| shipment.stock_location.name }
@@ -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(@taxons) do
7
+ child @taxons => :taxons do
8
8
  attributes *taxon_attributes
9
- extends "spree/api/taxons/taxons"
9
+ unless params[:without_children]
10
+ extends "spree/api/taxons/taxons"
11
+ end
10
12
  end
@@ -0,0 +1,19 @@
1
+ object @variant
2
+ cache @variant
3
+ attributes *variant_attributes
4
+ extends "spree/api/variants/variant"
5
+ child(:images => :images) do
6
+ attributes *image_attributes
7
+ code(:urls) do |v|
8
+ v.attachment.styles.keys.inject({}) { |urls, style| urls[style] = v.attachment.url(style); urls }
9
+ end
10
+ end
11
+
12
+ child(:stock_items) do
13
+ attributes :id, :count_on_hand, :stock_location_id, :backorderable
14
+ attribute :available? => :available
15
+
16
+ glue(:stock_location) do
17
+ attribute :name => :stock_location_name
18
+ end
19
+ end
@@ -5,21 +5,5 @@ node(:current_page) { params[:page] ? params[:page].to_i : 1 }
5
5
  node(:pages) { @variants.num_pages }
6
6
 
7
7
  child(@variants => :variants) do
8
- attributes *variant_attributes
9
- child(:option_values => :option_values) { attributes *option_value_attributes }
10
- child(:images => :images) do
11
- attributes *image_attributes
12
- code(:urls) do |v|
13
- v.attachment.styles.keys.inject({}) { |urls, style| urls[style] = v.attachment.url(style); urls }
14
- end
15
- end
16
-
17
- child(:stock_items) do
18
- attributes :id, :count_on_hand, :stock_location_id, :backorderable
19
- attribute :available? => :available
20
-
21
- glue(:stock_location) do
22
- attribute :name => :stock_location_name
23
- end
24
- end
8
+ extends "spree/api/variants/big_variant"
25
9
  end
@@ -1,4 +1,5 @@
1
1
  object @variant
2
+ cache @variant
2
3
  extends "spree/api/variants/variant"
3
4
  child(:option_values => :option_values) { attributes *option_value_attributes }
4
5
  child(:images => :images) { extends "spree/api/images/show" }
@@ -22,12 +22,14 @@ Spree::Core::Engine.add_routes do
22
22
  end
23
23
  end
24
24
 
25
- resources :variants, :only => [:index]
25
+ resources :variants, :only => [:index, :show]
26
26
 
27
27
  resources :option_types do
28
28
  resources :option_values
29
29
  end
30
30
 
31
+ get '/orders/mine', :to => 'orders#mine', :as => 'my_orders'
32
+
31
33
  resources :orders do
32
34
  resources :addresses, :only => [:show, :update]
33
35
 
@@ -38,7 +38,7 @@ module Spree
38
38
  end
39
39
 
40
40
  context "PUT 'update'" do
41
- let(:order) do
41
+ let(:order) do
42
42
  order = create(:order_with_line_items)
43
43
  # Order should be in a pristine state
44
44
  # Without doing this, the order may transition from 'cart' straight to 'delivery'
@@ -52,27 +52,25 @@ module Spree
52
52
  Order.any_instance.stub(:payment_required? => true)
53
53
  end
54
54
 
55
- it "will return an error if the recently created order cannot transition from cart to address" do
55
+ it "should transition a recently created order from cart to address" do
56
56
  order.state.should eq "cart"
57
- order.update_column(:email, nil) # email is necessary to transition from cart to address
58
-
57
+ order.email.should_not be_nil
59
58
  api_put :update, :id => order.to_param, :order_token => order.token
60
-
61
- # Order has not transitioned
62
- json_response['state'].should == 'cart'
59
+ order.reload.state.should eq "address"
63
60
  end
64
61
 
65
- it "should transition a recently created order from cart to address" do
62
+ it "should transition a recently created order from cart to address with order token in header" do
66
63
  order.state.should eq "cart"
67
64
  order.email.should_not be_nil
68
- api_put :update, :id => order.to_param, :order_token => order.token
65
+ request.headers["X-Spree-Order-Token"] = order.token
66
+ api_put :update, :id => order.to_param
69
67
  order.reload.state.should eq "address"
70
68
  end
71
69
 
72
70
  it "can take line_items_attributes as a parameter" do
73
71
  line_item = order.line_items.first
74
72
  api_put :update, :id => order.to_param, :order_token => order.token,
75
- :order => { :line_items_attributes => { line_item.id => { :quantity => 1 } } }
73
+ :order => { :line_items_attributes => { 0 => { :id => line_item.id, :quantity => 1 } } }
76
74
  response.status.should == 200
77
75
  order.reload.state.should eq "address"
78
76
  end
@@ -80,7 +78,7 @@ module Spree
80
78
  it "can take line_items as a parameter" do
81
79
  line_item = order.line_items.first
82
80
  api_put :update, :id => order.to_param, :order_token => order.token,
83
- :order => { :line_items => { line_item.id => { :quantity => 1 } } }
81
+ :order => { :line_items => { 0 => { :id => line_item.id, :quantity => 1 } } }
84
82
  response.status.should == 200
85
83
  order.reload.state.should eq "address"
86
84
  end
@@ -251,7 +249,10 @@ module Spree
251
249
  end
252
250
 
253
251
  it "cannot transition if order email is blank" do
254
- order.update_column(:email, nil)
252
+ order.update_columns(
253
+ state: 'address',
254
+ email: nil
255
+ )
255
256
 
256
257
  api_put :next, :id => order.to_param, :order_token => order.token
257
258
  response.status.should == 422
@@ -28,6 +28,14 @@ module Spree
28
28
  json_response.should have_attributes(attributes)
29
29
  json_response["variant"]["name"].should_not be_blank
30
30
  end
31
+
32
+ it "can add a new line item to an existing order with token in header" do
33
+ request.headers["X-Spree-Order-Token"] = order.token
34
+ api_post :create, :line_item => { :variant_id => product.master.to_param, :quantity => 1 }
35
+ response.status.should == 201
36
+ json_response.should have_attributes(attributes)
37
+ json_response["variant"]["name"].should_not be_blank
38
+ end
31
39
  end
32
40
 
33
41
  context "as the order owner" do
@@ -6,6 +6,7 @@ module Spree
6
6
 
7
7
  let!(:order) { create(:order) }
8
8
  let(:variant) { create(:variant) }
9
+ let(:line_item) { create(:line_item) }
9
10
 
10
11
  let(:attributes) { [:number, :item_total, :display_total, :total,
11
12
  :state, :adjustment_total,
@@ -41,6 +42,40 @@ module Spree
41
42
  assert_unauthorized!
42
43
  end
43
44
 
45
+ context "the current api user is not persisted" do
46
+ let(:current_api_user) { double(persisted?: false) }
47
+
48
+ it "returns a 401" do
49
+ api_get :mine
50
+
51
+ response.status.should == 401
52
+ end
53
+ end
54
+
55
+ context "the current api user is authenticated" do
56
+ let(:current_api_user) { order.user }
57
+ let(:order) { create(:order, line_items: [line_item]) }
58
+
59
+ it "can view all of their own orders" do
60
+ api_get :mine
61
+
62
+ response.status.should == 200
63
+ json_response["pages"].should == 1
64
+ json_response["current_page"].should == 1
65
+ json_response["orders"].length.should == 1
66
+ json_response["orders"].first["number"].should == order.number
67
+ json_response["orders"].first["line_items"].length.should == 1
68
+ json_response["orders"].first["line_items"].first["id"].should == line_item.id
69
+ end
70
+
71
+ it "can filter the returned results" do
72
+ api_get :mine, q: {completed_at_not_null: 1}
73
+
74
+ response.status.should == 200
75
+ json_response["orders"].length.should == 0
76
+ end
77
+ end
78
+
44
79
  it "can view their own order" do
45
80
  Order.any_instance.stub :user => current_api_user
46
81
  api_get :show, :id => order.to_param
@@ -75,6 +110,12 @@ module Spree
75
110
  response.status.should == 200
76
111
  end
77
112
 
113
+ it "can view an order if the token is passed in header" do
114
+ request.headers["X-Spree-Order-Token"] = order.token
115
+ api_get :show, :id => order.to_param
116
+ response.status.should == 200
117
+ end
118
+
78
119
  it "cannot cancel an order that doesn't belong to them" do
79
120
  order.update_attribute(:completed_at, Time.now)
80
121
  order.update_attribute(:shipment_state, "ready")
@@ -109,7 +150,7 @@ module Spree
109
150
  line_item.should_receive(:update_attributes).with("special" => true)
110
151
 
111
152
  controller.stub(permitted_line_item_attributes: [:id, :variant_id, :quantity, :special])
112
- api_post :create, :order => {
153
+ api_post :create, :order => {
113
154
  :line_items => {
114
155
  "0" => {
115
156
  :variant_id => variant.to_param, :quantity => 5, :special => true
@@ -179,7 +220,7 @@ module Spree
179
220
  order.stub(:associate_user!)
180
221
  order.stub_chain(:contents, :add).and_return(line_item = double('LineItem'))
181
222
  line_item.should_not_receive(:update_attributes)
182
- api_post :create, :order => {
223
+ api_post :create, :order => {
183
224
  :line_items => {
184
225
  "0" => {
185
226
  :variant_id => variant.to_param, :quantity => 5
@@ -237,7 +278,7 @@ module Spree
237
278
  it "updates quantities of existing line items" do
238
279
  api_put :update, :id => order.to_param, :order => {
239
280
  :line_items => {
240
- line_item.id => { :quantity => 10 }
281
+ 0 => { :id => line_item.id, :quantity => 10 }
241
282
  }
242
283
  }
243
284
 
@@ -246,10 +287,26 @@ module Spree
246
287
  json_response['line_items'].first['quantity'].should == 10
247
288
  end
248
289
 
290
+ it "adds an extra line item" do
291
+ variant2 = create(:variant)
292
+ api_put :update, :id => order.to_param, :order => {
293
+ :line_items => {
294
+ 0 => { :id => line_item.id, :quantity => 10 },
295
+ 1 => { :variant_id => variant2.id, :quantity => 1}
296
+ }
297
+ }
298
+
299
+ response.status.should == 200
300
+ json_response['line_items'].count.should == 2
301
+ json_response['line_items'][0]['quantity'].should == 10
302
+ json_response['line_items'][1]['variant_id'].should == variant2.id
303
+ json_response['line_items'][1]['quantity'].should == 1
304
+ end
305
+
249
306
  it "cannot change the price of an existing line item" do
250
307
  api_put :update, :id => order.to_param, :order => {
251
308
  :line_items => {
252
- line_item.id => { :price => 0 }
309
+ 0 => { :id => line_item.id, :price => 0 }
253
310
  }
254
311
  }
255
312
 
@@ -301,7 +358,7 @@ module Spree
301
358
  previous_shipments = order.shipments
302
359
  api_put :update, :id => order.to_param, :order => {
303
360
  :line_items => {
304
- line_item.id => { :quantity => 10 }
361
+ 0 => { :id => line_item.id, :quantity => 10 }
305
362
  }
306
363
  }
307
364
  expect(order.reload.shipments).to be_empty
@@ -338,6 +395,13 @@ module Spree
338
395
  json_response['line_items'].first['variant'].should have_attributes([:product_id])
339
396
  end
340
397
 
398
+ it "includes the tax_total in the response" do
399
+ api_get :show, :id => order.to_param
400
+
401
+ json_response['tax_total'].should == '0.0'
402
+ json_response['display_tax_total'].should == '$0.00'
403
+ end
404
+
341
405
  context "when in delivery" do
342
406
  let!(:shipping_method) do
343
407
  FactoryGirl.create(:shipping_method).tap do |shipping_method|
@@ -352,6 +416,13 @@ module Spree
352
416
  order.save
353
417
  end
354
418
 
419
+ it "includes the ship_total in the response" do
420
+ api_get :show, :id => order.to_param
421
+
422
+ json_response['ship_total'].should == '10.0'
423
+ json_response['display_ship_total'].should == '$10.00'
424
+ end
425
+
355
426
  it "returns available shipments for an order" do
356
427
  api_get :show, :id => order.to_param
357
428
  response.status.should == 200
@@ -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, :display_price, :available_on, :permalink, :meta_description, :meta_keywords, :shipping_category_id, :taxon_ids] }
11
+ let(:product_data) 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!
@@ -155,6 +160,9 @@ module Spree
155
160
  end
156
161
 
157
162
  context "as an admin" do
163
+ let(:taxon_1) { create(:taxon) }
164
+ let(:taxon_2) { create(:taxon) }
165
+
158
166
  sign_in_as_admin!
159
167
 
160
168
  it "can see all products" do
@@ -182,53 +190,197 @@ module Spree
182
190
  end
183
191
  end
184
192
 
185
- it "can create a new product" do
186
- api_post :create, :product => { :name => "The Other Product",
187
- :price => 19.99,
188
- :shipping_category_id => create(:shipping_category).id }
189
- json_response.should have_attributes(attributes)
190
- response.status.should == 201
191
- end
193
+ describe "creating a product" do
194
+ it "can create a new product" do
195
+ api_post :create, :product => { :name => "The Other Product",
196
+ :price => 19.99,
197
+ :shipping_category_id => create(:shipping_category).id }
198
+ json_response.should have_attributes(attributes)
199
+ response.status.should == 201
200
+ end
192
201
 
193
- # Regression test for #2140
194
- context "with authentication_required set to false" do
195
- before do
196
- Spree::Api::Config.requires_authentication = false
202
+ 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
+ product_data.merge!({
214
+ variants: [attributes_for_variant, attributes_for_variant]
215
+ })
216
+
217
+ api_post :create, :product => product_data
218
+ expect(response.status).to eq 201
219
+ expect(json_response['variants'].count).to eq(3) # 1 master + 2 variants
220
+
221
+ variants = json_response['variants'].select { |v| !v['is_master'] }
222
+ expect(variants.last['option_values'][0]['name']).to eq('small')
223
+ expect(variants.last['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 "can create a new product with embedded product_properties" do
229
+ product_data.merge!({
230
+ product_properties_attributes: [{
231
+ property_name: "fabric",
232
+ value: "cotton"
233
+ }]
234
+ })
235
+
236
+ api_post :create, :product => product_data
237
+
238
+ expect(json_response['product_properties'][0]['property_name']).to eq('fabric')
239
+ expect(json_response['product_properties'][0]['value']).to eq('cotton')
197
240
  end
198
241
 
199
- after do
200
- Spree::Api::Config.requires_authentication = true
242
+ it "can create a new product with option_types" do
243
+ product_data.merge!({
244
+ option_types: ['size', 'color']
245
+ })
246
+
247
+ api_post :create, :product => product_data
248
+ expect(json_response['option_types'].count).to eq(2)
201
249
  end
202
250
 
203
- it "can still create a product" do
251
+ it "can create a new product" do
204
252
  api_post :create, :product => { :name => "The Other Product",
205
253
  :price => 19.99,
206
- :shipping_category_id => create(:shipping_category).id },
207
- :token => "fake"
254
+ :shipping_category_id => create(:shipping_category).id }
208
255
  json_response.should have_attributes(attributes)
209
256
  response.status.should == 201
210
257
  end
211
- end
212
258
 
213
- it "cannot create a new product with invalid attributes" do
214
- api_post :create, :product => {}
215
- response.status.should == 422
216
- json_response["error"].should == "Invalid resource. Please fix errors and try again."
217
- errors = json_response["errors"]
218
- errors.delete("permalink") # Don't care about this one.
219
- errors.keys.should =~ ["name", "price", "shipping_category_id"]
220
- end
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
221
298
 
222
- it "can update a product" do
223
- api_put :update, :id => product.to_param, :product => { :name => "New and Improved Product!" }
224
- response.status.should == 200
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
+ it "creates with shipping categories" do
309
+ hash = { :name => "The Other Product",
310
+ :price => 19.99,
311
+ :shipping_category => "Free Ships" }
312
+
313
+ api_post :create, :product => hash
314
+ expect(response.status).to eq 201
315
+
316
+ shipping_id = ShippingCategory.find_by_name("Free Ships").id
317
+ expect(json_response['shipping_category_id']).to eq shipping_id
318
+ end
319
+
320
+ it "puts the created product in the given taxon" do
321
+ product_data[:taxon_ids] = taxon_1.id.to_s
322
+ api_post :create, :product => product_data
323
+ expect(json_response["taxon_ids"]).to eq([taxon_1.id,])
324
+ end
325
+
326
+ # Regression test for #4123
327
+ it "puts the created product in the given taxons" do
328
+ product_data[:taxon_ids] = [taxon_1.id, taxon_2.id].join(',')
329
+ api_post :create, :product => product_data
330
+ expect(json_response["taxon_ids"]).to eq([taxon_1.id, taxon_2.id])
331
+ end
332
+
333
+ # Regression test for #2140
334
+ context "with authentication_required set to false" do
335
+ before do
336
+ Spree::Api::Config.requires_authentication = false
337
+ end
338
+
339
+ after do
340
+ Spree::Api::Config.requires_authentication = true
341
+ end
342
+
343
+ it "can still create a product" do
344
+ api_post :create, :product => product_data, :token => "fake"
345
+ json_response.should have_attributes(attributes)
346
+ response.status.should == 201
347
+ end
348
+ end
349
+
350
+ it "cannot create a new product with invalid attributes" do
351
+ api_post :create, :product => {}
352
+ response.status.should == 422
353
+ json_response["error"].should == "Invalid resource. Please fix errors and try again."
354
+ errors = json_response["errors"]
355
+ errors.delete("permalink") # Don't care about this one.
356
+ errors.keys.should =~ ["name", "price", "shipping_category_id"]
357
+ end
225
358
  end
226
359
 
227
- it "cannot update a product with an invalid attribute" do
228
- api_put :update, :id => product.to_param, :product => { :name => "" }
229
- response.status.should == 422
230
- json_response["error"].should == "Invalid resource. Please fix errors and try again."
231
- json_response["errors"]["name"].should == ["can't be blank"]
360
+ context 'updating a product' do
361
+ it "can update a product" do
362
+ api_put :update, :id => product.to_param, :product => { :name => "New and Improved Product!" }
363
+ response.status.should == 200
364
+ end
365
+
366
+ it "cannot update a product with an invalid attribute" do
367
+ api_put :update, :id => product.to_param, :product => { :name => "" }
368
+ response.status.should == 422
369
+ json_response["error"].should == "Invalid resource. Please fix errors and try again."
370
+ json_response["errors"]["name"].should == ["can't be blank"]
371
+ end
372
+
373
+ # Regression test for #4123
374
+ it "puts the created product in the given taxon" do
375
+ api_put :update, :id => product.to_param, :product => {:taxon_ids => taxon_1.id.to_s}
376
+ expect(json_response["taxon_ids"]).to eq([taxon_1.id,])
377
+ end
378
+
379
+ # Regression test for #4123
380
+ it "puts the created product in the given taxons" do
381
+ api_put :update, :id => product.to_param, :product => {:taxon_ids => [taxon_1.id, taxon_2.id].join(',')}
382
+ expect(json_response["taxon_ids"]).to eq([taxon_1.id, taxon_2.id])
383
+ end
232
384
  end
233
385
 
234
386
  it "can delete a product" do
@@ -31,6 +31,19 @@ module Spree
31
31
  json_response['properties'].first['presentation'].should eq property_2.presentation
32
32
  end
33
33
 
34
+ it "retrieves a list of properties by id" do
35
+ api_get :index, :ids => [property_1.id]
36
+ json_response["properties"].first.should have_attributes(attributes)
37
+ json_response["count"].should == 1
38
+ end
39
+
40
+ it "retrieves a list of properties by ids string" do
41
+ api_get :index, :ids => [property_1.id, property_2.id].join(",")
42
+ json_response["properties"].first.should have_attributes(attributes)
43
+ json_response["properties"][1].should have_attributes(attributes)
44
+ json_response["count"].should == 2
45
+ end
46
+
34
47
  it "can see a single property" do
35
48
  api_get :show, :id => property_1.id
36
49
  json_response.should have_attributes(attributes)
@@ -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
- it "gets all taxons" do
43
- api_get :index
44
-
45
- json_response['taxons'].first['name'].should eq taxonomy.root.name
46
- children = json_response['taxons'].first['taxons']
47
- children.count.should eq 1
48
- children.first['name'].should eq taxon.name
49
- children.first['taxons'].count.should eq 1
50
- end
51
-
52
- it "can search for a single taxon" do
53
- api_get :index, :q => { :name_cont => "Ruby" }
54
-
55
- json_response['taxons'].count.should == 1
56
- json_response['taxons'].first['name'].should eq "Ruby"
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
@@ -71,8 +100,6 @@ module Spree
71
100
  response["state"].should eq("closed")
72
101
  end
73
102
 
74
-
75
-
76
103
  it "can learn how to create a new taxon" do
77
104
  api_get :new, :taxonomy_id => taxonomy.id
78
105
  json_response["attributes"].should == attributes.map(&:to_s)
@@ -111,6 +138,14 @@ module Spree
111
138
  taxon.taxonomy_id.should eq taxonomy.id
112
139
  end
113
140
 
141
+ it "can update the position in the list" do
142
+ taxonomy.root.children << taxon2
143
+ api_put :update, :taxonomy_id => taxonomy.id, :id => taxon.id, :taxon => {:parent_id => taxon.parent_id, :child_index => 2 }
144
+ response.status.should == 200
145
+ taxonomy.reload.root.children[0].should eql taxon2
146
+ taxonomy.reload.root.children[1].should eql taxon
147
+ end
148
+
114
149
  it "cannot create a new taxon with invalid attributes" do
115
150
  api_post :create, :taxonomy_id => taxonomy.id, :taxon => {}
116
151
  response.status.should == 422
@@ -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
- require File.expand_path("../dummy/config/environment", __FILE__)
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 'ffaker'
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.3
4
+ version: 2.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Bigg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-20 00:00:00.000000000 Z
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: 2.1.3
19
+ version: 2.1.4
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.3
26
+ version: 2.1.4
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rabl
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -42,14 +42,14 @@ dependencies:
42
42
  name: versioncake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: 1.2.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 1.2.0
55
55
  description: Spree's API
@@ -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
@@ -127,6 +127,7 @@ files:
127
127
  - app/views/spree/api/orders/delivery.v1.rabl
128
128
  - app/views/spree/api/orders/index.v1.rabl
129
129
  - app/views/spree/api/orders/invalid_shipping_method.v1.rabl
130
+ - app/views/spree/api/orders/mine.v1.rabl
130
131
  - app/views/spree/api/orders/order.v1.rabl
131
132
  - app/views/spree/api/orders/payment.v1.rabl
132
133
  - app/views/spree/api/orders/show.v1.rabl
@@ -173,6 +174,7 @@ files:
173
174
  - app/views/spree/api/users/index.v1.rabl
174
175
  - app/views/spree/api/users/new.v1.rabl
175
176
  - app/views/spree/api/users/show.v1.rabl
177
+ - app/views/spree/api/variants/big_variant.v1.rabl
176
178
  - app/views/spree/api/variants/index.v1.rabl
177
179
  - app/views/spree/api/variants/new.v1.rabl
178
180
  - app/views/spree/api/variants/show.v1.rabl
@@ -241,17 +243,17 @@ require_paths:
241
243
  - lib
242
244
  required_ruby_version: !ruby/object:Gem::Requirement
243
245
  requirements:
244
- - - '>='
246
+ - - ">="
245
247
  - !ruby/object:Gem::Version
246
248
  version: '0'
247
249
  required_rubygems_version: !ruby/object:Gem::Requirement
248
250
  requirements:
249
- - - '>='
251
+ - - ">="
250
252
  - !ruby/object:Gem::Version
251
253
  version: '0'
252
254
  requirements: []
253
255
  rubyforge_project:
254
- rubygems_version: 2.1.0
256
+ rubygems_version: 2.2.0
255
257
  signing_key:
256
258
  specification_version: 4
257
259
  summary: Spree's API