solidus_api 2.10.5 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.
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