solidus_api 2.10.5 → 2.11.0

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.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/app/controllers/spree/api/addresses_controller.rb +1 -1
  4. data/app/controllers/spree/api/base_controller.rb +11 -3
  5. data/app/controllers/spree/api/checkouts_controller.rb +1 -11
  6. data/app/controllers/spree/api/countries_controller.rb +2 -2
  7. data/app/controllers/spree/api/credit_cards_controller.rb +2 -2
  8. data/app/controllers/spree/api/customer_returns_controller.rb +67 -0
  9. data/app/controllers/spree/api/images_controller.rb +4 -4
  10. data/app/controllers/spree/api/inventory_units_controller.rb +1 -1
  11. data/app/controllers/spree/api/option_types_controller.rb +3 -3
  12. data/app/controllers/spree/api/option_values_controller.rb +2 -2
  13. data/app/controllers/spree/api/orders_controller.rb +1 -1
  14. data/app/controllers/spree/api/payments_controller.rb +1 -1
  15. data/app/controllers/spree/api/product_properties_controller.rb +9 -14
  16. data/app/controllers/spree/api/promotions_controller.rb +3 -12
  17. data/app/controllers/spree/api/properties_controller.rb +3 -3
  18. data/app/controllers/spree/api/resource_controller.rb +2 -2
  19. data/app/controllers/spree/api/return_authorizations_controller.rb +3 -3
  20. data/app/controllers/spree/api/shipments_controller.rb +1 -1
  21. data/app/controllers/spree/api/states_controller.rb +3 -3
  22. data/app/controllers/spree/api/stock_items_controller.rb +2 -2
  23. data/app/controllers/spree/api/stock_locations_controller.rb +3 -3
  24. data/app/controllers/spree/api/stock_movements_controller.rb +3 -3
  25. data/app/controllers/spree/api/stores_controller.rb +3 -3
  26. data/app/controllers/spree/api/taxonomies_controller.rb +2 -2
  27. data/app/controllers/spree/api/taxons_controller.rb +4 -4
  28. data/app/controllers/spree/api/users_controller.rb +13 -0
  29. data/app/controllers/spree/api/variants_controller.rb +3 -3
  30. data/app/controllers/spree/api/zones_controller.rb +2 -2
  31. data/app/helpers/spree/api/api_helpers.rb +18 -5
  32. data/app/views/spree/api/customer_returns/index.json.jbuilder +6 -0
  33. data/app/views/spree/api/customer_returns/new.json.jbuilder +4 -0
  34. data/app/views/spree/api/customer_returns/show.json.jbuilder +3 -0
  35. data/app/views/spree/api/errors/could_not_transition.json.jbuilder +4 -0
  36. data/app/views/spree/api/orders/could_not_transition.json.jbuilder +5 -0
  37. data/config/locales/en.yml +2 -0
  38. data/config/routes.rb +6 -3
  39. data/lib/spree/api/testing_support/helpers.rb +1 -1
  40. data/openapi/authentication.md +9 -1
  41. data/openapi/checkout-flow.md +17 -4
  42. data/openapi/main.hub.yml +1 -1
  43. data/openapi/solidus-api.oas.yml +6753 -0
  44. data/solidus_api.gemspec +19 -19
  45. metadata +14 -114
  46. data/openapi/api.oas2.yml +0 -6108
  47. data/script/rails +0 -10
  48. data/spec/controllers/spree/api/base_controller_spec.rb +0 -118
  49. data/spec/controllers/spree/api/resource_controller_spec.rb +0 -190
  50. data/spec/features/checkout_spec.rb +0 -192
  51. data/spec/fixtures/thinking-cat.jpg +0 -0
  52. data/spec/lib/spree_api_responders_spec.rb +0 -10
  53. data/spec/models/spree/legacy_user_spec.rb +0 -103
  54. data/spec/requests/api/address_books_spec.rb +0 -240
  55. data/spec/requests/jbuilder_cache_spec.rb +0 -34
  56. data/spec/requests/ransackable_attributes_spec.rb +0 -79
  57. data/spec/requests/spree/api/addresses_controller_spec.rb +0 -57
  58. data/spec/requests/spree/api/checkouts_controller_spec.rb +0 -484
  59. data/spec/requests/spree/api/classifications_controller_spec.rb +0 -50
  60. data/spec/requests/spree/api/config_controller_spec.rb +0 -26
  61. data/spec/requests/spree/api/countries_controller_spec.rb +0 -48
  62. data/spec/requests/spree/api/coupon_codes_controller_spec.rb +0 -105
  63. data/spec/requests/spree/api/credit_cards_controller_spec.rb +0 -105
  64. data/spec/requests/spree/api/images_controller_spec.rb +0 -99
  65. data/spec/requests/spree/api/inventory_units_controller_spec.rb +0 -55
  66. data/spec/requests/spree/api/line_items_controller_spec.rb +0 -213
  67. data/spec/requests/spree/api/option_types_controller_spec.rb +0 -116
  68. data/spec/requests/spree/api/option_values_controller_spec.rb +0 -138
  69. data/spec/requests/spree/api/orders_controller_spec.rb +0 -954
  70. data/spec/requests/spree/api/payments_controller_spec.rb +0 -259
  71. data/spec/requests/spree/api/product_properties_controller_spec.rb +0 -114
  72. data/spec/requests/spree/api/products_controller_spec.rb +0 -422
  73. data/spec/requests/spree/api/promotion_application_spec.rb +0 -50
  74. data/spec/requests/spree/api/promotions_controller_spec.rb +0 -67
  75. data/spec/requests/spree/api/properties_controller_spec.rb +0 -102
  76. data/spec/requests/spree/api/return_authorizations_controller_spec.rb +0 -180
  77. data/spec/requests/spree/api/shipments_controller_spec.rb +0 -532
  78. data/spec/requests/spree/api/states_controller_spec.rb +0 -69
  79. data/spec/requests/spree/api/stock_items_controller_spec.rb +0 -311
  80. data/spec/requests/spree/api/stock_locations_controller_spec.rb +0 -170
  81. data/spec/requests/spree/api/stock_movements_controller_spec.rb +0 -81
  82. data/spec/requests/spree/api/store_credit_events_controller_spec.rb +0 -59
  83. data/spec/requests/spree/api/stores_controller_spec.rb +0 -134
  84. data/spec/requests/spree/api/taxonomies_controller_spec.rb +0 -114
  85. data/spec/requests/spree/api/taxons_controller_spec.rb +0 -217
  86. data/spec/requests/spree/api/unauthenticated_products_controller_spec.rb +0 -27
  87. data/spec/requests/spree/api/users_controller_spec.rb +0 -151
  88. data/spec/requests/spree/api/variants_controller_spec.rb +0 -340
  89. data/spec/requests/spree/api/zones_controller_spec.rb +0 -89
  90. data/spec/shared_examples/protect_product_actions.rb +0 -18
  91. data/spec/spec_helper.rb +0 -73
  92. data/spec/support/be_paginated_matcher.rb +0 -9
  93. data/spec/support/controller_hacks.rb +0 -43
  94. data/spec/support/database_cleaner.rb +0 -16
  95. data/spec/support/have_attributes_matcher.rb +0 -11
  96. data/spec/test_views/spree/api/widgets/_widget.json.jbuilder +0 -3
  97. data/spec/test_views/spree/api/widgets/index.json.jbuilder +0 -9
  98. data/spec/test_views/spree/api/widgets/new.json.jbuilder +0 -3
  99. data/spec/test_views/spree/api/widgets/show.json.jbuilder +0 -3
data/script/rails DELETED
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
5
-
6
- ENGINE_ROOT = File.expand_path('..', __dir__)
7
- ENGINE_PATH = File.expand_path('../lib/spree/api/engine', __dir__)
8
-
9
- require 'rails/all'
10
- require 'rails/engine/commands'
@@ -1,118 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- class FakesController < Spree::Api::BaseController
6
- end
7
-
8
- describe Spree::Api::BaseController, type: :controller do
9
- render_views
10
- controller(Spree::Api::BaseController) do
11
- rescue_from Spree::Order::InsufficientStock, with: :insufficient_stock_error
12
-
13
- def index
14
- render json: { "products" => [] }
15
- end
16
- end
17
-
18
- before do
19
- @routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
20
- r.draw { get 'index', to: 'spree/api/base#index' }
21
- end
22
- end
23
-
24
- context "when validating based on an order token" do
25
- let!(:order) { create :order }
26
-
27
- context "with a correct order token" do
28
- it "succeeds" do
29
- get :index, params: { order_token: order.guest_token, order_id: order.number }
30
- expect(response.status).to eq(200)
31
- end
32
-
33
- it "succeeds with an order_number parameter" do
34
- get :index, params: { order_token: order.guest_token, order_number: order.number }
35
- expect(response.status).to eq(200)
36
- end
37
- end
38
-
39
- context "with an incorrect order token" do
40
- it "returns unauthorized" do
41
- get :index, params: { order_token: "NOT_A_TOKEN", order_id: order.number }
42
- expect(response.status).to eq(401)
43
- end
44
- end
45
- end
46
-
47
- context "cannot make a request to the API" do
48
- it "without an API key" do
49
- get :index
50
- expect(json_response).to eq({ "error" => "You must specify an API key." })
51
- expect(response.status).to eq(401)
52
- end
53
-
54
- it "with an invalid API key" do
55
- request.headers["Authorization"] = "Bearer fake_key"
56
- get :index, params: {}
57
- expect(json_response).to eq({ "error" => "Invalid API key (fake_key) specified." })
58
- expect(response.status).to eq(401)
59
- end
60
-
61
- it "using an invalid token param" do
62
- get :index, params: { token: "fake_key" }
63
- expect(json_response).to eq({ "error" => "Invalid API key (fake_key) specified." })
64
- end
65
- end
66
-
67
- it "lets a subclass override the product associations that are eager-loaded" do
68
- expect(controller.respond_to?(:product_includes, true)).to be
69
- end
70
-
71
- context 'insufficient stock' do
72
- before do
73
- expect(subject).to receive(:authenticate_user).and_return(true)
74
- expect(subject).to receive(:index).and_raise(Spree::Order::InsufficientStock)
75
- get :index, params: { token: "fake_key" }
76
- end
77
-
78
- it "should return a 422" do
79
- expect(response.status).to eq(422)
80
- end
81
-
82
- it "returns an error message" do
83
- expect(json_response).to eq(
84
- { "errors" => ["Quantity is not available for items in your order"], "type" => "insufficient_stock" }
85
- )
86
- end
87
- end
88
-
89
- context 'lock_order' do
90
- let!(:order) { create :order }
91
-
92
- controller(Spree::Api::BaseController) do
93
- around_action :lock_order
94
-
95
- def index
96
- render json: { "products" => [] }
97
- end
98
- end
99
-
100
- context 'without an existing lock' do
101
- it 'succeeds' do
102
- get :index, params: { order_token: order.guest_token, order_id: order.number }
103
- expect(response.status).to eq(200)
104
- end
105
- end
106
-
107
- context 'with an existing lock' do
108
- around do |example|
109
- Spree::OrderMutex.with_lock!(order) { example.run }
110
- end
111
-
112
- it 'returns a 409 conflict' do
113
- get :index, params: { order_token: order.guest_token, order_id: order.number }
114
- expect(response.status).to eq(409)
115
- end
116
- end
117
- end
118
- end
@@ -1,190 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- module Spree
6
- module Api
7
- class WidgetsController < Spree::Api::ResourceController
8
- prepend_view_path('spec/test_views')
9
-
10
- def model_class
11
- Widget
12
- end
13
-
14
- def permitted_widget_attributes
15
- [:name]
16
- end
17
- end
18
- end
19
-
20
- describe Api::WidgetsController, type: :controller do
21
- render_views
22
-
23
- after(:all) do
24
- Rails.application.reload_routes!
25
- end
26
-
27
- with_model 'Widget', scope: :all do
28
- table do |widget|
29
- widget.string :name
30
- widget.integer :position
31
- widget.timestamps null: false
32
- end
33
-
34
- model do
35
- acts_as_list
36
- validates :name, presence: true
37
- end
38
- end
39
-
40
- before do
41
- Spree::Core::Engine.routes.draw do
42
- namespace :api do
43
- resources :widgets
44
- end
45
- end
46
- end
47
-
48
- let(:user) { create(:user, :with_api_key) }
49
- let(:admin_user) { create(:admin_user, :with_api_key) }
50
-
51
- describe "#index" do
52
- let!(:widget) { Widget.create!(name: "a widget") }
53
-
54
- it "returns no widgets" do
55
- get :index, params: { token: user.spree_api_key }, as: :json
56
- expect(response).to be_successful
57
- expect(json_response['widgets']).to be_blank
58
- end
59
-
60
- context "it has authorization to read widgets" do
61
- it "returns widgets" do
62
- get :index, params: { token: admin_user.spree_api_key }, as: :json
63
- expect(response).to be_successful
64
- expect(json_response['widgets']).to include(
65
- hash_including(
66
- 'name' => 'a widget',
67
- 'position' => 1
68
- )
69
- )
70
- end
71
-
72
- context "specifying ids" do
73
- let!(:widget2) { Widget.create!(name: "a widget") }
74
-
75
- it "returns both widgets from comma separated string" do
76
- get :index, params: { ids: [widget.id, widget2.id].join(','), token: admin_user.spree_api_key }, as: :json
77
- expect(response).to be_successful
78
- expect(json_response['widgets'].size).to eq 2
79
- end
80
-
81
- it "returns both widgets from multiple arguments" do
82
- get :index, params: { ids: [widget.id, widget2.id], token: admin_user.spree_api_key }, as: :json
83
- expect(response).to be_successful
84
- expect(json_response['widgets'].size).to eq 2
85
- end
86
-
87
- it "returns one requested widgets" do
88
- get :index, params: { ids: widget2.id.to_s, token: admin_user.spree_api_key }, as: :json
89
- expect(response).to be_successful
90
- expect(json_response['widgets'].size).to eq 1
91
- expect(json_response['widgets'][0]['id']).to eq widget2.id
92
- end
93
-
94
- it "returns no widgets if empty" do
95
- get :index, params: { ids: '', token: admin_user.spree_api_key }, as: :json
96
- expect(response).to be_successful
97
- expect(json_response['widgets']).to be_empty
98
- end
99
- end
100
- end
101
- end
102
-
103
- describe "#show" do
104
- let(:widget) { Widget.create!(name: "a widget") }
105
-
106
- it "returns not found" do
107
- get :show, params: { id: widget.to_param, token: user.spree_api_key }, as: :json
108
- assert_not_found!
109
- end
110
-
111
- context "it has authorization read widgets" do
112
- it "returns widget details" do
113
- get :show, params: { id: widget.to_param, token: admin_user.spree_api_key }, as: :json
114
- expect(response).to be_successful
115
- expect(json_response['name']).to eq 'a widget'
116
- end
117
- end
118
- end
119
-
120
- describe "#new" do
121
- it "returns unauthorized" do
122
- get :new, params: { token: user.spree_api_key }, as: :json
123
- expect(response).to be_unauthorized
124
- end
125
-
126
- context "it is allowed to view a new widget" do
127
- it "can learn how to create a new widget" do
128
- get :new, params: { token: admin_user.spree_api_key }, as: :json
129
- expect(response).to be_successful
130
- expect(json_response["attributes"]).to eq(['name'])
131
- end
132
- end
133
- end
134
-
135
- describe "#create" do
136
- it "returns unauthorized" do
137
- expect {
138
- post :create, params: { widget: { name: "a widget" }, token: user.spree_api_key }, as: :json
139
- }.not_to change(Widget, :count)
140
- expect(response).to be_unauthorized
141
- end
142
-
143
- context "it is authorized to create widgets" do
144
- it "can create a widget" do
145
- expect {
146
- post :create, params: { widget: { name: "a widget" }, token: admin_user.spree_api_key }, as: :json
147
- }.to change(Widget, :count).by(1)
148
- expect(response).to be_created
149
- expect(json_response['name']).to eq 'a widget'
150
- expect(Widget.last.name).to eq 'a widget'
151
- end
152
- end
153
- end
154
-
155
- describe "#update" do
156
- let!(:widget) { Widget.create!(name: "a widget") }
157
- it "returns unauthorized" do
158
- put :update, params: { id: widget.to_param, widget: { name: "another widget" }, token: user.spree_api_key }, as: :json
159
- assert_not_found!
160
- expect(widget.reload.name).to eq 'a widget'
161
- end
162
-
163
- context "it is authorized to update widgets" do
164
- it "can update a widget" do
165
- put :update, params: { id: widget.to_param, widget: { name: "another widget" }, token: admin_user.spree_api_key }, as: :json
166
- expect(response).to be_successful
167
- expect(json_response['name']).to eq 'another widget'
168
- expect(widget.reload.name).to eq 'another widget'
169
- end
170
- end
171
- end
172
-
173
- describe "#destroy" do
174
- let!(:widget) { Widget.create!(name: "a widget") }
175
- it "returns unauthorized" do
176
- delete :destroy, params: { id: widget.to_param, token: user.spree_api_key }, as: :json
177
- assert_not_found!
178
- expect { widget.reload }.not_to raise_error
179
- end
180
-
181
- context "it is authorized to destroy widgets" do
182
- it "can destroy a widget" do
183
- delete :destroy, params: { id: widget.to_param, token: admin_user.spree_api_key }, as: :json
184
- expect(response.status).to eq 204
185
- expect { widget.reload }.to raise_error(ActiveRecord::RecordNotFound)
186
- end
187
- end
188
- end
189
- end
190
- end
@@ -1,192 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- module Spree
6
- describe 'Api Feature Specs', type: :request do
7
- before do
8
- stub_spree_preferences(Spree::Api::Config, requires_authentication: false)
9
- end
10
- let!(:promotion) { FactoryBot.create(:promotion, :with_order_adjustment, code: 'foo', weighted_order_adjustment_amount: 10) }
11
- let(:promotion_code) { promotion.codes.first }
12
- let!(:store) { FactoryBot.create(:store) }
13
- let(:bill_address) { FactoryBot.create(:address) }
14
- let(:ship_address) { FactoryBot.create(:address) }
15
- let(:variant_1) { FactoryBot.create(:variant, price: 100.00) }
16
- let(:variant_2) { FactoryBot.create(:variant, price: 200.00) }
17
- let(:payment_method) { FactoryBot.create(:check_payment_method) }
18
- let!(:shipping_method) do
19
- FactoryBot.create(:shipping_method).tap do |shipping_method|
20
- shipping_method.zones.first.zone_members.create!(zoneable: ship_address.country)
21
- shipping_method.calculator.set_preference(:amount, 10.0)
22
- end
23
- end
24
-
25
- def parsed
26
- JSON.parse(response.body)
27
- end
28
-
29
- def login
30
- expect {
31
- post '/api/users', params: {
32
- user: {
33
- email: "featurecheckoutuser@example.com",
34
- password: "featurecheckoutuser"
35
- }
36
- }
37
- }.to change { Spree.user_class.count }.by 1
38
- expect(response).to have_http_status(:created)
39
- @user = Spree.user_class.find(parsed['id'])
40
-
41
- # copied from api testing helpers support since we can't really sign in
42
- allow(Spree::LegacyUser).to receive(:find_by).with(hash_including(:spree_api_key)) { @user }
43
- end
44
-
45
- def create_order(order_params: {})
46
- expect { post '/api/orders', params: order_params }.to change { Order.count }.by 1
47
- expect(response).to have_http_status(:created)
48
- @order = Order.find(parsed['id'])
49
- expect(@order.email).to eq "featurecheckoutuser@example.com"
50
- end
51
-
52
- def update_order(order_params: {})
53
- put "/api/orders/#{@order.number}", params: order_params
54
- expect(response).to have_http_status(:ok)
55
- end
56
-
57
- def create_line_item(variant, quantity = 1)
58
- expect {
59
- post "/api/orders/#{@order.number}/line_items",
60
- params: { line_item: { variant_id: variant.id, quantity: quantity } }
61
- }.to change { @order.line_items.count }.by 1
62
- expect(response).to have_http_status(:created)
63
- end
64
-
65
- def add_promotion(_promotion)
66
- expect {
67
- post "/api/orders/#{@order.number}/coupon_codes",
68
- params: { coupon_code: promotion_code.value }
69
- }.to change { @order.promotions.count }.by 1
70
- expect(response).to have_http_status(:ok)
71
- end
72
-
73
- def add_address(address, billing: true)
74
- address_type = billing ? :bill_address : :ship_address
75
- # It seems we are missing an order-scoped address api endpoint since we need
76
- # to use update here.
77
- expect {
78
- update_order(order_params: { order: { address_type => address.attributes.except('id') } })
79
- }.to change { @order.reload.public_send(address_type) }.to address
80
- end
81
-
82
- def add_payment
83
- expect {
84
- post "/api/orders/#{@order.number}/payments",
85
- params: { payment: { payment_method_id: payment_method.id } }
86
- }.to change { @order.reload.payments.count }.by 1
87
- expect(response).to have_http_status(:created)
88
- expect(@order.payments.last.payment_method).to eq payment_method
89
- end
90
-
91
- def advance
92
- put "/api/checkouts/#{@order.number}/advance"
93
- expect(response).to have_http_status(:ok)
94
- end
95
-
96
- def complete
97
- put "/api/checkouts/#{@order.number}/complete"
98
- expect(response).to have_http_status(:ok)
99
- end
100
-
101
- def assert_order_expectations
102
- @order.reload
103
- expect(@order.state).to eq 'complete'
104
- expect(@order.completed_at).to be_a ActiveSupport::TimeWithZone
105
- expect(@order.item_total).to eq 600.00
106
- expect(@order.total).to eq 600.00
107
- expect(@order.adjustment_total).to eq(-10.00)
108
- expect(@order.shipment_total).to eq 10.00
109
- expect(@order.user).to eq @user
110
- expect(@order.bill_address).to eq bill_address
111
- expect(@order.ship_address).to eq ship_address
112
- expect(@order.payments.length).to eq 1
113
- expect(@order.line_items.any? { |li| li.variant == variant_1 && li.quantity == 2 }).to eq true
114
- expect(@order.line_items.any? { |li| li.variant == variant_2 && li.quantity == 2 }).to eq true
115
- expect(@order.promotions).to eq [promotion]
116
- end
117
-
118
- it "is able to checkout with individualized requests" do
119
- login
120
- create_order
121
-
122
- create_line_item(variant_1, 2)
123
- add_promotion(promotion)
124
- create_line_item(variant_2, 2)
125
-
126
- add_address(bill_address)
127
- add_address(ship_address, billing: false)
128
-
129
- add_payment
130
-
131
- advance
132
- complete
133
-
134
- assert_order_expectations
135
- end
136
-
137
- it "is able to checkout with the create request" do
138
- login
139
-
140
- create_order(order_params: {
141
- order: {
142
- bill_address: bill_address.as_json.except('id'),
143
- ship_address: ship_address.as_json.except('id'),
144
- line_items: {
145
- 0 => { variant_id: variant_1.id, quantity: 2 },
146
- 1 => { variant_id: variant_2.id, quantity: 2 }
147
- },
148
- # Would like to do this, but it puts the payment in a complete state,
149
- # which the order does not like when transitioning from confirm to complete
150
- # since it looks to process pending payments.
151
- # payments: [ { payment_method: payment_method.name, state: "pending" } ],
152
- }
153
- })
154
-
155
- add_promotion(promotion)
156
- add_payment
157
-
158
- advance
159
- complete
160
-
161
- assert_order_expectations
162
- end
163
-
164
- it "is able to checkout with the update request" do
165
- login
166
-
167
- create_order
168
- update_order(order_params: {
169
- order: {
170
- bill_address: bill_address.as_json.except('id'),
171
- ship_address: ship_address.as_json.except('id'),
172
- line_items: {
173
- 0 => { variant_id: variant_1.id, quantity: 2 },
174
- 1 => { variant_id: variant_2.id, quantity: 2 }
175
- },
176
- # Would like to do this, but it puts the payment in a complete state,
177
- # which the order does not like when transitioning from confirm to complete
178
- # since it looks to process pending payments.
179
- # payments: [ { payment_method: payment_method.name, state: "pending" } ],
180
- }
181
- })
182
-
183
- add_promotion(promotion)
184
- add_payment
185
-
186
- advance
187
- complete
188
-
189
- assert_order_expectations
190
- end
191
- end
192
- end