solidus_api 2.9.6 → 2.10.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +35 -2
- data/app/controllers/spree/api/addresses_controller.rb +1 -1
- data/app/controllers/spree/api/base_controller.rb +10 -10
- data/app/controllers/spree/api/checkouts_controller.rb +4 -4
- data/app/controllers/spree/api/credit_cards_controller.rb +1 -1
- data/app/controllers/spree/api/images_controller.rb +1 -1
- data/app/controllers/spree/api/inventory_units_controller.rb +1 -1
- data/app/controllers/spree/api/option_types_controller.rb +1 -1
- data/app/controllers/spree/api/option_values_controller.rb +1 -1
- data/app/controllers/spree/api/orders_controller.rb +10 -5
- data/app/controllers/spree/api/payments_controller.rb +1 -1
- data/app/controllers/spree/api/product_properties_controller.rb +1 -1
- data/app/controllers/spree/api/properties_controller.rb +1 -1
- data/app/controllers/spree/api/resource_controller.rb +1 -1
- data/app/controllers/spree/api/return_authorizations_controller.rb +1 -1
- data/app/controllers/spree/api/shipments_controller.rb +1 -1
- data/app/controllers/spree/api/stock_items_controller.rb +1 -1
- data/app/controllers/spree/api/stock_locations_controller.rb +1 -1
- data/app/controllers/spree/api/stores_controller.rb +1 -1
- data/app/controllers/spree/api/taxonomies_controller.rb +4 -2
- data/app/controllers/spree/api/taxons_controller.rb +1 -1
- data/app/controllers/spree/api/variants_controller.rb +1 -1
- data/app/controllers/spree/api/zones_controller.rb +1 -1
- data/app/helpers/spree/api/api_helpers.rb +2 -2
- data/app/views/spree/api/images/_image.json.jbuilder +2 -2
- data/app/views/spree/api/orders/_order.json.jbuilder +1 -1
- data/app/views/spree/api/shared/_pagination.json.jbuilder +1 -1
- data/lib/spree/api.rb +0 -7
- data/lib/spree/api/config.rb +9 -0
- data/lib/spree/api/engine.rb +4 -4
- data/lib/spree/api/responders.rb +3 -2
- data/lib/spree/api/responders/{rabl_template.rb → jbuilder_template.rb} +3 -1
- data/{app/models → lib}/spree/api_configuration.rb +0 -0
- data/openapi/.stoplight.yml +7 -0
- data/openapi/api.oas2.yml +6108 -0
- data/openapi/authentication.md +25 -0
- data/openapi/checkout-flow.md +50 -0
- data/openapi/errors.md +3 -0
- data/openapi/lint.yml +1 -0
- data/openapi/main.hub.yml +65 -0
- data/openapi/pagination.md +7 -0
- data/openapi/theme.css +0 -0
- data/solidus_api.gemspec +1 -1
- data/spec/controllers/spree/api/resource_controller_spec.rb +4 -4
- data/spec/lib/spree_api_responders_spec.rb +10 -0
- data/spec/requests/api/address_books_spec.rb +2 -2
- data/spec/requests/{rabl_cache_spec.rb → jbuilder_cache_spec.rb} +2 -2
- data/spec/requests/spree/api/checkouts_controller_spec.rb +2 -2
- data/spec/requests/spree/api/classifications_controller_spec.rb +1 -1
- data/spec/requests/spree/api/option_types_controller_spec.rb +2 -2
- data/spec/requests/spree/api/option_values_controller_spec.rb +2 -2
- data/spec/requests/spree/api/orders_controller_spec.rb +15 -15
- data/spec/requests/spree/api/payments_controller_spec.rb +3 -3
- data/spec/requests/spree/api/products_controller_spec.rb +6 -6
- data/spec/requests/spree/api/stock_items_controller_spec.rb +5 -5
- data/spec/requests/spree/api/stock_locations_controller_spec.rb +4 -4
- data/spec/requests/spree/api/taxons_controller_spec.rb +2 -2
- metadata +25 -13
@@ -0,0 +1,25 @@
|
|
1
|
+
# Authentication
|
2
|
+
|
3
|
+
The Solidus API provides two means of authentication: one is through your Solidus user's API key, while the other is through an order's guest token.
|
4
|
+
|
5
|
+
### API key
|
6
|
+
|
7
|
+
You can use your API key to access all resources in the API. The API key must be passed in the `Authorization` header in the following form:
|
8
|
+
|
9
|
+
```
|
10
|
+
Authorization: Bearer API_KEY
|
11
|
+
```
|
12
|
+
|
13
|
+
By default, API keys are only generated for admins, but you can easily customize Solidus to generate them for all users, which is useful for instance if you want users to be able to sign in and manage their profile via the API.
|
14
|
+
|
15
|
+
### Order token
|
16
|
+
|
17
|
+
For allowing guests to manage their cart and place their order, you can use the order's guest token. This token is contained in the `guest_token` property of the order, and it allows you to perform certain checkout-related operations on the order such as managing line items, completing the checkout flow etc.
|
18
|
+
|
19
|
+
The order token must be passed in the `X-Spree-Order-Token` header in the following form:
|
20
|
+
|
21
|
+
```
|
22
|
+
X-Spree-Order-Token: ORDER_TOKEN
|
23
|
+
```
|
24
|
+
|
25
|
+
If you are already providing an API key, you don't need to also provide the order token (although you may do so).
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Checkout flow
|
2
|
+
|
3
|
+
Given the amount of endpoints at your disposal, it can be difficult to understand how to string the right API calls together to perform a full checkout flow. This document explains how to perform a full checkout flow.
|
4
|
+
|
5
|
+
## 1. Create an order
|
6
|
+
|
7
|
+
The first step is to create an order via `POST /orders`. You should save the number of the order that is created as well as the guest token, in case you are not authenticating with an API key.
|
8
|
+
|
9
|
+
## 2. Fill the cart
|
10
|
+
|
11
|
+
Once you have an order, you can begin filling your cart. Here are some endpoints you can use for that:
|
12
|
+
|
13
|
+
- `POST /checkouts/:order_number/line_items`
|
14
|
+
- `PATCH /checkouts/:order_number/line_items/:id`
|
15
|
+
- `DELETE /checkouts/:order_number/line_items/:id`
|
16
|
+
- `PUT /orders/:order_number/empty`
|
17
|
+
|
18
|
+
## 3. (Optional) Apply a coupon code
|
19
|
+
|
20
|
+
You can also apply a coupon code on the order via `POST /orders/:order_number/coupon_codes`.
|
21
|
+
|
22
|
+
## 4. Start the checkout flow
|
23
|
+
|
24
|
+
When you are ready to start the checkout flow, you can call `PUT /checkouts/:order_number/next` to transition the order from the `cart` to the `address` state.
|
25
|
+
|
26
|
+
## 5. Enter billing and shipping addresses
|
27
|
+
|
28
|
+
To enter the billing and shipping addresses, use the `PATCH /checkouts/:order_number` endpoint.
|
29
|
+
|
30
|
+
Once again, call `PUT /checkouts/:order_number/next` to transition the order from the `address` to the `shipping` state.
|
31
|
+
|
32
|
+
## 6. Select a shipping method
|
33
|
+
|
34
|
+
You can retrieve the available shipping methods, along with their rates, via `GET /shipments/:shipment_number/estimated_rates`. This allows you to let your user choose the shipping method they prefer.
|
35
|
+
|
36
|
+
When you want to select a shipping method, call `PUT /shipments/:shipment_number/select_shipping_method`.
|
37
|
+
|
38
|
+
Finally, call `PUT /checkouts/:order_number/next` to transition the order from the `shipping` to the `payment` state.
|
39
|
+
|
40
|
+
## 7. Enter payment details
|
41
|
+
|
42
|
+
To create a payment, call `POST /orders/:order_number/payments`.
|
43
|
+
|
44
|
+
Now call `PUT /checkouts/:order_number/next` to transition the order from the `payment` to the `confirm` state.
|
45
|
+
|
46
|
+
## 8. Complete the order
|
47
|
+
|
48
|
+
At this point, you should show the user a summary of their cart and ask them to confirm they want to place the order.
|
49
|
+
|
50
|
+
When they confirm, call `PUT /checkouts/:order_number/complete` to complete the checkout flow and place the order!
|
data/openapi/errors.md
ADDED
data/openapi/lint.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rules: {}
|
@@ -0,0 +1,65 @@
|
|
1
|
+
title: Solidus API
|
2
|
+
logo: 'https://next.stoplight.io/images/mark-light-bg.png'
|
3
|
+
header:
|
4
|
+
nav:
|
5
|
+
left: []
|
6
|
+
right: []
|
7
|
+
pages:
|
8
|
+
/:
|
9
|
+
title: Welcome
|
10
|
+
data:
|
11
|
+
blocks:
|
12
|
+
- type: text
|
13
|
+
data: >-
|
14
|
+
# Solidus API
|
15
|
+
|
16
|
+
|
17
|
+
Welcome! This is the documentation for the
|
18
|
+
[Solidus](https://solidus.io) REST API.
|
19
|
+
|
20
|
+
|
21
|
+
This documentation refers to a stock installation of Solidus.
|
22
|
+
However, every store may customize their API in any number of ways,
|
23
|
+
so make sure to ensure the store you are working with conforms to
|
24
|
+
this documentation or refer to the store's own documentation for
|
25
|
+
interacting with the API.
|
26
|
+
|
27
|
+
|
28
|
+
Endpoints are grouped by the logical resource they interact with.
|
29
|
+
Note that some of the endpoints are duplicated, since the same
|
30
|
+
resource may be accessed at the root level or as the child of
|
31
|
+
another resource (e.g. you may access all variants or the variants
|
32
|
+
that belong to a specific product).
|
33
|
+
- type: text
|
34
|
+
data: ''
|
35
|
+
children:
|
36
|
+
- title: Authentication
|
37
|
+
route:
|
38
|
+
path: /authentication
|
39
|
+
data:
|
40
|
+
$ref: ./authentication.md
|
41
|
+
- title: Pagination
|
42
|
+
route:
|
43
|
+
path: /pagination
|
44
|
+
data:
|
45
|
+
$ref: ./pagination.md
|
46
|
+
- title: Errors
|
47
|
+
route:
|
48
|
+
path: /errors
|
49
|
+
data:
|
50
|
+
$ref: ./errors.md
|
51
|
+
- title: Checkout Flow
|
52
|
+
route:
|
53
|
+
path: /checkout-flow
|
54
|
+
data:
|
55
|
+
$ref: ./checkout-flow.md
|
56
|
+
config:
|
57
|
+
sidebar:
|
58
|
+
token: ''
|
59
|
+
- title: API Reference
|
60
|
+
config:
|
61
|
+
includeDownloadLink: true
|
62
|
+
route:
|
63
|
+
path: /api-reference
|
64
|
+
data:
|
65
|
+
$ref: ./api.oas2.yml
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# Pagination
|
2
|
+
|
3
|
+
Most endpoints that return a collection are paginated. A paginated response contains metadata about the current page at the root level and the resources in the current page in a child key named after the resource (e.g. `orders`).
|
4
|
+
|
5
|
+
You can pass the `page` and `per_page` parameters to set the current page and the desired number of items per page. Note that the default and the maximum number of items per page is decided at the application level.
|
6
|
+
|
7
|
+
All pagination metadata is documented in the individual API endpoints, so take a look there if you're unsure what data you can expect.
|
data/openapi/theme.css
ADDED
File without changes
|
data/solidus_api.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
gem.version = Spree.solidus_version
|
20
20
|
|
21
|
-
gem.required_ruby_version = '>= 2.
|
21
|
+
gem.required_ruby_version = '>= 2.4.0'
|
22
22
|
gem.required_rubygems_version = '>= 1.8.23'
|
23
23
|
|
24
24
|
gem.add_dependency 'jbuilder', '~> 2.8'
|
@@ -25,10 +25,10 @@ module Spree
|
|
25
25
|
end
|
26
26
|
|
27
27
|
with_model 'Widget', scope: :all do
|
28
|
-
table do |
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
table do |widget|
|
29
|
+
widget.string :name
|
30
|
+
widget.integer :position
|
31
|
+
widget.timestamps null: false
|
32
32
|
end
|
33
33
|
|
34
34
|
model do
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe "Spree Api Responders" do
|
6
|
+
it "RablTemplate is deprecated Use JbuilderTemplate" do
|
7
|
+
warning_message = /DEPRECATION WARNING: RablTemplate is deprecated! Use JbuilderTemplate instead/
|
8
|
+
expect{ Spree::Api::Responders::RablTemplate.methods }.to output(warning_message).to_stderr
|
9
|
+
end
|
10
|
+
end
|
@@ -80,7 +80,7 @@ module Spree
|
|
80
80
|
user_address = UserAddress.last
|
81
81
|
|
82
82
|
expect(response.status).to eq(200)
|
83
|
-
update_target_ids = JSON.parse(response.body).select { |
|
83
|
+
update_target_ids = JSON.parse(response.body).select { |target| target['update_target'] }.map { |location| location['id'] }
|
84
84
|
expect(update_target_ids).to eq([user_address.address_id])
|
85
85
|
end
|
86
86
|
end
|
@@ -97,7 +97,7 @@ module Spree
|
|
97
97
|
}.to_not change { UserAddress.count }
|
98
98
|
|
99
99
|
expect(response.status).to eq(200)
|
100
|
-
update_target_ids = JSON.parse(response.body).select { |
|
100
|
+
update_target_ids = JSON.parse(response.body).select { |target| target['update_target'] }.map { |location| location['id'] }
|
101
101
|
expect(update_target_ids).to eq([address.id])
|
102
102
|
end
|
103
103
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe "
|
5
|
+
describe "Jbuilder Cache", type: :request, caching: true do
|
6
6
|
let!(:user) { create(:admin_user) }
|
7
7
|
|
8
8
|
before do
|
@@ -11,7 +11,7 @@ describe "Rabl Cache", type: :request, caching: true do
|
|
11
11
|
expect(Spree::Product.count).to eq(1)
|
12
12
|
end
|
13
13
|
|
14
|
-
it "doesn't create a cache key collision for models with different
|
14
|
+
it "doesn't create a cache key collision for models with different jbuilder templates" do
|
15
15
|
get "/api/variants", params: { token: user.spree_api_key }
|
16
16
|
expect(response.status).to eq(200)
|
17
17
|
|
@@ -132,9 +132,9 @@ module Spree
|
|
132
132
|
put spree.api_checkout_path(order.to_param), params: { order_token: order.guest_token, order: { shipments_attributes: { "0" => { selected_shipping_rate_id: shipping_rate.id, id: shipment.id } } } }
|
133
133
|
expect(response.status).to eq(200)
|
134
134
|
# Find the correct shipment...
|
135
|
-
json_shipment = json_response['shipments'].detect { |
|
135
|
+
json_shipment = json_response['shipments'].detect { |value| value["id"] == shipment.id }
|
136
136
|
# Find the correct shipping rate for that shipment...
|
137
|
-
json_shipping_rate = json_shipment['shipping_rates'].detect { |
|
137
|
+
json_shipping_rate = json_shipment['shipping_rates'].detect { |value| value["id"] == shipping_rate.id }
|
138
138
|
# ... And finally ensure that it's selected
|
139
139
|
expect(json_shipping_rate['selected']).to be true
|
140
140
|
# Order should automatically transfer to payment because all criteria are met
|
@@ -39,7 +39,7 @@ module Spree
|
|
39
39
|
end
|
40
40
|
|
41
41
|
it "should touch the taxon" do
|
42
|
-
taxon.
|
42
|
+
taxon.update(updated_at: Time.current - 10.seconds)
|
43
43
|
taxon_last_updated_at = taxon.updated_at
|
44
44
|
put spree.api_classifications_path, params: { taxon_id: taxon.id, product_id: last_product.id, position: 0 }
|
45
45
|
taxon.reload
|
@@ -34,9 +34,9 @@ module Spree
|
|
34
34
|
end
|
35
35
|
|
36
36
|
it "can retrieve a list of specific option types" do
|
37
|
-
|
37
|
+
option_type_one = create(:option_type)
|
38
38
|
create(:option_type)
|
39
|
-
get spree.api_option_types_path, params: { ids: "#{option_type.id},#{
|
39
|
+
get spree.api_option_types_path, params: { ids: "#{option_type.id},#{option_type_one.id}" }
|
40
40
|
expect(json_response.count).to eq(2)
|
41
41
|
|
42
42
|
check_option_values(json_response.first["option_values"])
|
@@ -48,9 +48,9 @@ module Spree
|
|
48
48
|
end
|
49
49
|
|
50
50
|
it "can retrieve a list of option types" do
|
51
|
-
|
51
|
+
option_value_one = create(:option_value, option_type: option_type)
|
52
52
|
create(:option_value, option_type: option_type)
|
53
|
-
get spree.api_option_values_path, params: { ids: [option_value.id,
|
53
|
+
get spree.api_option_values_path, params: { ids: [option_value.id, option_value_one.id] }
|
54
54
|
expect(json_response.count).to eq(2)
|
55
55
|
end
|
56
56
|
|
@@ -269,12 +269,12 @@ module Spree
|
|
269
269
|
it "returns orders in reverse chronological order by completed_at" do
|
270
270
|
order.update_columns completed_at: Time.current, created_at: 3.days.ago
|
271
271
|
|
272
|
-
|
273
|
-
expect(
|
274
|
-
|
275
|
-
expect(
|
276
|
-
|
277
|
-
expect(
|
272
|
+
order_two = Order.create user: order.user, completed_at: Time.current - 1.day, created_at: 2.days.ago, store: store
|
273
|
+
expect(order_two.created_at).to be > order.created_at
|
274
|
+
order_three = Order.create user: order.user, completed_at: nil, created_at: 1.day.ago, store: store
|
275
|
+
expect(order_three.created_at).to be > order_two.created_at
|
276
|
+
order_four = Order.create user: order.user, completed_at: nil, created_at: 0.days.ago, store: store
|
277
|
+
expect(order_four.created_at).to be > order_three.created_at
|
278
278
|
|
279
279
|
get spree.api_my_orders_path, headers: { 'SERVER_NAME' => store.url }
|
280
280
|
expect(response.status).to eq(200)
|
@@ -282,8 +282,8 @@ module Spree
|
|
282
282
|
orders = json_response["orders"]
|
283
283
|
expect(orders.length).to eq(4)
|
284
284
|
expect(orders[0]["number"]).to eq(order.number)
|
285
|
-
expect(orders[1]["number"]).to eq(
|
286
|
-
expect([orders[2]["number"], orders[3]["number"]]).to match_array([
|
285
|
+
expect(orders[1]["number"]).to eq(order_two.number)
|
286
|
+
expect([orders[2]["number"], orders[3]["number"]]).to match_array([order_three.number, order_four.number])
|
287
287
|
end
|
288
288
|
end
|
289
289
|
|
@@ -329,7 +329,7 @@ module Spree
|
|
329
329
|
|
330
330
|
context 'when an item does not track inventory' do
|
331
331
|
before do
|
332
|
-
order.line_items.first.variant.
|
332
|
+
order.line_items.first.variant.update!(track_inventory: false)
|
333
333
|
end
|
334
334
|
|
335
335
|
it 'contains stock information on variant' do
|
@@ -525,18 +525,18 @@ module Spree
|
|
525
525
|
end
|
526
526
|
|
527
527
|
it "adds an extra line item" do
|
528
|
-
|
528
|
+
variant_two = create(:variant)
|
529
529
|
put spree.api_order_path(order), params: { order: {
|
530
530
|
line_items: {
|
531
531
|
"0" => { id: line_item.id, quantity: 10 },
|
532
|
-
"1" => { variant_id:
|
532
|
+
"1" => { variant_id: variant_two.id, quantity: 1 }
|
533
533
|
}
|
534
534
|
} }
|
535
535
|
|
536
536
|
expect(response.status).to eq(200)
|
537
537
|
expect(json_response['line_items'].count).to eq(2)
|
538
538
|
expect(json_response['line_items'][0]['quantity']).to eq(10)
|
539
|
-
expect(json_response['line_items'][1]['variant_id']).to eq(
|
539
|
+
expect(json_response['line_items'][1]['variant_id']).to eq(variant_two.id)
|
540
540
|
expect(json_response['line_items'][1]['quantity']).to eq(1)
|
541
541
|
end
|
542
542
|
|
@@ -570,7 +570,7 @@ module Spree
|
|
570
570
|
end
|
571
571
|
|
572
572
|
it "can add shipping address" do
|
573
|
-
order.
|
573
|
+
order.update!(ship_address_id: nil)
|
574
574
|
|
575
575
|
expect {
|
576
576
|
put spree.api_order_path(order), params: { order: { ship_address_attributes: shipping_address } }
|
@@ -578,7 +578,7 @@ module Spree
|
|
578
578
|
end
|
579
579
|
|
580
580
|
it "receives error message if trying to add shipping address with errors" do
|
581
|
-
order.
|
581
|
+
order.update!(ship_address_id: nil)
|
582
582
|
|
583
583
|
shipping_address[:firstname] = ""
|
584
584
|
|
@@ -750,7 +750,7 @@ module Spree
|
|
750
750
|
|
751
751
|
orders = json_response[:orders]
|
752
752
|
expect(orders.count).to be >= 3
|
753
|
-
expect(orders.map { |
|
753
|
+
expect(orders.map { |order| order[:id] }).to match_array Order.pluck(:id)
|
754
754
|
end
|
755
755
|
|
756
756
|
after { ActionController::Base.perform_caching = false }
|
@@ -137,7 +137,7 @@ module Spree
|
|
137
137
|
context "for a given payment" do
|
138
138
|
context "updating" do
|
139
139
|
it "can update" do
|
140
|
-
payment.
|
140
|
+
payment.update(state: 'pending')
|
141
141
|
put spree.api_order_payment_path(order, payment), params: { payment: { amount: 2.01 } }
|
142
142
|
expect(response.status).to eq(200)
|
143
143
|
expect(payment.reload.amount).to eq(2.01)
|
@@ -145,14 +145,14 @@ module Spree
|
|
145
145
|
|
146
146
|
context "update fails" do
|
147
147
|
it "returns a 422 status when the amount is invalid" do
|
148
|
-
payment.
|
148
|
+
payment.update(state: 'pending')
|
149
149
|
put spree.api_order_payment_path(order, payment), params: { payment: { amount: 'invalid' } }
|
150
150
|
expect(response.status).to eq(422)
|
151
151
|
expect(json_response["error"]).to eq("Invalid resource. Please fix errors and try again.")
|
152
152
|
end
|
153
153
|
|
154
154
|
it "returns a 403 status when the payment is not pending" do
|
155
|
-
payment.
|
155
|
+
payment.update(state: 'completed')
|
156
156
|
put spree.api_order_payment_path(order, payment), params: { payment: { amount: 2.01 } }
|
157
157
|
expect(response.status).to eq(403)
|
158
158
|
expect(json_response["error"]).to eq("This payment cannot be updated because it is completed.")
|
@@ -17,8 +17,8 @@ module Spree
|
|
17
17
|
shipping_category_id: create(:shipping_category).id }
|
18
18
|
end
|
19
19
|
let(:attributes_for_variant) do
|
20
|
-
|
21
|
-
|
20
|
+
attributes = attributes_for(:variant).except(:option_values, :product)
|
21
|
+
attributes.merge({
|
22
22
|
options: [
|
23
23
|
{ name: "size", value: "small" },
|
24
24
|
{ name: "color", value: "black" }
|
@@ -40,7 +40,7 @@ module Spree
|
|
40
40
|
|
41
41
|
it "returns unique products" do
|
42
42
|
get spree.api_products_path
|
43
|
-
product_ids = json_response["products"].map { |
|
43
|
+
product_ids = json_response["products"].map { |product| product["id"] }
|
44
44
|
expect(product_ids.uniq.count).to eq(product_ids.count)
|
45
45
|
end
|
46
46
|
|
@@ -361,8 +361,8 @@ module Spree
|
|
361
361
|
expect(response.status).to eq 200
|
362
362
|
expect(json_response['variants'].count).to eq(2) # 2 variants
|
363
363
|
|
364
|
-
variants = json_response['variants'].reject { |
|
365
|
-
size_option_value = variants.last['option_values'].detect{ |
|
364
|
+
variants = json_response['variants'].reject { |variant| variant['is_master'] }
|
365
|
+
size_option_value = variants.last['option_values'].detect{ |value| value['option_type_name'] == 'size' }
|
366
366
|
expect(size_option_value['name']).to eq('small')
|
367
367
|
|
368
368
|
expect(json_response['option_types'].count).to eq(2) # size, color
|
@@ -385,7 +385,7 @@ module Spree
|
|
385
385
|
} }
|
386
386
|
|
387
387
|
expect(json_response['variants'].count).to eq(1)
|
388
|
-
variants = json_response['variants'].reject { |
|
388
|
+
variants = json_response['variants'].reject { |variant| variant['is_master'] }
|
389
389
|
expect(variants.last['option_values'][0]['name']).to eq('large')
|
390
390
|
expect(variants.last['sku']).to eq('456')
|
391
391
|
expect(variants.count).to eq(1)
|
@@ -25,7 +25,7 @@ module Spree
|
|
25
25
|
end
|
26
26
|
|
27
27
|
it "cannot list stock items for an inactive stock location" do
|
28
|
-
stock_location.
|
28
|
+
stock_location.update!(active: false)
|
29
29
|
get spree.api_stock_location_stock_items_path(stock_location)
|
30
30
|
expect(response).to be_not_found
|
31
31
|
end
|
@@ -39,7 +39,7 @@ module Spree
|
|
39
39
|
end
|
40
40
|
|
41
41
|
it "cannot see a stock item for an inactive stock location" do
|
42
|
-
stock_location.
|
42
|
+
stock_location.update!(active: false)
|
43
43
|
get spree.api_stock_location_stock_item_path(stock_location, stock_item)
|
44
44
|
expect(response.status).to eq(404)
|
45
45
|
end
|
@@ -155,7 +155,7 @@ module Spree
|
|
155
155
|
|
156
156
|
context 'variant does not track inventory' do
|
157
157
|
before do
|
158
|
-
variant.
|
158
|
+
variant.update(track_inventory: false)
|
159
159
|
end
|
160
160
|
|
161
161
|
it "doesn't set the stock item's count_on_hand" do
|
@@ -221,7 +221,7 @@ module Spree
|
|
221
221
|
|
222
222
|
context 'not tracking inventory' do
|
223
223
|
before do
|
224
|
-
stock_item.variant.
|
224
|
+
stock_item.variant.update(track_inventory: false)
|
225
225
|
end
|
226
226
|
|
227
227
|
it "doesn't set the stock item's count_on_hand" do
|
@@ -279,7 +279,7 @@ module Spree
|
|
279
279
|
|
280
280
|
context 'not tracking inventory' do
|
281
281
|
before do
|
282
|
-
stock_item.variant.
|
282
|
+
stock_item.variant.update(track_inventory: false)
|
283
283
|
end
|
284
284
|
|
285
285
|
it "doesn't update the stock item's count_on_hand" do
|