effective_orders 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/effective_orders/version.rb +1 -1
- metadata +10 -258
- data/spec/controllers/admin/orders_controller_spec.rb +0 -243
- data/spec/controllers/carts_controller_spec.rb +0 -143
- data/spec/controllers/ccbill_orders_controller_spec.rb +0 -103
- data/spec/controllers/moneris_orders_controller_spec.rb +0 -133
- data/spec/controllers/orders_controller_spec.rb +0 -500
- data/spec/controllers/stripe_orders_controller_spec.rb +0 -128
- data/spec/controllers/webhooks_controller_spec.rb +0 -170
- data/spec/dummy/README.rdoc +0 -8
- data/spec/dummy/Rakefile +0 -6
- data/spec/dummy/app/assets/javascripts/application.js +0 -13
- data/spec/dummy/app/assets/stylesheets/application.css +0 -15
- data/spec/dummy/app/controllers/application_controller.rb +0 -5
- data/spec/dummy/app/helpers/application_helper.rb +0 -2
- data/spec/dummy/app/models/product.rb +0 -9
- data/spec/dummy/app/models/product_with_float_price.rb +0 -9
- data/spec/dummy/app/models/user.rb +0 -11
- data/spec/dummy/app/views/layouts/application.html.erb +0 -14
- data/spec/dummy/bin/bundle +0 -3
- data/spec/dummy/bin/rails +0 -4
- data/spec/dummy/bin/rake +0 -4
- data/spec/dummy/config.ru +0 -4
- data/spec/dummy/config/application.rb +0 -32
- data/spec/dummy/config/boot.rb +0 -5
- data/spec/dummy/config/database.yml +0 -25
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/development.rb +0 -37
- data/spec/dummy/config/environments/production.rb +0 -80
- data/spec/dummy/config/environments/test.rb +0 -36
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/dummy/config/initializers/cookies_serializer.rb +0 -3
- data/spec/dummy/config/initializers/devise.rb +0 -254
- data/spec/dummy/config/initializers/effective_addresses.rb +0 -15
- data/spec/dummy/config/initializers/effective_orders.rb +0 -269
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -4
- data/spec/dummy/config/initializers/inflections.rb +0 -16
- data/spec/dummy/config/initializers/mime_types.rb +0 -4
- data/spec/dummy/config/initializers/session_store.rb +0 -3
- data/spec/dummy/config/initializers/simple_form.rb +0 -189
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/spec/dummy/config/locales/en.yml +0 -23
- data/spec/dummy/config/routes.rb +0 -3
- data/spec/dummy/config/secrets.yml +0 -22
- data/spec/dummy/db/schema.rb +0 -158
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +0 -164
- data/spec/dummy/log/test.log +0 -60
- data/spec/dummy/public/404.html +0 -67
- data/spec/dummy/public/422.html +0 -67
- data/spec/dummy/public/500.html +0 -66
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/fixtures/stripe_webhooks/invoice.payment_succeeded.without_renewals.json +0 -76
- data/spec/helpers/effective_orders_helper_spec.rb +0 -21
- data/spec/models/acts_as_purchasable_spec.rb +0 -75
- data/spec/models/customer_spec.rb +0 -72
- data/spec/models/factories_spec.rb +0 -35
- data/spec/models/order_item_spec.rb +0 -35
- data/spec/models/order_spec.rb +0 -445
- data/spec/models/stripe_charge_spec.rb +0 -39
- data/spec/models/subscription_spec.rb +0 -103
- data/spec/spec_helper.rb +0 -46
- data/spec/support/factories.rb +0 -139
@@ -1,143 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Effective::CartsController, type: :controller do
|
4
|
-
routes { EffectiveOrders::Engine.routes }
|
5
|
-
|
6
|
-
let(:user) { FactoryGirl.create(:user) }
|
7
|
-
let(:cart) { FactoryGirl.create(:cart) }
|
8
|
-
let(:product) { FactoryGirl.create(:product) }
|
9
|
-
|
10
|
-
describe 'First time user - not logged in' do
|
11
|
-
it 'creates a new cart and set the session[:cart]' do
|
12
|
-
get :show
|
13
|
-
assigns(:cart).id.should eq session[:cart]
|
14
|
-
assigns(:cart).size.should eq 0
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'allows me to add_to_cart' do
|
18
|
-
get :add_to_cart, :purchasable_type => product.class, :purchasable_id => product.id
|
19
|
-
assigns(:cart).size.should eq 1
|
20
|
-
assigns(:cart).find(product).present?.should eq true
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'allow me to remove_from_cart' do
|
24
|
-
get :add_to_cart, :purchasable_type => product.class, :purchasable_id => product.id
|
25
|
-
assigns(:cart).size.should eq 1
|
26
|
-
assigns(:cart).find(product).present?.should eq true
|
27
|
-
|
28
|
-
delete :remove_from_cart, :id => assigns(:cart).cart_items.first.id
|
29
|
-
assigns(:cart).reload.size.should eq 0
|
30
|
-
assigns(:cart).find(product).present?.should eq false
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'allow me to destroy the cart' do
|
34
|
-
get :add_to_cart, :purchasable_type => product.class, :purchasable_id => product.id
|
35
|
-
assigns(:cart).size.should eq 1
|
36
|
-
|
37
|
-
delete :destroy
|
38
|
-
response.should redirect_to('/cart')
|
39
|
-
|
40
|
-
# This redirects me, and reassigns the @cart
|
41
|
-
assigns(:cart).size.should eq 0
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
describe 'Logging in' do
|
46
|
-
describe 'with no previous cart' do
|
47
|
-
it 'assigns a new cart and unsets session[:cart]' do
|
48
|
-
session[:cart] = 12
|
49
|
-
sign_in user
|
50
|
-
|
51
|
-
get :show
|
52
|
-
|
53
|
-
assigns(:cart).user.should eq user
|
54
|
-
assigns(:cart).size.should eq 0
|
55
|
-
|
56
|
-
session[:cart].should eq nil
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
describe 'with an existing cart' do
|
61
|
-
it 'assigns me the existing cart' do
|
62
|
-
sign_in cart.user
|
63
|
-
get :show
|
64
|
-
assigns(:cart).should eq cart
|
65
|
-
assigns(:cart).size.should eq 3 # As per our factory
|
66
|
-
session[:cart].should eq nil
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe 'with no existing user cart, and a session cart full of items' do
|
71
|
-
it 'copies the session cart items into the user cart' do
|
72
|
-
get :show
|
73
|
-
assigns(:cart).id.should eq session[:cart]
|
74
|
-
assigns(:cart).size.should eq 0
|
75
|
-
|
76
|
-
get :add_to_cart, :purchasable_type => product.class, :purchasable_id => product.id
|
77
|
-
assigns(:cart).size.should eq 1
|
78
|
-
assigns(:cart).find(product).present?.should eq true
|
79
|
-
|
80
|
-
sign_in user
|
81
|
-
controller.instance_variable_set(:@cart, nil) # This is what happens in a real RailsController. zzz.
|
82
|
-
|
83
|
-
get :show
|
84
|
-
|
85
|
-
assigns(:cart).user.should eq user
|
86
|
-
assigns(:cart).size.should eq 1
|
87
|
-
assigns(:cart).find(product).present?.should eq true
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
describe 'with an existing user cart, and a session cart full of items' do
|
92
|
-
it 'merges the session cart into the user cart and destroy the session cart' do
|
93
|
-
get :show
|
94
|
-
session_cart = session[:cart]
|
95
|
-
|
96
|
-
assigns(:cart).id.should eq session[:cart]
|
97
|
-
assigns(:cart).size.should eq 0
|
98
|
-
|
99
|
-
get :add_to_cart, :purchasable_type => product.class, :purchasable_id => product.id
|
100
|
-
assigns(:cart).size.should eq 1
|
101
|
-
assigns(:cart).find(product).present?.should eq true
|
102
|
-
|
103
|
-
sign_in cart.user
|
104
|
-
controller.instance_variable_set(:@cart, nil) # This is what happens in a real RailsController. zzz.
|
105
|
-
|
106
|
-
get :show
|
107
|
-
assigns(:cart).user.should eq cart.user
|
108
|
-
assigns(:cart).cart_items.length.should eq 4 # the 3 from my factory, and 1 more we just created
|
109
|
-
assigns(:cart).find(product).present?.should eq true
|
110
|
-
|
111
|
-
Effective::Cart.where(:id => session_cart).should eq []
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
describe '#add_to_cart' do
|
117
|
-
before(:each) do
|
118
|
-
sign_in cart.user
|
119
|
-
end
|
120
|
-
|
121
|
-
it 'provides a useful error when passed an unknown purchasable_id' do
|
122
|
-
get :add_to_cart, :purchasable_type => product.class, :purchasable_id => 'asdf'
|
123
|
-
|
124
|
-
assigns(:purchasable).should eq nil
|
125
|
-
flash[:danger].include?('Unable to add item').should eq true
|
126
|
-
end
|
127
|
-
|
128
|
-
it 'provides a useful error when passed an unknown purchasable_type' do
|
129
|
-
get :add_to_cart, :purchasable_type => 'Something', :purchasable_id => product.id
|
130
|
-
|
131
|
-
assigns(:purchasable).should eq nil
|
132
|
-
flash[:danger].include?('Unable to add item').should eq true
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
describe '#remove_from_cart' do
|
137
|
-
it 'throws ActiveRecord::RecordNotFound when passed an invalid ID' do
|
138
|
-
expect { delete :remove_from_cart, :id => 12345 }.to raise_error(ActiveRecord::RecordNotFound)
|
139
|
-
assigns(:cart_item).should eq nil
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
end
|
@@ -1,103 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
# We're testing the effective/providers/ccbill.rb file, which is included into the OrdersController at runtime
|
4
|
-
|
5
|
-
describe Effective::OrdersController, type: :controller do
|
6
|
-
routes { EffectiveOrders::Engine.routes }
|
7
|
-
|
8
|
-
let(:order) { FactoryGirl.create(:order) }
|
9
|
-
|
10
|
-
let(:ccbill_params) do
|
11
|
-
{
|
12
|
-
"customer_fname"=>"Nathan",
|
13
|
-
"customer_lname"=>"Feaver",
|
14
|
-
"email"=>"nathan@agilestyle.com",
|
15
|
-
"username"=>"",
|
16
|
-
"password"=>"[FILTERED]",
|
17
|
-
"productDesc"=>"Cool Stuff",
|
18
|
-
"price"=>"#{ccbill_formatted_price(order.total)} for 365 days",
|
19
|
-
"subscription_id"=>"0216026202000000347",
|
20
|
-
"denialId"=>"",
|
21
|
-
"clientAccnum"=>"999999",
|
22
|
-
"clientSubacc"=>"0000",
|
23
|
-
"address1"=>"123 Easy St",
|
24
|
-
"city"=>"Edmonton",
|
25
|
-
"state"=>"AB",
|
26
|
-
"country"=>"CA",
|
27
|
-
"phone_number"=>"",
|
28
|
-
"zipcode"=>"A1B 2C3",
|
29
|
-
"start_date"=>"2016-01-26 13:55:44",
|
30
|
-
"referer"=>"",
|
31
|
-
"ccbill_referer"=>"",
|
32
|
-
"affiliate"=>"",
|
33
|
-
"reservationId"=>"",
|
34
|
-
"referringUrl"=>"http://localhost:3000/orders/833-7014-992",
|
35
|
-
"reasonForDecline"=>"",
|
36
|
-
"reasonForDeclineCode"=>"",
|
37
|
-
"formName"=>"211cc",
|
38
|
-
"cardType"=>"VISA",
|
39
|
-
"responseDigest"=>"43492c3db3f97944bab31a0f15d486cb",
|
40
|
-
"commit"=>"Checkout with CCBill",
|
41
|
-
"authenticity_token"=>"96wvM13VjhtNwgCyRZfO03Gn4x2ntgl7GBSn3U51OdwlGLxe2YYNdCHETtGjm8WwikQfRF79/aHF2zmldwsFCA==",
|
42
|
-
"order_id"=>order.to_param,
|
43
|
-
"utf8"=>"✓",
|
44
|
-
"typeId"=>"0",
|
45
|
-
"initialPrice"=>"10.5",
|
46
|
-
"initialPeriod"=>"365",
|
47
|
-
"recurringPrice"=>"0",
|
48
|
-
"recurringPeriod"=>"0",
|
49
|
-
"rebills"=>"0",
|
50
|
-
"initialFormattedPrice"=>ccbill_formatted_price(order.total),
|
51
|
-
"recurringFormattedPrice"=>"$0.00",
|
52
|
-
"ip_address"=>"00.00.000.00"
|
53
|
-
}
|
54
|
-
end
|
55
|
-
|
56
|
-
let(:ccbill_declined_params) do
|
57
|
-
ccbill_params.merge(
|
58
|
-
"denialId"=>"",
|
59
|
-
"reasonForDecline"=>"Transaction Denied by Bank",
|
60
|
-
"reasonForDeclineCode"=>"24",
|
61
|
-
)
|
62
|
-
end
|
63
|
-
|
64
|
-
def ccbill_formatted_price(price)
|
65
|
-
price_in_dollars = price.to_s.insert(-3, '.')
|
66
|
-
"$#{price_in_dollars}"
|
67
|
-
end
|
68
|
-
|
69
|
-
describe 'ccbill_postback' do
|
70
|
-
before do
|
71
|
-
sign_in order.user
|
72
|
-
allow_any_instance_of(Effective::Providers::CcbillPostback).to receive(:verified?).and_return(true)
|
73
|
-
end
|
74
|
-
|
75
|
-
describe 'invalid parameters' do
|
76
|
-
it 'raises RecordNotFound when passed an unknown order id' do
|
77
|
-
expect {
|
78
|
-
post :ccbill_postback, ccbill_params.tap { |x| x[:order_id] = 999 }
|
79
|
-
}.to raise_error(ActiveRecord::RecordNotFound)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
describe 'declined purchase params' do
|
84
|
-
it 'marks an order declined when params[:result] indicate decline' do
|
85
|
-
expect(subject).to receive(:order_declined).and_call_original
|
86
|
-
|
87
|
-
post :ccbill_postback, ccbill_declined_params
|
88
|
-
|
89
|
-
expect(assigns(:order)).to be_declined
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
describe 'approved purchase' do
|
94
|
-
it 'marks the order as purchased' do
|
95
|
-
expect(subject).to receive(:order_purchased).and_call_original
|
96
|
-
|
97
|
-
post :ccbill_postback, ccbill_params
|
98
|
-
|
99
|
-
expect(assigns(:order)).to be_purchased
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
@@ -1,133 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
# We're testing the effective/providers/moneris.rb file, which is included into the OrdersController at runtime
|
4
|
-
|
5
|
-
describe Effective::OrdersController, type: :controller do
|
6
|
-
routes { EffectiveOrders::Engine.routes }
|
7
|
-
|
8
|
-
let(:order) { FactoryGirl.create(:order) }
|
9
|
-
let(:moneris_params) do
|
10
|
-
{
|
11
|
-
response_order_id: "#{order.to_param}",
|
12
|
-
date_stamp: '2014-10-27',
|
13
|
-
time_stamp: '17:42:31',
|
14
|
-
bank_transaction_id:'660110910011137660',
|
15
|
-
charge_total: "#{'%.2f' % order.total}",
|
16
|
-
bank_approval_code: '497365',
|
17
|
-
response_code: '027',
|
18
|
-
iso_code: '01',
|
19
|
-
message: 'APPROVED * =',
|
20
|
-
trans_name: 'purchase',
|
21
|
-
cardholder: 'Matt',
|
22
|
-
f4l4: '4242***4242',
|
23
|
-
card:'V',
|
24
|
-
expiry_date: '1904',
|
25
|
-
result: '1',
|
26
|
-
rvar_authenticity_token: 'nJQf5RKL9SES4uiQIaj4aMNNdIQayEeauOL44iSppD4=',
|
27
|
-
transactionKey: 'C3kYLXwyMDDFD1ArgxiHFph3wIy1Jx'
|
28
|
-
}
|
29
|
-
end
|
30
|
-
|
31
|
-
describe 'moneris_postback' do
|
32
|
-
before do
|
33
|
-
allow(subject).to receive(:send_moneris_verify_request).and_return('') # Don't actually make Moneris requests
|
34
|
-
sign_in order.user
|
35
|
-
end
|
36
|
-
|
37
|
-
describe 'invalid parameters' do
|
38
|
-
it 'raises RecordNotFound when passed an unknown order id' do
|
39
|
-
expect {
|
40
|
-
post :moneris_postback, moneris_params.tap { |x| x[:response_order_id] = 999 }
|
41
|
-
}.to raise_error(ActiveRecord::RecordNotFound)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
describe 'declined purchase params' do
|
46
|
-
it 'marks an order declined when params[:result] indicate decline' do
|
47
|
-
subject.should_not_receive(:send_moneris_verify_request)
|
48
|
-
subject.should_not_receive(:parse_moneris_response)
|
49
|
-
|
50
|
-
post :moneris_postback, moneris_params.tap { |x| x[:result] = 'null' }
|
51
|
-
|
52
|
-
response.should redirect_to "/orders/#{order.to_param}/declined"
|
53
|
-
assigns(:order).declined?.should eq true
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'marks an order declined when params[:transactionKey] is blank' do
|
57
|
-
post :moneris_postback, moneris_params.tap { |x| x.delete(:transactionKey) }
|
58
|
-
|
59
|
-
response.should redirect_to "/orders/#{order.to_param}/declined"
|
60
|
-
assigns(:order).declined?.should eq true
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
describe 'successful purchase params' do
|
65
|
-
it 'sends a moneris verify request when passed successful purchase params' do
|
66
|
-
subject.should_receive(:send_moneris_verify_request)
|
67
|
-
subject.should_receive(:parse_moneris_response)
|
68
|
-
|
69
|
-
post :moneris_postback, moneris_params
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
describe 'transaction verification step' do
|
74
|
-
it 'marks the order as purchased when response code is valid' do
|
75
|
-
allow(subject).to receive(:parse_moneris_response).and_return({response_code: 1}) # success
|
76
|
-
|
77
|
-
post :moneris_postback, moneris_params
|
78
|
-
|
79
|
-
response.should redirect_to "/orders/#{order.to_param}/purchased"
|
80
|
-
assigns(:order).purchased?.should eq true
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'marks order declined when response_code = null' do
|
84
|
-
allow(subject).to receive(:parse_moneris_response).and_return({response_code: 'null'}) # failure
|
85
|
-
|
86
|
-
post :moneris_postback, moneris_params
|
87
|
-
|
88
|
-
response.should redirect_to "/orders/#{order.to_param}/declined"
|
89
|
-
assigns(:order).purchased?.should eq false
|
90
|
-
assigns(:order).declined?.should eq true
|
91
|
-
end
|
92
|
-
|
93
|
-
it 'marks order declined when response_code blank' do
|
94
|
-
allow(subject).to receive(:parse_moneris_response).and_return({}) # failure
|
95
|
-
|
96
|
-
post :moneris_postback, moneris_params
|
97
|
-
|
98
|
-
response.should redirect_to "/orders/#{order.to_param}/declined"
|
99
|
-
assigns(:order).purchased?.should eq false
|
100
|
-
assigns(:order).declined?.should eq true
|
101
|
-
end
|
102
|
-
|
103
|
-
it 'marks order declined when response_code = 0' do
|
104
|
-
allow(subject).to receive(:parse_moneris_response).and_return({response_code: 0}) # failure
|
105
|
-
post :moneris_postback, moneris_params
|
106
|
-
response.should redirect_to "/orders/#{order.to_param}/declined"
|
107
|
-
assigns(:order).purchased?.should eq false
|
108
|
-
end
|
109
|
-
|
110
|
-
it 'marks order declined when response_code = 50' do
|
111
|
-
allow(subject).to receive(:parse_moneris_response).and_return({response_code: 50}) # failure
|
112
|
-
post :moneris_postback, moneris_params
|
113
|
-
response.should redirect_to "/orders/#{order.to_param}/declined"
|
114
|
-
assigns(:order).purchased?.should eq false
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
describe 'redirect urls' do
|
119
|
-
it 'redirects to the purchased_url on purchase' do
|
120
|
-
allow(subject).to receive(:parse_moneris_response).and_return({response_code: 1}) # success
|
121
|
-
post :moneris_postback, moneris_params.tap { |x| x[:rvar_purchased_url] = '/something' }
|
122
|
-
response.should redirect_to '/something'
|
123
|
-
end
|
124
|
-
|
125
|
-
it 'redirects to the declined_url on decline' do
|
126
|
-
allow(subject).to receive(:parse_moneris_response).and_return({response_code: 'null'}) # failure
|
127
|
-
post :moneris_postback, moneris_params.tap { |x| x[:rvar_declined_url] = '/something' }
|
128
|
-
response.should redirect_to '/something'
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
end
|
133
|
-
end
|
@@ -1,500 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Effective::OrdersController, type: :controller do
|
4
|
-
routes { EffectiveOrders::Engine.routes }
|
5
|
-
|
6
|
-
let(:purchased_order) { FactoryGirl.create(:purchased_order) }
|
7
|
-
let(:order) { FactoryGirl.create(:order) }
|
8
|
-
|
9
|
-
let(:cart) { FactoryGirl.create(:cart) }
|
10
|
-
let(:address) { FactoryGirl.create(:address) }
|
11
|
-
|
12
|
-
let(:billing_address) { FactoryGirl.create(:address) }
|
13
|
-
let(:billing_atts) { billing_address.attributes.reject { |k, v| ['id', 'addressable_type', 'addressable_id', 'category', 'updated_at', 'created_at'].include?(k) } }
|
14
|
-
|
15
|
-
let(:shipping_address) { FactoryGirl.create(:address) }
|
16
|
-
let(:shipping_atts) { shipping_address.attributes.reject { |k, v| ['id', 'addressable_type', 'addressable_id', 'category', 'updated_at', 'created_at'].include?(k) } }
|
17
|
-
|
18
|
-
let(:valid_order_attributes) do
|
19
|
-
{
|
20
|
-
effective_order: {
|
21
|
-
billing_address: billing_atts, save_billing_address: false,
|
22
|
-
shipping_address: shipping_atts, save_shipping_address: false,
|
23
|
-
}
|
24
|
-
}
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'uses authenticate_user! to redirect to sign in if not signed in' do
|
28
|
-
get :new
|
29
|
-
response.should redirect_to '/users/sign_in'
|
30
|
-
end
|
31
|
-
|
32
|
-
describe '#new' do
|
33
|
-
it 'should assign an @order based off the user cart' do
|
34
|
-
sign_in cart.user
|
35
|
-
get :new
|
36
|
-
|
37
|
-
assigns(:order).user.should eq cart.user
|
38
|
-
|
39
|
-
assigns(:order).order_items.size.should eq cart.cart_items.size
|
40
|
-
assigns(:order).total.should eq cart.subtotal
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'redirects if there is an empty order' do
|
44
|
-
sign_in cart.user
|
45
|
-
cart.cart_items.destroy_all
|
46
|
-
|
47
|
-
get :new
|
48
|
-
|
49
|
-
flash[:danger].downcase.include?('add one or more item to your cart').should eq true
|
50
|
-
response.should redirect_to '/cart' # cart_path
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'redirects if order total is less than minimum charge' do
|
54
|
-
sign_in cart.user
|
55
|
-
|
56
|
-
cart.cart_items.each do |cart_item|
|
57
|
-
cart_item.purchasable.update_column(:price, 10)
|
58
|
-
end
|
59
|
-
|
60
|
-
get :new
|
61
|
-
|
62
|
-
flash[:danger].downcase.include?('a minimum order of $0.50 is required').should eq true
|
63
|
-
response.should redirect_to '/cart' # cart_path
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# "effective_order"=> {
|
68
|
-
# "order_items_attributes"=> {
|
69
|
-
# "0"=> {
|
70
|
-
# "class"=>"Effective::Subscription", "stripe_coupon_id"=>"50OFF", "id"=>"2"}},
|
71
|
-
# "billing_address"=>{"address1"=>"1234 Fake street", "address2"=>"", "city"=>"Edmonton", "country_code"=>"KH", "state_code"=>"1", "postal_code"=>"T5T2T1"},
|
72
|
-
# "save_billing_address"=>"1",
|
73
|
-
# "shipping_address"=>{"address1"=>"123 Shipping street", "address2"=>"", "city"=>"Edmonton", "country_code"=>"KH", "state_code"=>"10", "postal_code"=>"t5t2t1"},
|
74
|
-
# "save_shipping_address"=>"1"},
|
75
|
-
# "commit"=>"Continue Checkout"
|
76
|
-
# }
|
77
|
-
|
78
|
-
describe '#create' do
|
79
|
-
before(:each) do
|
80
|
-
sign_in cart.user
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'should assign an @order based off the user cart' do
|
84
|
-
post :create, effective_order: {}
|
85
|
-
|
86
|
-
assigns(:order).user.should eq cart.user
|
87
|
-
assigns(:order).order_items.size.should eq cart.cart_items.size
|
88
|
-
assigns(:order).total.should eq cart.subtotal
|
89
|
-
assigns(:order).purchased?.should eq false
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'assign appropriate User fields' do
|
93
|
-
post :create, effective_order: {
|
94
|
-
billing_address: billing_atts, save_billing_address: false,
|
95
|
-
shipping_address: shipping_atts, save_shipping_address: false,
|
96
|
-
user_attributes: {first_name: 'First', last_name: 'Last', email: 'email@somwhere.com'}
|
97
|
-
}
|
98
|
-
|
99
|
-
(assigns(:order).valid? && assigns(:order).persisted?).should eq true
|
100
|
-
|
101
|
-
assigns(:order).user.first_name.should eq 'First'
|
102
|
-
assigns(:order).user.last_name.should eq 'Last'
|
103
|
-
assigns(:order).user.email.should_not eq 'email@somwhere.com'
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'assign addresses to the order and not the user' do
|
107
|
-
post :create, effective_order: {
|
108
|
-
billing_address: billing_atts, save_billing_address: false,
|
109
|
-
shipping_address: shipping_atts, save_shipping_address: false,
|
110
|
-
}
|
111
|
-
|
112
|
-
(assigns(:order).valid? && assigns(:order).persisted?).should eq true
|
113
|
-
|
114
|
-
assigns(:order).billing_address.address1.should eq billing_atts['address1']
|
115
|
-
assigns(:order).shipping_address.address1.should eq shipping_atts['address1']
|
116
|
-
|
117
|
-
assigns(:order).user.billing_address.present?.should eq false
|
118
|
-
assigns(:order).user.shipping_address.present?.should eq false
|
119
|
-
end
|
120
|
-
|
121
|
-
it 'assign addresses to the order and the user' do
|
122
|
-
post :create, effective_order: {
|
123
|
-
billing_address: billing_atts, save_billing_address: true,
|
124
|
-
shipping_address: shipping_atts, save_shipping_address: true
|
125
|
-
}
|
126
|
-
|
127
|
-
(assigns(:order).valid? && assigns(:order).persisted?).should eq true
|
128
|
-
|
129
|
-
assigns(:order).billing_address.address1.should eq billing_atts['address1']
|
130
|
-
assigns(:order).shipping_address.address1.should eq shipping_atts['address1']
|
131
|
-
|
132
|
-
assigns(:order).user.billing_address.address1.should eq billing_atts['address1']
|
133
|
-
assigns(:order).user.shipping_address.address1.should eq shipping_atts['address1']
|
134
|
-
|
135
|
-
response.should redirect_to "/orders/#{assigns(:order).to_param}"
|
136
|
-
end
|
137
|
-
|
138
|
-
it 'does not assign the billing_address to user if save_billing_address is false' do
|
139
|
-
post :create, effective_order: {
|
140
|
-
billing_address: billing_atts, save_billing_address: false,
|
141
|
-
shipping_address: shipping_atts, save_shipping_address: true
|
142
|
-
}
|
143
|
-
|
144
|
-
(assigns(:order).valid? && assigns(:order).persisted?).should eq true
|
145
|
-
|
146
|
-
assigns(:order).billing_address.address1.should eq billing_atts['address1']
|
147
|
-
assigns(:order).shipping_address.address1.should eq shipping_atts['address1']
|
148
|
-
|
149
|
-
assigns(:order).user.billing_address.present?.should eq false
|
150
|
-
assigns(:order).user.shipping_address.address1.should eq shipping_atts['address1']
|
151
|
-
|
152
|
-
response.should redirect_to "/orders/#{assigns(:order).to_param}"
|
153
|
-
end
|
154
|
-
|
155
|
-
it 'does not assign the shipping_address to user if save_shipping_address is false' do
|
156
|
-
post :create, effective_order: {
|
157
|
-
billing_address: billing_atts, save_billing_address: true,
|
158
|
-
shipping_address: shipping_atts, save_shipping_address: false
|
159
|
-
}
|
160
|
-
|
161
|
-
(assigns(:order).valid? && assigns(:order).persisted?).should eq true
|
162
|
-
|
163
|
-
assigns(:order).billing_address.address1.should eq billing_atts['address1']
|
164
|
-
assigns(:order).shipping_address.address1.should eq shipping_atts['address1']
|
165
|
-
|
166
|
-
assigns(:order).user.billing_address.address1.should eq billing_atts['address1']
|
167
|
-
assigns(:order).user.shipping_address.present?.should eq false
|
168
|
-
|
169
|
-
response.should redirect_to "/orders/#{assigns(:order).to_param}"
|
170
|
-
end
|
171
|
-
|
172
|
-
it 'assign billing address to the order shipping_address when shipping_address_same_as_billing' do
|
173
|
-
post :create, effective_order: {
|
174
|
-
billing_address: billing_atts, save_billing_address: true,
|
175
|
-
shipping_address: shipping_atts.merge(shipping_address_same_as_billing: 1), save_shipping_address: true,
|
176
|
-
}
|
177
|
-
|
178
|
-
(assigns(:order).valid? && assigns(:order).persisted?).should eq true
|
179
|
-
|
180
|
-
assigns(:order).billing_address.address1.should eq billing_atts['address1']
|
181
|
-
assigns(:order).shipping_address.address1.should eq billing_atts['address1']
|
182
|
-
|
183
|
-
assigns(:order).user.billing_address.address1.should eq billing_atts['address1']
|
184
|
-
assigns(:order).user.shipping_address.address1.should eq billing_atts['address1']
|
185
|
-
|
186
|
-
response.should redirect_to "/orders/#{assigns(:order).to_param}"
|
187
|
-
end
|
188
|
-
|
189
|
-
it 'assign billing address to the order shipping_address when shipping_address_same_as_billing and no shipping provided' do
|
190
|
-
post :create, effective_order: {
|
191
|
-
billing_address: billing_atts, save_billing_address: true, shipping_address: { shipping_address_same_as_billing: 1 }
|
192
|
-
}
|
193
|
-
|
194
|
-
(assigns(:order).valid? && assigns(:order).persisted?).should eq true
|
195
|
-
|
196
|
-
assigns(:order).billing_address.address1.should eq billing_atts['address1']
|
197
|
-
assigns(:order).shipping_address.address1.should eq billing_atts['address1']
|
198
|
-
|
199
|
-
assigns(:order).user.billing_address.address1.should eq billing_atts['address1']
|
200
|
-
assigns(:order).user.shipping_address.address1.should eq billing_atts['address1']
|
201
|
-
|
202
|
-
response.should redirect_to "/orders/#{assigns(:order).to_param}"
|
203
|
-
end
|
204
|
-
|
205
|
-
it 'assign billing address to the order shipping_address but not the user when shipping_address_same_as_billing provided' do
|
206
|
-
post :create, effective_order: {
|
207
|
-
billing_address: billing_atts, save_billing_address: false, shipping_address: { shipping_address_same_as_billing: 1 },
|
208
|
-
save_shipping_address: false
|
209
|
-
}
|
210
|
-
|
211
|
-
(assigns(:order).valid? && assigns(:order).persisted?).should eq true
|
212
|
-
|
213
|
-
assigns(:order).billing_address.address1.should eq billing_atts['address1']
|
214
|
-
assigns(:order).shipping_address.address1.should eq billing_atts['address1']
|
215
|
-
|
216
|
-
assigns(:order).user.billing_address.present?.should eq false
|
217
|
-
assigns(:order).user.shipping_address.present?.should eq false
|
218
|
-
|
219
|
-
response.should redirect_to "/orders/#{assigns(:order).to_param}"
|
220
|
-
end
|
221
|
-
|
222
|
-
it 'is invalid when passed an invalid address' do
|
223
|
-
post :create, effective_order: {
|
224
|
-
billing_address: billing_atts, save_billing_address: true,
|
225
|
-
shipping_address: shipping_atts.tap { |x| x[:address1] = nil }, save_shipping_address: true
|
226
|
-
}
|
227
|
-
|
228
|
-
(assigns(:order).valid? && assigns(:order).persisted?).should eq false
|
229
|
-
assigns(:order).errors[:shipping_address].present?.should eq true
|
230
|
-
|
231
|
-
response.should render_template(:checkout_step1)
|
232
|
-
end
|
233
|
-
|
234
|
-
it 'is invalid when passed an invalid order_item' do
|
235
|
-
Effective::OrderItem.any_instance.stub(:valid?).and_return(false)
|
236
|
-
|
237
|
-
post :create, effective_order: {
|
238
|
-
billing_address: billing_atts, save_billing_address: true,
|
239
|
-
shipping_address: shipping_atts, save_shipping_address: true,
|
240
|
-
}
|
241
|
-
|
242
|
-
(assigns(:order).valid? && assigns(:order).persisted?).should eq false
|
243
|
-
response.should render_template(:checkout_step1)
|
244
|
-
end
|
245
|
-
|
246
|
-
it 'is invalid when passed an invalid user' do
|
247
|
-
User.any_instance.stub(:valid?).and_return(false)
|
248
|
-
|
249
|
-
post :create, effective_order: {
|
250
|
-
billing_address: billing_atts, save_billing_address: true,
|
251
|
-
shipping_address: shipping_atts, save_shipping_address: true,
|
252
|
-
}
|
253
|
-
|
254
|
-
(assigns(:order).valid? && assigns(:order).persisted?).should eq false
|
255
|
-
response.should render_template(:checkout_step1)
|
256
|
-
end
|
257
|
-
|
258
|
-
it 'is invalid when passed an invalid purchasable' do
|
259
|
-
Product.any_instance.stub(:valid?).and_return(false)
|
260
|
-
|
261
|
-
post :create, effective_order: {
|
262
|
-
billing_address: billing_atts, save_billing_address: true,
|
263
|
-
shipping_address: shipping_atts, save_shipping_address: true,
|
264
|
-
}
|
265
|
-
|
266
|
-
(assigns(:order).valid? && assigns(:order).persisted?).should eq false
|
267
|
-
response.should render_template(:checkout_step1)
|
268
|
-
end
|
269
|
-
|
270
|
-
it 'prevents the order from proceeding when missing a required address' do
|
271
|
-
post :create, effective_order: { billing_address: billing_atts, save_billing_address: true }
|
272
|
-
|
273
|
-
(assigns(:order).valid? && assigns(:order).persisted?).should eq false
|
274
|
-
assigns(:order).errors[:shipping_address].present?.should eq true
|
275
|
-
|
276
|
-
response.should render_template(:checkout_step1)
|
277
|
-
end
|
278
|
-
end
|
279
|
-
|
280
|
-
describe '#create with a Stripe Subscription object' do
|
281
|
-
let(:cart_with_subscription) { FactoryGirl.create(:cart_with_subscription) }
|
282
|
-
let(:subscription) { cart_with_subscription.cart_items.find { |obj| obj.purchasable.kind_of?(Effective::Subscription)}.purchasable }
|
283
|
-
|
284
|
-
let(:valid_order_with_new_subscription_coupon_attributes) do
|
285
|
-
valid_order_attributes.tap { |x| x[:effective_order]['order_items_attributes'] = {'0' => {"class"=>"Effective::Subscription", "stripe_coupon_id"=>"#{FactoryGirl.create(:stripe_coupon).id}", 'id' => "#{subscription.id}"}} }
|
286
|
-
end
|
287
|
-
|
288
|
-
before do
|
289
|
-
StripeMock.start
|
290
|
-
sign_in cart_with_subscription.user
|
291
|
-
end
|
292
|
-
|
293
|
-
after { StripeMock.stop }
|
294
|
-
|
295
|
-
it 'has an OrderItem that is a Subscription' do
|
296
|
-
post :create, valid_order_attributes
|
297
|
-
assigns(:order).persisted?.should eq true
|
298
|
-
|
299
|
-
subscription = assigns(:order).order_items.find { |obj| obj.purchasable.kind_of?(Effective::Subscription) }
|
300
|
-
subscription.present?.should eq true
|
301
|
-
end
|
302
|
-
|
303
|
-
it 'does not alter the subscription.stripe_coupon_id' do
|
304
|
-
post :create, valid_order_attributes
|
305
|
-
assigns(:order).persisted?.should eq true
|
306
|
-
|
307
|
-
order_subscription = assigns(:order).order_items.find { |obj| obj.purchasable.kind_of?(Effective::Subscription) }.purchasable
|
308
|
-
order_subscription.stripe_coupon_id.should eq subscription.stripe_coupon_id
|
309
|
-
end
|
310
|
-
|
311
|
-
it 'updates the subscription.stripe_coupon_id when passed' do
|
312
|
-
post :create, valid_order_with_new_subscription_coupon_attributes
|
313
|
-
assigns(:order).persisted?.should eq true
|
314
|
-
|
315
|
-
order_subscription = assigns(:order).order_items.find { |obj| obj.purchasable.kind_of?(Effective::Subscription) }.purchasable
|
316
|
-
order_subscription.stripe_coupon_id.should_not eq subscription.stripe_coupon_id
|
317
|
-
end
|
318
|
-
|
319
|
-
it 'is invalid when passed an invalid coupon code' do
|
320
|
-
invalid_coupon_atts = valid_order_with_new_subscription_coupon_attributes.tap { |x| x[:effective_order]['order_items_attributes']['0']['stripe_coupon_id'] = 'SOMETHING INVALID' }
|
321
|
-
|
322
|
-
post :create, invalid_coupon_atts
|
323
|
-
|
324
|
-
assigns(:order).errors['order_items.purchasable'].present?.should eq true
|
325
|
-
assigns(:order).errors['order_items.purchasable.stripe_coupon_id'].present?.should eq true
|
326
|
-
assigns(:order).persisted?.should eq false
|
327
|
-
end
|
328
|
-
end
|
329
|
-
|
330
|
-
describe '#order_purchased (with a free order)' do
|
331
|
-
before(:each) do
|
332
|
-
sign_in cart.user
|
333
|
-
cart.cart_items.each { |cart_item| cart_item.purchasable.update_attributes(price: 0) }
|
334
|
-
end
|
335
|
-
|
336
|
-
it 'creates a purchased order' do
|
337
|
-
post :create, valid_order_attributes
|
338
|
-
assigns(:order).purchased?.should eq true
|
339
|
-
assigns(:order).payment[:details].should eq 'automatic purchase of free order'
|
340
|
-
end
|
341
|
-
|
342
|
-
it 'destroys the current user cart' do
|
343
|
-
post :create, valid_order_attributes
|
344
|
-
|
345
|
-
expect { Effective::Cart.find(cart.id) }.to raise_error(ActiveRecord::RecordNotFound)
|
346
|
-
Effective::Cart.count.should eq 0
|
347
|
-
end
|
348
|
-
|
349
|
-
it 'redirects to the purchased page' do
|
350
|
-
post :create, valid_order_attributes
|
351
|
-
response.should redirect_to "/orders/#{assigns(:order).to_param}/purchased"
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
describe '#show' do
|
356
|
-
context 'when finding order' do
|
357
|
-
before { sign_in purchased_order.user }
|
358
|
-
|
359
|
-
it 'should find the order by obfuscated ID' do
|
360
|
-
get :show, id: purchased_order.to_param
|
361
|
-
|
362
|
-
expect(assigns(:order).id).to eq purchased_order.id
|
363
|
-
end
|
364
|
-
|
365
|
-
it 'should not find an order by regular ID' do
|
366
|
-
expect { get :show, id: purchased_order.id }.to raise_error(ActiveRecord::RecordNotFound)
|
367
|
-
end
|
368
|
-
end
|
369
|
-
|
370
|
-
context 'when rendering template' do
|
371
|
-
let(:user) { FactoryGirl.create(:user) }
|
372
|
-
|
373
|
-
before { sign_in user }
|
374
|
-
|
375
|
-
context 'when not purchased order' do
|
376
|
-
let(:order) { FactoryGirl.create(:order, user: user) }
|
377
|
-
|
378
|
-
it 'should render checkout page successfully' do
|
379
|
-
get :show, id: order.to_param
|
380
|
-
|
381
|
-
expect(response).to be_successful
|
382
|
-
expect(response).to render_template :checkout_step2
|
383
|
-
expect(assigns(:order)).to eq order
|
384
|
-
expect(assigns(:page_title)).to eq 'Checkout'
|
385
|
-
end
|
386
|
-
|
387
|
-
it 'should render checkout page successfully' do
|
388
|
-
get :edit, id: order.to_param
|
389
|
-
|
390
|
-
expect(response).to be_successful
|
391
|
-
expect(response).to render_template :checkout_step1
|
392
|
-
expect(assigns(:order)).to eq order
|
393
|
-
expect(assigns(:page_title)).to eq 'Checkout'
|
394
|
-
end
|
395
|
-
end
|
396
|
-
|
397
|
-
context 'when pending order' do
|
398
|
-
let(:order) { FactoryGirl.create(:pending_order, user: user) }
|
399
|
-
|
400
|
-
it 'should render checkout page successfully' do
|
401
|
-
get :show, id: order.to_param
|
402
|
-
|
403
|
-
expect(response).to be_successful
|
404
|
-
expect(response).to render_template :checkout_step2
|
405
|
-
expect(assigns(:order)).to eq order
|
406
|
-
expect(assigns(:page_title)).to eq 'Checkout'
|
407
|
-
end
|
408
|
-
|
409
|
-
it 'should render checkout page successfully' do
|
410
|
-
get :edit, id: order.to_param
|
411
|
-
|
412
|
-
expect(response).to be_successful
|
413
|
-
expect(response).to render_template :checkout_step1
|
414
|
-
expect(assigns(:order)).to eq order
|
415
|
-
expect(assigns(:page_title)).to eq 'Checkout'
|
416
|
-
end
|
417
|
-
end
|
418
|
-
|
419
|
-
context 'when purchased order' do
|
420
|
-
let(:order) { FactoryGirl.create(:purchased_order, user: user) }
|
421
|
-
|
422
|
-
it 'should render order show page successfully' do
|
423
|
-
get :show, id: order.to_param
|
424
|
-
|
425
|
-
expect(response).to be_successful
|
426
|
-
expect(response).to render_template :show
|
427
|
-
expect(assigns(:order)).to eq order
|
428
|
-
expect(assigns(:page_title)).to eq 'Receipt'
|
429
|
-
end
|
430
|
-
end
|
431
|
-
end
|
432
|
-
end
|
433
|
-
|
434
|
-
describe '#purchased' do
|
435
|
-
before(:each) do
|
436
|
-
sign_in purchased_order.user
|
437
|
-
end
|
438
|
-
|
439
|
-
it 'finds the order by obfuscated ID' do
|
440
|
-
get :purchased, id: purchased_order.to_param
|
441
|
-
assigns(:order).id.should eq purchased_order.id
|
442
|
-
end
|
443
|
-
|
444
|
-
it 'does not find an order by regular ID' do
|
445
|
-
expect { get :purchased, id: purchased_order.id }.to raise_error(ActiveRecord::RecordNotFound)
|
446
|
-
end
|
447
|
-
end
|
448
|
-
|
449
|
-
describe '#declined' do
|
450
|
-
before(:each) do
|
451
|
-
sign_in purchased_order.user
|
452
|
-
end
|
453
|
-
|
454
|
-
it 'finds the order by obfuscated ID' do
|
455
|
-
get :declined, id: purchased_order.to_param
|
456
|
-
assigns(:order).id.should eq purchased_order.id
|
457
|
-
end
|
458
|
-
|
459
|
-
it 'does not find an order by regular ID' do
|
460
|
-
expect { get :declined, id: purchased_order.id }.to raise_error(ActiveRecord::RecordNotFound)
|
461
|
-
end
|
462
|
-
end
|
463
|
-
|
464
|
-
describe 'POST #pay_by_cheque' do
|
465
|
-
let(:user) { FactoryGirl.create(:user) }
|
466
|
-
let(:order) { FactoryGirl.create(:order, user: user) }
|
467
|
-
let!(:cart) { FactoryGirl.create(:cart_with_items, user: user) }
|
468
|
-
|
469
|
-
before { sign_in user }
|
470
|
-
|
471
|
-
context 'when success' do
|
472
|
-
it 'should update order state, empty cart and redirect to order show page with success message' do
|
473
|
-
Effective::OrdersMailer.deliveries.clear
|
474
|
-
|
475
|
-
post :pay_by_cheque, id: order.to_param
|
476
|
-
|
477
|
-
expect(assigns(:order).pending?).to be_truthy
|
478
|
-
expect(Effective::Cart.first).to be_nil
|
479
|
-
flash[:success].present?.should eq true
|
480
|
-
response.should render_template(:pay_by_cheque)
|
481
|
-
Effective::OrdersMailer.deliveries.length.should eq 1
|
482
|
-
end
|
483
|
-
end
|
484
|
-
|
485
|
-
context 'when failed' do
|
486
|
-
before { Effective::Order.any_instance.stub(:save).and_return(false) }
|
487
|
-
|
488
|
-
it 'should not empty cart and redirect to order show page with danger message' do
|
489
|
-
Effective::OrdersMailer.deliveries.clear
|
490
|
-
post :pay_by_cheque, id: order.to_param
|
491
|
-
|
492
|
-
expect(response).to be_redirect
|
493
|
-
expect(response).to redirect_to EffectiveOrders::Engine.routes.url_helpers.order_path(order)
|
494
|
-
expect(Effective::Cart.first.empty?).to be_falsey
|
495
|
-
flash[:danger].present?.should eq true
|
496
|
-
Effective::OrdersMailer.deliveries.length.should eq 0
|
497
|
-
end
|
498
|
-
end
|
499
|
-
end
|
500
|
-
end
|