spree_frontend 3.2.9 → 3.3.0.rc1
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/app/controllers/spree/checkout_controller.rb +8 -2
- data/app/controllers/spree/orders_controller.rb +7 -3
- data/app/controllers/spree/products_controller.rb +3 -1
- data/app/helpers/spree/frontend_helper.rb +1 -1
- data/app/helpers/spree/taxons_helper.rb +2 -3
- data/app/views/spree/checkout/_confirm.html.erb +3 -0
- data/app/views/spree/checkout/_summary.html.erb +1 -1
- data/app/views/spree/checkout/payment/_storecredit.html.erb +1 -0
- data/app/views/spree/products/_cart_form.html.erb +3 -3
- data/app/views/spree/shared/_main_nav_bar.html.erb +1 -1
- data/app/views/spree/shared/_order_details.html.erb +0 -1
- data/app/views/spree/shared/_products.html.erb +4 -1
- data/spec/controllers/controller_extension_spec.rb +126 -0
- data/spec/controllers/controller_helpers_spec.rb +122 -0
- data/spec/controllers/spree/checkout_controller_spec.rb +547 -0
- data/spec/controllers/spree/checkout_controller_with_views_spec.rb +36 -0
- data/spec/controllers/spree/content_controller_spec.rb +12 -0
- data/spec/controllers/spree/current_order_tracking_spec.rb +44 -0
- data/spec/controllers/spree/home_controller_spec.rb +47 -0
- data/spec/controllers/spree/orders_controller_ability_spec.rb +96 -0
- data/spec/controllers/spree/orders_controller_spec.rb +134 -0
- data/spec/controllers/spree/orders_controller_transitions_spec.rb +31 -0
- data/spec/controllers/spree/products_controller_spec.rb +87 -0
- data/spec/controllers/spree/taxons_controller_spec.rb +12 -0
- data/spec/features/address_spec.rb +93 -0
- data/spec/features/automatic_promotion_adjustments_spec.rb +47 -0
- data/spec/features/caching/products_spec.rb +59 -0
- data/spec/features/caching/taxons_spec.rb +22 -0
- data/spec/features/cart_spec.rb +132 -0
- data/spec/features/checkout_spec.rb +723 -0
- data/spec/features/checkout_unshippable_spec.rb +34 -0
- data/spec/features/coupon_code_spec.rb +88 -0
- data/spec/features/currency_spec.rb +18 -0
- data/spec/features/delivery_spec.rb +64 -0
- data/spec/features/free_shipping_promotions_spec.rb +59 -0
- data/spec/features/locale_spec.rb +60 -0
- data/spec/features/microdata_spec.rb +0 -0
- data/spec/features/order_spec.rb +107 -0
- data/spec/features/page_promotions_spec.rb +36 -0
- data/spec/features/products_spec.rb +345 -0
- data/spec/features/taxons_spec.rb +147 -0
- data/spec/features/template_rendering_spec.rb +19 -0
- data/spec/helpers/frontend_helper_spec.rb +57 -0
- data/spec/helpers/taxons_helper_spec.rb +17 -0
- data/spec/spec_helper.rb +128 -0
- data/spec/support/shared_contexts/checkout_setup.rb +10 -0
- data/spec/support/shared_contexts/custom_products.rb +25 -0
- data/spec/support/shared_contexts/product_prototypes.rb +30 -0
- data/spec/views/spree/checkout/_summary_spec.rb +11 -0
- data/spree_frontend.gemspec +5 -4
- metadata +90 -15
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
describe OrdersController, type: :controller do
|
5
|
+
let(:user) { create(:user) }
|
6
|
+
let(:guest_user) { create(:user) }
|
7
|
+
let(:order) { Spree::Order.create }
|
8
|
+
|
9
|
+
context 'when an order exists in the cookies.signed' do
|
10
|
+
let(:token) { 'some_token' }
|
11
|
+
let(:specified_order) { create(:order) }
|
12
|
+
|
13
|
+
before do
|
14
|
+
cookies.signed[:guest_token] = token
|
15
|
+
allow(controller).to receive_messages current_order: order
|
16
|
+
allow(controller).to receive_messages spree_current_user: user
|
17
|
+
end
|
18
|
+
|
19
|
+
context '#populate' do
|
20
|
+
it 'should check if user is authorized for :edit' do
|
21
|
+
expect(controller).to receive(:authorize!).with(:edit, order, token)
|
22
|
+
spree_post :populate
|
23
|
+
end
|
24
|
+
it "should check against the specified order" do
|
25
|
+
expect(controller).to receive(:authorize!).with(:edit, specified_order, token)
|
26
|
+
spree_post :populate, id: specified_order.number
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context '#edit' do
|
31
|
+
it 'should check if user is authorized for :edit' do
|
32
|
+
expect(controller).to receive(:authorize!).with(:edit, order, token)
|
33
|
+
spree_get :edit
|
34
|
+
end
|
35
|
+
it "should check against the specified order" do
|
36
|
+
expect(controller).to receive(:authorize!).with(:edit, specified_order, token)
|
37
|
+
spree_get :edit, id: specified_order.number
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context '#update' do
|
42
|
+
it 'should check if user is authorized for :edit' do
|
43
|
+
allow(order).to receive :update_attributes
|
44
|
+
expect(controller).to receive(:authorize!).with(:edit, order, token)
|
45
|
+
spree_post :update, order: { email: "foo@bar.com" }
|
46
|
+
end
|
47
|
+
it "should check against the specified order" do
|
48
|
+
allow(order).to receive :update_attributes
|
49
|
+
expect(controller).to receive(:authorize!).with(:edit, specified_order, token)
|
50
|
+
spree_post :update, order: { email: "foo@bar.com" }, id: specified_order.number
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context '#empty' do
|
55
|
+
it 'should check if user is authorized for :edit' do
|
56
|
+
expect(controller).to receive(:authorize!).with(:edit, order, token)
|
57
|
+
spree_post :empty
|
58
|
+
end
|
59
|
+
it "should check against the specified order" do
|
60
|
+
expect(controller).to receive(:authorize!).with(:edit, specified_order, token)
|
61
|
+
spree_post :empty, id: specified_order.number
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "#show" do
|
66
|
+
it "should check against the specified order" do
|
67
|
+
expect(controller).to receive(:authorize!).with(:edit, specified_order, token)
|
68
|
+
spree_get :show, id: specified_order.number
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'when no authenticated user' do
|
74
|
+
let(:order) { create(:order, number: 'R123') }
|
75
|
+
|
76
|
+
context '#show' do
|
77
|
+
context 'when guest_token correct' do
|
78
|
+
before { cookies.signed[:guest_token] = order.guest_token }
|
79
|
+
|
80
|
+
it 'displays the page' do
|
81
|
+
expect(controller).to receive(:authorize!).with(:edit, order, order.guest_token)
|
82
|
+
spree_get :show, { id: 'R123' }
|
83
|
+
expect(response.code).to eq('200')
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'when guest_token not present' do
|
88
|
+
it 'should respond with 404' do
|
89
|
+
spree_get :show, { id: 'R123'}
|
90
|
+
expect(response.code).to eq('404')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Spree::OrdersController, type: :controller do
|
4
|
+
let(:user) { create(:user) }
|
5
|
+
|
6
|
+
context "Order model mock" do
|
7
|
+
let(:order) do
|
8
|
+
Spree::Order.create!
|
9
|
+
end
|
10
|
+
let(:variant) { create(:variant) }
|
11
|
+
|
12
|
+
before do
|
13
|
+
allow(controller).to receive_messages(try_spree_current_user: user)
|
14
|
+
end
|
15
|
+
|
16
|
+
context "#populate" do
|
17
|
+
it "should create a new order when none specified" do
|
18
|
+
spree_post :populate, {}, {}
|
19
|
+
expect(cookies.signed[:guest_token]).not_to be_blank
|
20
|
+
expect(Spree::Order.find_by_guest_token(cookies.signed[:guest_token])).to be_persisted
|
21
|
+
end
|
22
|
+
|
23
|
+
context "with Variant" do
|
24
|
+
it "should handle population" do
|
25
|
+
expect do
|
26
|
+
spree_post :populate, variant_id: variant.id, quantity: 5
|
27
|
+
end.to change { user.orders.count }.by(1)
|
28
|
+
order = user.orders.last
|
29
|
+
expect(response).to redirect_to spree.cart_path
|
30
|
+
expect(order.line_items.size).to eq(1)
|
31
|
+
line_item = order.line_items.first
|
32
|
+
expect(line_item.variant_id).to eq(variant.id)
|
33
|
+
expect(line_item.quantity).to eq(5)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "shows an error when population fails" do
|
37
|
+
request.env["HTTP_REFERER"] = '/dummy_redirect'
|
38
|
+
allow_any_instance_of(Spree::LineItem).to(
|
39
|
+
receive(:valid?).and_return(false)
|
40
|
+
)
|
41
|
+
allow_any_instance_of(Spree::LineItem).to(
|
42
|
+
receive_message_chain(:errors, :full_messages).
|
43
|
+
and_return(["Order population failed"])
|
44
|
+
)
|
45
|
+
|
46
|
+
spree_post :populate, variant_id: variant.id, quantity: 5
|
47
|
+
|
48
|
+
expect(response).to redirect_to('/dummy_redirect')
|
49
|
+
expect(flash[:error]).to eq("Order population failed")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "shows an error when quantity is invalid" do
|
53
|
+
request.env["HTTP_REFERER"] = '/dummy_redirect'
|
54
|
+
|
55
|
+
spree_post(
|
56
|
+
:populate,
|
57
|
+
variant_id: variant.id, quantity: -1
|
58
|
+
)
|
59
|
+
|
60
|
+
expect(response).to redirect_to('/dummy_redirect')
|
61
|
+
expect(flash[:error]).to eq(
|
62
|
+
Spree.t(:please_enter_reasonable_quantity)
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "#update" do
|
69
|
+
context "with authorization" do
|
70
|
+
before do
|
71
|
+
allow(controller).to receive :check_authorization
|
72
|
+
allow(controller).to receive_messages current_order: order
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should render the edit view (on failure)" do
|
76
|
+
# email validation is only after address state
|
77
|
+
order.update_column(:state, "delivery")
|
78
|
+
spree_put :update, { order: { email: "" } }, { order_id: order.id }
|
79
|
+
expect(response).to render_template :edit
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should redirect to cart path (on success)" do
|
83
|
+
allow(order).to receive(:update_attributes).and_return true
|
84
|
+
spree_put :update, {}, {order_id: 1}
|
85
|
+
expect(response).to redirect_to(spree.cart_path)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "#empty" do
|
91
|
+
before do
|
92
|
+
allow(controller).to receive :check_authorization
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should destroy line items in the current order" do
|
96
|
+
allow(controller).to receive(:current_order).and_return(order)
|
97
|
+
expect(order).to receive(:empty!)
|
98
|
+
spree_put :empty
|
99
|
+
expect(response).to redirect_to(spree.cart_path)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Regression test for #2750
|
104
|
+
context "#update" do
|
105
|
+
before do
|
106
|
+
allow(user).to receive :last_incomplete_spree_order
|
107
|
+
allow(controller).to receive :set_current_order
|
108
|
+
end
|
109
|
+
|
110
|
+
it "cannot update a blank order" do
|
111
|
+
spree_put :update, order: { email: "foo" }
|
112
|
+
expect(flash[:error]).to eq(Spree.t(:order_not_found))
|
113
|
+
expect(response).to redirect_to(spree.root_path)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "line items quantity is 0" do
|
119
|
+
let(:order) { Spree::Order.create }
|
120
|
+
let(:variant) { create(:variant) }
|
121
|
+
let!(:line_item) { order.contents.add(variant, 1) }
|
122
|
+
|
123
|
+
before do
|
124
|
+
allow(controller).to receive(:check_authorization)
|
125
|
+
allow(controller).to receive_messages(current_order: order)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "removes line items on update" do
|
129
|
+
expect(order.line_items.count).to eq 1
|
130
|
+
spree_put :update, order: { line_items_attributes: { "0" => { id: line_item.id, quantity: 0 } } }
|
131
|
+
expect(order.reload.line_items.count).to eq 0
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
Spree::Order.class_eval do
|
4
|
+
attr_accessor :did_transition
|
5
|
+
end
|
6
|
+
|
7
|
+
module Spree
|
8
|
+
describe OrdersController, type: :controller do
|
9
|
+
# Regression test for #2004
|
10
|
+
context "with a transition callback on first state" do
|
11
|
+
let(:order) { Spree::Order.new }
|
12
|
+
|
13
|
+
before do
|
14
|
+
allow(controller).to receive_messages current_order: order
|
15
|
+
expect(controller).to receive(:authorize!).at_least(:once).and_return(true)
|
16
|
+
|
17
|
+
first_state, _ = Spree::Order.checkout_steps.first
|
18
|
+
Spree::Order.state_machine.after_transition to: first_state do |order|
|
19
|
+
order.did_transition = true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "correctly calls the transition callback" do
|
24
|
+
expect(order.did_transition).to be_nil
|
25
|
+
order.line_items << FactoryGirl.create(:line_item)
|
26
|
+
spree_put :update, { checkout: "checkout" }, { order_id: 1}
|
27
|
+
expect(order.did_transition).to be true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Spree::ProductsController, type: :controller do
|
4
|
+
let!(:product) { create(:product, available_on: 1.year.from_now) }
|
5
|
+
let(:taxon) { create(:taxon) }
|
6
|
+
|
7
|
+
# Regression test for #1390
|
8
|
+
it "allows admins to view non-active products" do
|
9
|
+
allow(controller).to receive_messages spree_current_user: mock_model(Spree.user_class, has_spree_role?: true, last_incomplete_spree_order: nil, spree_api_key: 'fake')
|
10
|
+
spree_get :show, id: product.to_param
|
11
|
+
expect(response.status).to eq(200)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "cannot view non-active products" do
|
15
|
+
spree_get :show, id: product.to_param
|
16
|
+
expect(response.status).to eq(404)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should provide the current user to the searcher class" do
|
20
|
+
user = mock_model(Spree.user_class, last_incomplete_spree_order: nil, spree_api_key: 'fake')
|
21
|
+
allow(controller).to receive_messages spree_current_user: user
|
22
|
+
expect_any_instance_of(Spree::Config.searcher_class).to receive(:current_user=).with(user)
|
23
|
+
spree_get :index
|
24
|
+
expect(response.status).to eq(200)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Regression test for #2249
|
28
|
+
it "doesn't error when given an invalid referer" do
|
29
|
+
current_user = mock_model(Spree.user_class, has_spree_role?: true, last_incomplete_spree_order: nil, generate_spree_api_key!: nil)
|
30
|
+
allow(controller).to receive_messages spree_current_user: current_user
|
31
|
+
request.env['HTTP_REFERER'] = "not|a$url"
|
32
|
+
|
33
|
+
# Previously a URI::InvalidURIError exception was being thrown
|
34
|
+
expect { spree_get :show, id: product.to_param }.not_to raise_error
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'with history slugs present' do
|
38
|
+
let!(:product) { create(:product, available_on: 1.day.ago) }
|
39
|
+
|
40
|
+
it 'will redirect with a 301 with legacy url used' do
|
41
|
+
legacy_params = product.to_param
|
42
|
+
product.name = product.name + " Brand New"
|
43
|
+
product.slug = nil
|
44
|
+
product.save!
|
45
|
+
spree_get :show, id: legacy_params
|
46
|
+
expect(response.status).to eq(301)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'will redirect with a 301 with id used' do
|
50
|
+
product.name = product.name + " Brand New"
|
51
|
+
product.slug = nil
|
52
|
+
product.save!
|
53
|
+
spree_get :show, id: product.id
|
54
|
+
expect(response.status).to eq(301)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "will keep url params on legacy url redirect" do
|
58
|
+
legacy_params = product.to_param
|
59
|
+
product.name = product.name + " Brand New"
|
60
|
+
product.slug = nil
|
61
|
+
product.save!
|
62
|
+
spree_get :show, id: legacy_params, taxon_id: taxon.id
|
63
|
+
expect(response.status).to eq(301)
|
64
|
+
expect(response.header["Location"]).to include("taxon_id=#{taxon.id}")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "index products" do
|
69
|
+
it "calls includes when the retrieved_products object responds to it" do
|
70
|
+
searcher = double("Searcher")
|
71
|
+
allow(controller).to receive_messages build_searcher: searcher
|
72
|
+
expect(searcher).to receive_message_chain("retrieve_products.includes")
|
73
|
+
|
74
|
+
spree_get :index
|
75
|
+
end
|
76
|
+
|
77
|
+
it "does not call includes when it's not available" do
|
78
|
+
searcher = double("Searcher")
|
79
|
+
allow(controller).to receive_messages build_searcher: searcher
|
80
|
+
allow(searcher).to receive(:retrieve_products).and_return([])
|
81
|
+
|
82
|
+
spree_get :index
|
83
|
+
|
84
|
+
expect(assigns(:products)).to eq([])
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Spree::TaxonsController, type: :controller do
|
4
|
+
it "should provide the current user to the searcher class" do
|
5
|
+
taxon = create(:taxon, permalink: "test")
|
6
|
+
user = mock_model(Spree.user_class, last_incomplete_spree_order: nil, spree_api_key: 'fake')
|
7
|
+
allow(controller).to receive_messages spree_current_user: user
|
8
|
+
expect_any_instance_of(Spree::Config.searcher_class).to receive(:current_user=).with(user)
|
9
|
+
spree_get :show, id: taxon.permalink
|
10
|
+
expect(response.status).to eq(200)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Address", type: :feature, inaccessible: true do
|
4
|
+
let!(:product) { create(:product, name: "RoR Mug") }
|
5
|
+
let!(:order) { create(:order_with_totals, state: 'cart') }
|
6
|
+
|
7
|
+
stub_authorization!
|
8
|
+
|
9
|
+
after do
|
10
|
+
Capybara.ignore_hidden_elements = true
|
11
|
+
end
|
12
|
+
|
13
|
+
before do
|
14
|
+
Capybara.ignore_hidden_elements = false
|
15
|
+
|
16
|
+
visit spree.root_path
|
17
|
+
|
18
|
+
click_link "RoR Mug"
|
19
|
+
click_button "add-to-cart-button"
|
20
|
+
|
21
|
+
address = "order_bill_address_attributes"
|
22
|
+
@country_css = "#{address}_country_id"
|
23
|
+
@state_select_css = "##{address}_state_id"
|
24
|
+
@state_name_css = "##{address}_state_name"
|
25
|
+
end
|
26
|
+
|
27
|
+
context "country requires state", js: true, focus: true do
|
28
|
+
let!(:canada) { create(:country, name: "Canada", states_required: true, iso: "CA") }
|
29
|
+
let!(:uk) { create(:country, name: "United Kingdom", states_required: true, iso: "UK") }
|
30
|
+
|
31
|
+
before { Spree::Config[:default_country_id] = uk.id }
|
32
|
+
|
33
|
+
context "but has no state" do
|
34
|
+
it "shows the state input field" do
|
35
|
+
click_button "Checkout"
|
36
|
+
|
37
|
+
select canada.name, from: @country_css
|
38
|
+
expect(page).to have_selector(@state_select_css, visible: false)
|
39
|
+
expect(page).to have_selector(@state_name_css, visible: true)
|
40
|
+
expect(find(@state_name_css)['class']).not_to match(/hidden/)
|
41
|
+
expect(find(@state_name_css)['class']).to match(/required/)
|
42
|
+
expect(find(@state_select_css)['class']).not_to match(/required/)
|
43
|
+
expect(page).not_to have_selector("input#{@state_name_css}[disabled]")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "and has state" do
|
48
|
+
before { create(:state, name: "Ontario", country: canada) }
|
49
|
+
|
50
|
+
it "shows the state collection selection" do
|
51
|
+
click_button "Checkout"
|
52
|
+
|
53
|
+
select canada.name, from: @country_css
|
54
|
+
expect(page).to have_selector(@state_select_css, visible: true)
|
55
|
+
expect(page).to have_selector(@state_name_css, visible: false)
|
56
|
+
expect(find(@state_select_css)['class']).to match(/required/)
|
57
|
+
expect(find(@state_select_css)['class']).not_to match(/hidden/)
|
58
|
+
expect(find(@state_name_css)['class']).not_to match(/required/)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "user changes to country without states required" do
|
63
|
+
let!(:france) { create(:country, name: "France", states_required: false, iso: "FRA") }
|
64
|
+
|
65
|
+
it "clears the state name" do
|
66
|
+
skip "This is failing on the CI server, but not when you run the tests manually... It also does not fail locally on a machine."
|
67
|
+
click_button "Checkout"
|
68
|
+
select canada.name, from: @country_css
|
69
|
+
page.find(@state_name_css).set("Toscana")
|
70
|
+
|
71
|
+
select france.name, from: @country_css
|
72
|
+
expect(page.find(@state_name_css)).to have_content('')
|
73
|
+
until page.evaluate_script("$.active").to_i == 0
|
74
|
+
expect(find(@state_name_css)['class']).not_to match(/hidden/)
|
75
|
+
expect(find(@state_name_css)['class']).not_to match(/required/)
|
76
|
+
expect(find(@state_select_css)['class']).not_to match(/required/)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "country does not require state", js: true do
|
83
|
+
let!(:france) { create(:country, name: "France", states_required: false, iso: "FRA") }
|
84
|
+
|
85
|
+
it "shows a disabled state input field" do
|
86
|
+
click_button "Checkout"
|
87
|
+
|
88
|
+
select france.name, from: @country_css
|
89
|
+
expect(page).to have_selector(@state_select_css, visible: false)
|
90
|
+
expect(page).to have_selector(@state_name_css, visible: false)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Automatic promotions", type: :feature, js: true do
|
4
|
+
let!(:country) { create(:country, name: "United States of America", states_required: true) }
|
5
|
+
let!(:state) { create(:state, name: "Alabama", country: country) }
|
6
|
+
let!(:zone) { create(:zone) }
|
7
|
+
let!(:shipping_method) { create(:shipping_method) }
|
8
|
+
let!(:payment_method) { create(:check_payment_method) }
|
9
|
+
let!(:product) { create(:product, name: "RoR Mug", price: 20) }
|
10
|
+
|
11
|
+
let!(:promotion) do
|
12
|
+
promotion = Spree::Promotion.create!(name: "$10 off when you spend more than $100")
|
13
|
+
|
14
|
+
calculator = Spree::Calculator::FlatRate.new
|
15
|
+
calculator.preferred_amount = 10
|
16
|
+
|
17
|
+
rule = Spree::Promotion::Rules::ItemTotal.create
|
18
|
+
rule.preferred_amount_min = 100
|
19
|
+
rule.save
|
20
|
+
|
21
|
+
promotion.rules << rule
|
22
|
+
|
23
|
+
action = Spree::Promotion::Actions::CreateAdjustment.create
|
24
|
+
action.calculator = calculator
|
25
|
+
action.save
|
26
|
+
|
27
|
+
promotion.actions << action
|
28
|
+
end
|
29
|
+
|
30
|
+
context "on the cart page" do
|
31
|
+
|
32
|
+
before do
|
33
|
+
visit spree.root_path
|
34
|
+
click_link product.name
|
35
|
+
click_button "add-to-cart-button"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "automatically applies the promotion once the order crosses the threshold" do
|
39
|
+
fill_in "order_line_items_attributes_0_quantity", with: 10
|
40
|
+
click_button "Update"
|
41
|
+
expect(page).to have_content("Promotion ($10 off when you spend more than $100) -$10.00")
|
42
|
+
fill_in "order_line_items_attributes_0_quantity", with: 1
|
43
|
+
click_button "Update"
|
44
|
+
expect(page).not_to have_content("Promotion ($10 off when you spend more than $100) -$10.00")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'products', type: :feature, caching: true do
|
4
|
+
let!(:product) { create(:product) }
|
5
|
+
let!(:product2) { create(:product) }
|
6
|
+
let!(:taxonomy) { create(:taxonomy) }
|
7
|
+
let!(:taxon) { create(:taxon, taxonomy: taxonomy) }
|
8
|
+
|
9
|
+
before { Timecop.scale(1000) }
|
10
|
+
|
11
|
+
after { Timecop.return }
|
12
|
+
|
13
|
+
before do
|
14
|
+
product2.update_column(:updated_at, 1.day.ago)
|
15
|
+
# warm up the cache
|
16
|
+
visit spree.root_path
|
17
|
+
assert_written_to_cache("views/en/USD/spree/products/all--#{product.updated_at.utc.to_s(:number)}")
|
18
|
+
assert_written_to_cache("views/en/USD/spree/products/#{product.id}-#{product.updated_at.utc.to_s(:number)}")
|
19
|
+
assert_written_to_cache("views/en/spree/taxonomies/#{taxonomy.id}")
|
20
|
+
assert_written_to_cache("views/en/taxons/#{taxon.updated_at.utc.to_i}")
|
21
|
+
|
22
|
+
clear_cache_events
|
23
|
+
end
|
24
|
+
|
25
|
+
it "reads from cache upon a second viewing" do
|
26
|
+
visit spree.root_path
|
27
|
+
expect(cache_writes.count).to eq(0)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "busts the cache when a product is updated" do
|
31
|
+
product.update_column(:updated_at, 1.day.from_now)
|
32
|
+
visit spree.root_path
|
33
|
+
assert_written_to_cache("views/en/USD/spree/products/all--#{product.updated_at.utc.to_s(:number)}")
|
34
|
+
assert_written_to_cache("views/en/USD/spree/products/#{product.id}-#{product.updated_at.utc.to_s(:number)}")
|
35
|
+
expect(cache_writes.count).to eq(2)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "busts the cache when all products are deleted" do
|
39
|
+
product.destroy
|
40
|
+
product2.destroy
|
41
|
+
visit spree.root_path
|
42
|
+
assert_written_to_cache("views/en/USD/spree/products/all--#{Date.today.to_s(:number)}-0")
|
43
|
+
expect(cache_writes.count).to eq(1)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "busts the cache when the newest product is deleted" do
|
47
|
+
product.destroy
|
48
|
+
visit spree.root_path
|
49
|
+
assert_written_to_cache("views/en/USD/spree/products/all--#{product2.updated_at.utc.to_s(:number)}")
|
50
|
+
expect(cache_writes.count).to eq(1)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "busts the cache when an older product is deleted" do
|
54
|
+
product2.destroy
|
55
|
+
visit spree.root_path
|
56
|
+
assert_written_to_cache("views/en/USD/spree/products/all--#{product.updated_at.utc.to_s(:number)}")
|
57
|
+
expect(cache_writes.count).to eq(1)
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'taxons', type: :feature, caching: true do
|
4
|
+
let!(:taxonomy) { create(:taxonomy) }
|
5
|
+
let!(:taxon) { create(:taxon, taxonomy: taxonomy) }
|
6
|
+
|
7
|
+
before do
|
8
|
+
# warm up the cache
|
9
|
+
visit spree.root_path
|
10
|
+
assert_written_to_cache("views/en/spree/taxonomies/#{taxonomy.id}")
|
11
|
+
assert_written_to_cache("views/en/taxons/#{taxon.updated_at.utc.to_i}")
|
12
|
+
|
13
|
+
clear_cache_events
|
14
|
+
end
|
15
|
+
|
16
|
+
it "busts the cache when max_level_in_taxons_menu conf changes" do
|
17
|
+
Spree::Config[:max_level_in_taxons_menu] = 5
|
18
|
+
visit spree.root_path
|
19
|
+
assert_written_to_cache("views/en/spree/taxonomies/#{taxonomy.id}")
|
20
|
+
expect(cache_writes.count).to eq(1)
|
21
|
+
end
|
22
|
+
end
|