mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-27 21:06:49 +00:00
Direct calls to Flipper have the downside that we can't add any new functionality like storing the feature in the database when used.
954 lines
35 KiB
Ruby
954 lines
35 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "system_helper"
|
|
|
|
describe "As a consumer, I want to checkout my order", js: true do
|
|
include ShopWorkflow
|
|
include SplitCheckoutHelper
|
|
include FileHelper
|
|
include StripeHelper
|
|
include StripeStubs
|
|
include PaypalHelper
|
|
include AuthenticationHelper
|
|
|
|
let!(:zone) { create(:zone_with_member) }
|
|
let(:supplier) { create(:supplier_enterprise) }
|
|
let(:distributor) { create(:distributor_enterprise, charges_sales_tax: true) }
|
|
let(:product) {
|
|
create(:taxed_product, supplier: supplier, price: 10, zone: zone, tax_rate_amount: 0.1)
|
|
}
|
|
let(:variant) { product.variants.first }
|
|
let!(:order_cycle) {
|
|
create(:simple_order_cycle, suppliers: [supplier], distributors: [distributor],
|
|
coordinator: create(:distributor_enterprise), variants: [variant])
|
|
}
|
|
let(:order) {
|
|
create(:order, order_cycle: order_cycle, distributor: distributor, bill_address_id: nil,
|
|
ship_address_id: nil, state: "cart",
|
|
line_items: [create(:line_item, variant: variant)])
|
|
}
|
|
|
|
let(:fee_tax_rate) { create(:tax_rate, amount: 0.10, zone: zone, included_in_price: true) }
|
|
let(:fee_tax_category) { create(:tax_category, tax_rates: [fee_tax_rate]) }
|
|
let(:enterprise_fee) { create(:enterprise_fee, amount: 1.23, tax_category: fee_tax_category) }
|
|
|
|
let(:free_shipping_with_required_address) {
|
|
create(:shipping_method, require_ship_address: true, name: "A Free Shipping with required address")
|
|
}
|
|
let(:free_shipping) {
|
|
create(:shipping_method, require_ship_address: false, name: "free Shipping", description: "yellow",
|
|
calculator: Calculator::FlatRate.new(preferred_amount: 0.00))
|
|
}
|
|
let(:shipping_tax_rate) { create(:tax_rate, amount: 0.25, zone: zone, included_in_price: true) }
|
|
let(:shipping_tax_category) { create(:tax_category, tax_rates: [shipping_tax_rate]) }
|
|
let(:shipping_with_fee) {
|
|
create(:shipping_method, require_ship_address: true, tax_category: shipping_tax_category,
|
|
name: "Shipping with Fee", description: "blue",
|
|
calculator: Calculator::FlatRate.new(preferred_amount: 4.56))
|
|
}
|
|
let(:free_shipping_without_required_address) {
|
|
create(:shipping_method, require_ship_address: false, name: "Z Free Shipping without required address")
|
|
}
|
|
let(:tagged_shipping) {
|
|
create(:shipping_method, require_ship_address: false, name: "Local", tag_list: "local")
|
|
}
|
|
let!(:payment_with_fee) {
|
|
create(:payment_method, distributors: [distributor],
|
|
name: "Payment with Fee", description: "Payment with fee",
|
|
calculator: Calculator::FlatRate.new(preferred_amount: 1.23))
|
|
}
|
|
let(:shipping_backoffice_only) {
|
|
create(:shipping_method, require_ship_address: true, name: "Shipping Backoffice Only", display_on: "back_end")
|
|
}
|
|
let(:shipping_methods) {
|
|
[free_shipping_with_required_address, free_shipping, shipping_with_fee, free_shipping_without_required_address, tagged_shipping]
|
|
}
|
|
|
|
before do
|
|
allow(OpenFoodNetwork::FeatureToggle).to receive(:enabled?).with(:split_checkout).and_return(true)
|
|
allow(OpenFoodNetwork::FeatureToggle).to receive(:enabled?).with(:split_checkout, anything).and_return(true)
|
|
|
|
add_enterprise_fee enterprise_fee
|
|
set_order order
|
|
|
|
distributor.shipping_methods.push(shipping_methods)
|
|
end
|
|
|
|
context "guest checkout when distributor doesn't allow guest orders" do
|
|
before do
|
|
distributor.update_columns allow_guest_orders: false
|
|
visit checkout_step_path(:details)
|
|
end
|
|
|
|
it "should display the split checkout login page" do
|
|
expect(page).to have_content("Ok, ready to checkout?")
|
|
expect(page).to have_content("Login")
|
|
expect(page).to have_no_content("Checkout as guest")
|
|
end
|
|
|
|
it "should show the login modal when clicking the login button" do
|
|
click_on "Login"
|
|
expect(page).to have_selector ".login-modal"
|
|
end
|
|
end
|
|
|
|
shared_examples "when I have an out of stock product in my cart" do
|
|
before do
|
|
variant.update!(on_demand: false, on_hand: 0)
|
|
end
|
|
|
|
it "returns me to the cart with an error message" do
|
|
visit checkout_path
|
|
|
|
expect(page).not_to have_selector 'closing', text: "Checkout now"
|
|
expect(page).to have_selector 'closing', text: "Your shopping cart"
|
|
expect(page).to have_content "An item in your cart has become unavailable"
|
|
expect(page).to have_content "Update"
|
|
end
|
|
end
|
|
|
|
context "as a guest user" do
|
|
before do
|
|
visit checkout_path
|
|
end
|
|
|
|
context "actually user has an account and wants to login" do
|
|
let(:user) { create(:user) }
|
|
|
|
it "should redirect to '/checkout/details' when user submit the login form" do
|
|
expect(page).to have_content("Ok, ready to checkout?")
|
|
|
|
click_on "Login"
|
|
within ".login-modal" do
|
|
fill_in_and_submit_login_form(user)
|
|
end
|
|
|
|
expect_logged_in
|
|
expect(page).not_to have_selector ".login-modal"
|
|
expect_to_be_on_first_step
|
|
end
|
|
end
|
|
|
|
it "should display the split checkout login/guest form" do
|
|
expect(page).to have_content distributor.name
|
|
expect(page).to have_content("Ok, ready to checkout?")
|
|
expect(page).to have_content("Login")
|
|
expect(page).to have_content("Checkout as guest")
|
|
end
|
|
|
|
it "should display the split checkout details page" do
|
|
click_on "Checkout as guest"
|
|
expect(page).to have_content distributor.name
|
|
expect_to_be_on_first_step
|
|
end
|
|
|
|
context "when no shipping methods are available" do
|
|
before do
|
|
shipping_methods.each { |sm| sm.update(tag_list: "hidden") }
|
|
end
|
|
|
|
it "should display an error message" do
|
|
create(:filter_shipping_methods_tag_rule,
|
|
enterprise: distributor,
|
|
is_default: true,
|
|
preferred_shipping_method_tags: "hidden",
|
|
preferred_matched_shipping_methods_visibility: 'hidden')
|
|
|
|
visit checkout_path
|
|
expect(page).to have_content "Checkout is not possible due to absence of shipping options. Please contact the shop owner."
|
|
end
|
|
end
|
|
|
|
it "should display error when fields are empty" do
|
|
click_on "Checkout as guest"
|
|
click_button "Next - Payment method"
|
|
expect(page).to have_content("Saving failed, please update the highlighted fields")
|
|
expect(page).to have_css 'span.field_with_errors label', count: 6
|
|
expect(page).to have_css 'span.field_with_errors input', count: 6
|
|
expect(page).to have_css 'span.formError', count: 7
|
|
end
|
|
|
|
it "should validate once each needed field is filled" do
|
|
click_on "Checkout as guest"
|
|
fill_in "First Name", with: "Jane"
|
|
fill_in "Last Name", with: "Doe"
|
|
fill_in "Phone number", with: "07987654321"
|
|
fill_in "Address (Street + House Number)", with: "Flat 1 Elm apartments"
|
|
fill_in "City", with: "London"
|
|
fill_in "Postcode", with: "SW1A 1AA"
|
|
choose free_shipping.name
|
|
|
|
click_button "Next - Payment method"
|
|
expect(page).to have_button("Next - Order summary")
|
|
end
|
|
|
|
context "on the 'details' step" do
|
|
before do
|
|
visit checkout_step_path(:details)
|
|
click_on "Checkout as guest"
|
|
end
|
|
|
|
it "should allow visit '/checkout/details'" do
|
|
expect(page).to have_current_path("/checkout/details")
|
|
end
|
|
|
|
it 'does not show the save as default bill address checkbox' do
|
|
expect(page).not_to have_content "Save as default billing address"
|
|
end
|
|
|
|
it 'does not show the save as default ship address checkbox' do
|
|
choose free_shipping_with_required_address.name
|
|
uncheck "ship_address_same_as_billing"
|
|
expect(page).not_to have_content "Save as default shipping address"
|
|
end
|
|
|
|
it 'display shipping methods alphabetically' do
|
|
shipping_methods = page.all(:field, "shipping_method_id").map { |field| field.sibling("label") }.map(&:text)
|
|
expect(shipping_methods).to eq ["A Free Shipping with required address", "free Shipping", "Local", "Shipping with Fee", "Z Free Shipping without required address"]
|
|
end
|
|
|
|
it_behaves_like "when I have an out of stock product in my cart"
|
|
end
|
|
|
|
context "on the 'payment' step" do
|
|
before do
|
|
order.update(state: "payment")
|
|
visit checkout_step_path(:payment)
|
|
end
|
|
|
|
it "should allow visit '/checkout/payment'" do
|
|
expect(page).to have_current_path("/checkout/payment")
|
|
end
|
|
|
|
it_behaves_like "when I have an out of stock product in my cart"
|
|
end
|
|
|
|
describe "hidding a shipping method" do
|
|
let(:user) { create(:user) }
|
|
let(:customer) { create(:customer, user: user, enterprise: distributor) }
|
|
|
|
it "shows shipping methods allowed by the rule" do
|
|
visit checkout_path
|
|
click_on "Checkout as guest"
|
|
|
|
# No rules in effect
|
|
expect(page).to have_content free_shipping.name
|
|
expect(page).to have_content shipping_with_fee.name
|
|
expect(page).to have_content free_shipping_without_required_address.name
|
|
expect(page).to have_content tagged_shipping.name
|
|
|
|
create(:filter_shipping_methods_tag_rule,
|
|
enterprise: distributor,
|
|
preferred_customer_tags: "local",
|
|
preferred_shipping_method_tags: "local",
|
|
preferred_matched_shipping_methods_visibility: 'visible')
|
|
create(:filter_shipping_methods_tag_rule,
|
|
enterprise: distributor,
|
|
is_default: true,
|
|
preferred_shipping_method_tags: "local",
|
|
preferred_matched_shipping_methods_visibility: 'hidden')
|
|
|
|
visit checkout_path
|
|
|
|
# Default rule in effect, disallows access to 'Local'
|
|
expect(page).to have_content free_shipping.name
|
|
expect(page).to have_content shipping_with_fee.name
|
|
expect(page).to have_content free_shipping_without_required_address.name
|
|
expect(page).not_to have_content tagged_shipping.name
|
|
|
|
login_as(user)
|
|
visit checkout_path
|
|
|
|
# Default rule in still effect, disallows access to 'Local'
|
|
expect(page).to have_content free_shipping.name
|
|
expect(page).to have_content shipping_with_fee.name
|
|
expect(page).to have_content free_shipping_without_required_address.name
|
|
expect(page).not_to have_content tagged_shipping.name
|
|
|
|
customer.update_attribute(:tag_list, "local")
|
|
visit checkout_path
|
|
|
|
# #local Customer can access 'Local' shipping method
|
|
expect(page).to have_content free_shipping.name
|
|
expect(page).to have_content shipping_with_fee.name
|
|
expect(page).to have_content free_shipping_without_required_address.name
|
|
expect(page).to have_content tagged_shipping.name
|
|
end
|
|
end
|
|
end
|
|
|
|
context "as a logged in user" do
|
|
let(:user) { create(:user) }
|
|
|
|
before do
|
|
login_as(user)
|
|
visit checkout_path
|
|
end
|
|
|
|
context "details step" do
|
|
context "when form is submitted but invalid" do
|
|
it "display the checkbox about shipping address same as billing address when selecting a shipping method that requires ship address" do
|
|
choose free_shipping_with_required_address.name
|
|
check "Shipping address same as billing address?"
|
|
expect(page).to have_content "Save as default shipping address"
|
|
|
|
click_button "Next - Payment method"
|
|
|
|
expect(page).to have_content "Saving failed, please update the highlighted fields."
|
|
expect(page).to have_content "Shipping address same as billing address?"
|
|
expect(page).to have_content "Save as default shipping address"
|
|
expect(page).to have_checked_field "Shipping address same as billing address?"
|
|
end
|
|
end
|
|
|
|
describe "filling out order details" do
|
|
before do
|
|
fill_out_details
|
|
fill_out_billing_address
|
|
order.update(user_id: user.id)
|
|
end
|
|
|
|
context "billing address" do
|
|
describe "checking the default address box" do
|
|
before do
|
|
check "order_save_bill_address"
|
|
choose free_shipping.name
|
|
end
|
|
|
|
it "creates a new default bill address" do
|
|
expect {
|
|
proceed_to_payment
|
|
order.reload
|
|
user.reload
|
|
}.to change {
|
|
order.bill_address&.address1
|
|
}.from(nil).to("Rue de la Vie, 77")
|
|
.and change {
|
|
order.customer&.bill_address&.address1
|
|
}.from(nil).to("Rue de la Vie, 77")
|
|
.and change {
|
|
order.bill_address&.address1
|
|
}
|
|
.from(nil).to("Rue de la Vie, 77")
|
|
end
|
|
end
|
|
|
|
describe "unchecking the default address box" do
|
|
before do
|
|
uncheck "order_save_bill_address"
|
|
choose free_shipping.name
|
|
end
|
|
|
|
context "proceeding to payment" do
|
|
before do
|
|
expect {
|
|
proceed_to_payment
|
|
}.to_not change {
|
|
user.reload.bill_address
|
|
}
|
|
end
|
|
|
|
it "updates the bill address of the order and customer" do
|
|
expect(order.reload.bill_address.address1).to eq "Rue de la Vie, 77"
|
|
expect(order.customer.bill_address.address1).to eq "Rue de la Vie, 77"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "shipping address" do
|
|
describe "checking the default address box" do
|
|
before do
|
|
choose free_shipping_with_required_address.name
|
|
uncheck "ship_address_same_as_billing"
|
|
fill_out_shipping_address
|
|
check "order_save_ship_address"
|
|
end
|
|
|
|
context "proceeding to payment" do
|
|
it "creates a new default ship address" do
|
|
expect {
|
|
proceed_to_payment
|
|
order.reload
|
|
user.reload
|
|
}.to change {
|
|
order.ship_address&.address1
|
|
}.from(nil).to("Rue de la Vie, 66")
|
|
.and change {
|
|
order.customer&.ship_address&.address1
|
|
}.from(nil).to("Rue de la Vie, 66")
|
|
.and change {
|
|
order.ship_address&.address1
|
|
}
|
|
.from(nil).to("Rue de la Vie, 66")
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "unchecking the default address box" do
|
|
before do
|
|
choose free_shipping_with_required_address.name
|
|
uncheck "ship_address_same_as_billing"
|
|
fill_out_shipping_address
|
|
uncheck "order_save_ship_address"
|
|
end
|
|
|
|
context "proceeding to payment" do
|
|
before do
|
|
expect {
|
|
proceed_to_payment
|
|
}.to_not change {
|
|
user.reload.ship_address
|
|
}
|
|
end
|
|
|
|
it "updates the ship address of the order and customer" do
|
|
expect(order.reload.ship_address.address1).to eq "Rue de la Vie, 66"
|
|
expect(order.customer.ship_address.address1).to eq "Rue de la Vie, 66"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "selecting a pick-up shipping method and submiting the form" do
|
|
before do
|
|
choose free_shipping.name
|
|
end
|
|
|
|
it "redirects the user to the Payment Method step" do
|
|
fill_notes("SpEcIaL NoTeS")
|
|
proceed_to_payment
|
|
end
|
|
end
|
|
|
|
describe "selecting a delivery method with a shipping fee" do
|
|
before do
|
|
choose shipping_with_fee.name
|
|
end
|
|
|
|
context "with same shipping and billing address" do
|
|
before do
|
|
check "ship_address_same_as_billing"
|
|
end
|
|
|
|
it "displays the shipping fee" do
|
|
expect(page).to have_content("#{shipping_with_fee.name} " + with_currency(4.56).to_s)
|
|
end
|
|
|
|
it "does not display the shipping address form" do
|
|
expect(page).not_to have_field "order_ship_address_attributes_address1"
|
|
end
|
|
|
|
it "redirects the user to the Payment Method step, when submiting the form" do
|
|
proceed_to_payment
|
|
# asserts whether shipping and billing addresses are the same
|
|
ship_add_id = order.reload.ship_address_id
|
|
bill_add_id = order.reload.bill_address_id
|
|
expect(Spree::Address.where(id: bill_add_id).pluck(:address1) ==
|
|
Spree::Address.where(id: ship_add_id).pluck(:address1)).to be true
|
|
end
|
|
|
|
context "with a shipping fee" do
|
|
before do
|
|
proceed_to_payment
|
|
click_button "Next - Order summary"
|
|
end
|
|
|
|
shared_examples "displays the shipping fee" do |checkout_page|
|
|
it "on the #{checkout_page} page" do
|
|
within "#line-items" do
|
|
expect(page).to have_content("Shipping #{with_currency(4.56)}")
|
|
end
|
|
if checkout_page.eql?("order confirmation")
|
|
expect(page).to have_content "Your order has been processed successfully"
|
|
end
|
|
end
|
|
end
|
|
|
|
it_behaves_like "displays the shipping fee", "order summary"
|
|
|
|
context "after completing the order" do
|
|
before do
|
|
click_on "Complete order"
|
|
end
|
|
it_behaves_like "displays the shipping fee", "order confirmation"
|
|
end
|
|
end
|
|
end
|
|
|
|
context "with different shipping and billing address" do
|
|
before do
|
|
uncheck "ship_address_same_as_billing"
|
|
end
|
|
it "displays the shipping address form and the option to save it as default" do
|
|
expect(page).to have_field "order_ship_address_attributes_address1"
|
|
end
|
|
|
|
it "displays error messages when submitting incomplete billing address" do
|
|
click_button "Next - Payment method"
|
|
expect(page).to have_content "Saving failed, please update the highlighted fields."
|
|
expect(page).to have_field("Address", with: "")
|
|
expect(page).to have_field("City", with: "")
|
|
expect(page).to have_field("Postcode", with: "")
|
|
expect(page).to have_content("can't be blank", count: 3)
|
|
end
|
|
|
|
it "fills in shipping details and redirects the user to the Payment Method step,
|
|
when submiting the form" do
|
|
fill_out_shipping_address
|
|
fill_notes("SpEcIaL NoTeS")
|
|
proceed_to_payment
|
|
# asserts whether shipping and billing addresses are the same
|
|
ship_add_id = Spree::Order.first.ship_address_id
|
|
bill_add_id = Spree::Order.first.bill_address_id
|
|
expect(Spree::Address.where(id: bill_add_id).pluck(:address1) ==
|
|
Spree::Address.where(id: ship_add_id).pluck(:address1)).to be false
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "pre-selecting a shipping method" do
|
|
it "preselect a shipping method if only one is available" do
|
|
order.distributor.update! shipping_methods: [free_shipping, shipping_backoffice_only]
|
|
|
|
visit checkout_step_path(:details)
|
|
|
|
expect(page).to have_checked_field "shipping_method_#{free_shipping.id}"
|
|
end
|
|
|
|
it "don't preselect a shipping method if more than one is available" do
|
|
order.distributor.update! shipping_methods: [free_shipping, shipping_with_fee]
|
|
|
|
visit checkout_step_path(:details)
|
|
|
|
expect(page).to have_field "shipping_method_#{free_shipping.id}", checked: false
|
|
expect(page).to have_field "shipping_method_#{shipping_with_fee.id}", checked: false
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "not filling out delivery details" do
|
|
before do
|
|
fill_in "Email", with: ""
|
|
end
|
|
it "should display error when fields are empty" do
|
|
click_button "Next - Payment method"
|
|
expect(page).to have_content("Saving failed, please update the highlighted fields")
|
|
expect(page).to have_field("First Name", with: "")
|
|
expect(page).to have_field("Last Name", with: "")
|
|
expect(page).to have_field("Email", with: "")
|
|
expect(page).to have_content("is invalid")
|
|
expect(page).to have_field("Phone number", with: "")
|
|
expect(page).to have_field("Address", with: "")
|
|
expect(page).to have_field("City", with: "")
|
|
expect(page).to have_field("Postcode", with: "")
|
|
expect(page).to have_content("can't be blank", count: 7)
|
|
expect(page).to have_content("Select a shipping method")
|
|
end
|
|
end
|
|
|
|
context "with a saved address" do
|
|
let!(:address_state) do
|
|
create(:state, name: "Testville", abbr: "TST", country: DefaultCountry.country )
|
|
end
|
|
let(:saved_address) do
|
|
create(:bill_address, state: address_state, zipcode: "TST01" )
|
|
end
|
|
|
|
before do
|
|
user.update_columns bill_address_id: saved_address.id
|
|
end
|
|
|
|
it "pre-fills address details" do
|
|
visit checkout_path
|
|
expect(page).to have_select "order_bill_address_attributes_state_id", selected: "Testville"
|
|
expect(page).to have_field "order_bill_address_attributes_zipcode", with: "TST01"
|
|
end
|
|
end
|
|
end
|
|
|
|
context "payment step" do
|
|
let(:order) { create(:order_ready_for_payment, distributor: distributor) }
|
|
|
|
context "with one payment method, with a fee" do
|
|
before do
|
|
visit checkout_step_path(:payment)
|
|
end
|
|
it "preselect the payment method if only one is available" do
|
|
expect(page).to have_checked_field "payment_method_#{payment_with_fee.id}"
|
|
end
|
|
it "displays the transaction fee" do
|
|
expect(page).to have_content("#{payment_with_fee.name} " + "(#{with_currency(1.23)})")
|
|
end
|
|
end
|
|
|
|
context "with a transaction fee" do
|
|
before do
|
|
click_button "Next - Order summary"
|
|
end
|
|
|
|
shared_examples "displays the transaction fee" do |checkout_page|
|
|
it "on the #{checkout_page} page" do
|
|
within "#line-items" do
|
|
expect(page).to have_content("Transaction fee #{with_currency(1.23)}")
|
|
end
|
|
if checkout_page.eql?("order confirmation")
|
|
expect(page).to have_content "Your order has been processed successfully"
|
|
end
|
|
end
|
|
end
|
|
|
|
it_behaves_like "displays the transaction fee", "order summary"
|
|
|
|
context "after completing the order" do
|
|
before do
|
|
click_on "Complete order"
|
|
end
|
|
it_behaves_like "displays the transaction fee", "order confirmation"
|
|
end
|
|
end
|
|
|
|
context "with more than one payment method" do
|
|
let!(:payment_method) { create(:payment_method, distributors: [distributor]) }
|
|
|
|
before do
|
|
visit checkout_step_path(:payment)
|
|
end
|
|
|
|
it "don't preselect the payment method if more than one is available" do
|
|
expect(page).to have_field "payment_method_#{payment_with_fee.id}", checked: false
|
|
expect(page).to have_field "payment_method_#{payment_method.id}", checked: false
|
|
end
|
|
|
|
it "requires choosing a payment method" do
|
|
click_on "Next - Order summary"
|
|
expect(page).to have_content "Select a payment method"
|
|
end
|
|
end
|
|
|
|
describe "choosing" do
|
|
shared_examples "different payment methods" do |pay_method|
|
|
context "checking out with #{pay_method}", if: pay_method.eql?("Stripe SCA") == false do
|
|
before do
|
|
visit checkout_step_path(:payment)
|
|
end
|
|
|
|
it "proceeds to the summary step and completes the order" do
|
|
choose pay_method.to_s
|
|
proceed_to_summary
|
|
|
|
place_order
|
|
expect(page).to have_content "Paying via: #{pay_method}"
|
|
expect(order.reload.state).to eq "complete"
|
|
end
|
|
end
|
|
|
|
context "for Stripe SCA", if: pay_method.eql?("Stripe SCA") do
|
|
before do
|
|
setup_stripe
|
|
visit checkout_step_path(:payment)
|
|
end
|
|
|
|
it "selects Stripe SCA and proceeds to the summary step" do
|
|
choose pay_method.to_s
|
|
fill_out_card_details
|
|
click_on "Next - Order summary"
|
|
proceed_to_summary
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "shared examples" do
|
|
let!(:cash) { create(:payment_method, distributors: [distributor], name: "Cash") }
|
|
|
|
context "Cash" do
|
|
it_behaves_like "different payment methods", "Cash"
|
|
end
|
|
|
|
context "Paypal" do
|
|
let!(:paypal) do
|
|
Spree::Gateway::PayPalExpress.create!(
|
|
name: "Paypal",
|
|
environment: "test",
|
|
distributor_ids: [distributor.id]
|
|
)
|
|
end
|
|
|
|
before do
|
|
stub_paypal_response(
|
|
success: true,
|
|
redirect: payment_gateways_confirm_paypal_path(
|
|
payment_method_id: paypal.id, token: "t123", PayerID: 'p123'
|
|
)
|
|
)
|
|
stub_paypal_confirm
|
|
end
|
|
|
|
it_behaves_like "different payment methods", "Paypal"
|
|
end
|
|
|
|
context "Stripe SCA" do
|
|
let!(:stripe_account) { create(:stripe_account, enterprise: distributor) }
|
|
let!(:stripe_sca_payment_method) {
|
|
create(:stripe_sca_payment_method, distributors: [distributor], name: "Stripe SCA")
|
|
}
|
|
|
|
it_behaves_like "different payment methods", "Stripe SCA"
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "hiding a payment method with a default rule" do
|
|
let!(:tagged_customer) { create(:customer, user: user, enterprise: distributor) }
|
|
let!(:hidden_method) {
|
|
create(:payment_method, distributors: [distributor], name: "Hidden", tag_list: "hide_pm")
|
|
}
|
|
before do
|
|
create(:filter_payment_methods_tag_rule,
|
|
enterprise: distributor,
|
|
is_default: true,
|
|
preferred_payment_method_tags: "hide_pm",
|
|
preferred_matched_payment_methods_visibility: 'hidden')
|
|
visit checkout_step_path(:payment)
|
|
end
|
|
|
|
context "with no exceptions set to a customer" do
|
|
it "hides the payment method" do
|
|
expect(page).not_to have_content hidden_method.name
|
|
end
|
|
end
|
|
|
|
context "with an exception set to a customer" do
|
|
before do
|
|
create(:filter_payment_methods_tag_rule,
|
|
enterprise: distributor,
|
|
preferred_customer_tags: "show_pm",
|
|
preferred_payment_method_tags: "hide_pm",
|
|
preferred_matched_payment_methods_visibility: 'visible')
|
|
tagged_customer.update_attribute(:tag_list, "show_pm")
|
|
visit checkout_step_path(:payment)
|
|
end
|
|
|
|
it "displays the payment method" do
|
|
expect(page).to have_content hidden_method.name
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "summary step" do
|
|
let(:order) {
|
|
create(:order_ready_for_confirmation, distributor: distributor)
|
|
}
|
|
|
|
describe "completing the checkout" do
|
|
it "keeps the distributor selected for the current user after completion" do
|
|
visit checkout_step_path(:summary)
|
|
|
|
expect(page).to have_content "Shopping @ #{distributor.name}"
|
|
|
|
place_order
|
|
|
|
expect(page).to have_content "Back To Store"
|
|
expect(order.reload.state).to eq "complete"
|
|
|
|
expect(page).to have_content "Shopping @ #{distributor.name}"
|
|
end
|
|
end
|
|
|
|
describe "navigation available" do
|
|
it "redirect to Payment method step by clicking on 'Back to payment method' button" do
|
|
visit checkout_step_path(:summary)
|
|
|
|
click_on "Back to Payment method"
|
|
|
|
expect(page).to have_content "You can review and confirm your order in the next step which includes the final costs."
|
|
end
|
|
end
|
|
|
|
describe "terms and conditions" do
|
|
let(:system_terms_path) { Rails.root.join("public/Terms-of-service.pdf") }
|
|
let(:shop_terms_path) { Rails.root.join("public/Terms-of-ServiceUK.pdf") }
|
|
let(:system_terms) {
|
|
Rack::Test::UploadedFile.new(system_terms_path, "application/pdf")
|
|
}
|
|
let(:shop_terms) {
|
|
Rack::Test::UploadedFile.new(shop_terms_path, "application/pdf")
|
|
}
|
|
|
|
context "when none are required" do
|
|
it "doesn't show checkbox or links" do
|
|
visit checkout_step_path(:summary)
|
|
|
|
within "#checkout" do
|
|
expect(page).to_not have_field "order_accept_terms"
|
|
expect(page).to_not have_link "Terms and Conditions"
|
|
expect(page).to_not have_link "Terms of service"
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when distributor has T&Cs" do
|
|
before do
|
|
order.distributor.update!(terms_and_conditions: shop_terms)
|
|
end
|
|
|
|
describe "when customer has not accepted T&Cs before" do
|
|
it "shows a link to the T&Cs and disables checkout button until terms are accepted" do
|
|
visit checkout_step_path(:summary)
|
|
expect(page).to have_link "Terms and Conditions", href: /#{shop_terms_path.basename}$/
|
|
expect(page).to have_field "order_accept_terms", checked: false
|
|
end
|
|
end
|
|
|
|
describe "when customer has already accepted T&Cs before" do
|
|
before do
|
|
customer = create(:customer, enterprise: order.distributor, user: user)
|
|
customer.update terms_and_conditions_accepted_at: Time.zone.now
|
|
end
|
|
|
|
it "enables checkout button (because T&Cs are accepted by default)" do
|
|
visit checkout_step_path(:summary)
|
|
expect(page).to have_field "order_accept_terms", checked: true
|
|
end
|
|
|
|
describe "but afterwards the enterprise has uploaded a new T&Cs file" do
|
|
before { order.distributor.update!(terms_and_conditions: shop_terms) }
|
|
|
|
it "disables checkout button until terms are accepted" do
|
|
visit checkout_step_path(:summary)
|
|
expect(page).to have_field "order_accept_terms", checked: false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the platform's terms of service have to be accepted" do
|
|
let(:tos_url) { "https://example.org/tos" }
|
|
|
|
before do
|
|
allow(Spree::Config).to receive(:shoppers_require_tos).and_return(true)
|
|
allow(Spree::Config).to receive(:footer_tos_url).and_return(tos_url)
|
|
end
|
|
|
|
it "shows the terms which need to be accepted" do
|
|
visit checkout_step_path(:summary)
|
|
|
|
expect(page).to have_link "Terms of service", href: tos_url
|
|
expect(find_link("Terms of service")[:target]).to eq "_blank"
|
|
expect(page).to have_field "order_accept_terms", checked: false
|
|
end
|
|
|
|
context "when the terms have been accepted in the past" do
|
|
before do
|
|
TermsOfServiceFile.create!(
|
|
attachment: system_terms,
|
|
updated_at: 1.day.ago,
|
|
)
|
|
customer = create(:customer, enterprise: order.distributor, user: user)
|
|
customer.update(terms_and_conditions_accepted_at: Time.zone.now)
|
|
end
|
|
|
|
it "remembers the selection" do
|
|
visit checkout_step_path(:summary)
|
|
|
|
expect(page).to have_link "Terms of service"
|
|
expect(page).to have_field "order_accept_terms", checked: true
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the seller's terms and the platform's terms have to be accepted" do
|
|
let(:tos_url) { "https://example.org/tos" }
|
|
|
|
before do
|
|
order.distributor.update!(terms_and_conditions: shop_terms)
|
|
|
|
allow(Spree::Config).to receive(:shoppers_require_tos).and_return(true)
|
|
allow(Spree::Config).to receive(:footer_tos_url).and_return(tos_url)
|
|
end
|
|
|
|
it "shows links to both terms and all need accepting" do
|
|
visit checkout_step_path(:summary)
|
|
|
|
expect(page).to have_link "Terms and Conditions", href: /#{shop_terms_path.basename}$/
|
|
expect(page).to have_link "Terms of service", href: tos_url
|
|
expect(page).to have_field "order_accept_terms", checked: false
|
|
end
|
|
end
|
|
end
|
|
|
|
context "handle the navigation when the order is ready for confirmation" do
|
|
it "redirect to summary step" do
|
|
visit "/checkout"
|
|
|
|
expect(page).to have_current_path checkout_step_path(:summary)
|
|
end
|
|
|
|
it "handle the navigation between each step by clicking on tab or button to submit the form" do
|
|
visit checkout_step_path(:summary)
|
|
|
|
click_on "Your details"
|
|
|
|
expect(page).to have_current_path checkout_step_path(:details)
|
|
|
|
click_on "Next - Payment method"
|
|
|
|
expect(page).to have_current_path checkout_step_path(:payment)
|
|
end
|
|
end
|
|
|
|
describe "order state" do
|
|
before do
|
|
visit checkout_step_path(:summary)
|
|
end
|
|
|
|
it "emptying the cart changes the order state back to address" do
|
|
visit main_app.cart_path
|
|
expect {
|
|
find('#clear_cart_link').click
|
|
expect(page).to have_current_path enterprise_shop_path(distributor)
|
|
}.to change { order.reload.state }.from("confirmation").to("address")
|
|
end
|
|
end
|
|
end
|
|
|
|
context "with previous open orders" do
|
|
let(:order) {
|
|
create(:order_ready_for_confirmation, distributor: distributor,
|
|
order_cycle: order_cycle, user_id: user.id)
|
|
}
|
|
let!(:prev_order) {
|
|
create(:completed_order_with_totals,
|
|
order_cycle: order_cycle, distributor: distributor, user_id: order.user_id)
|
|
}
|
|
|
|
context "when distributor allows order changes" do
|
|
before do
|
|
order.distributor.allow_order_changes = true
|
|
order.distributor.save
|
|
visit checkout_step_path(:summary)
|
|
end
|
|
|
|
it "informs about previous orders" do
|
|
expect(page).to have_content("You have an order for this order cycle already.")
|
|
end
|
|
|
|
it "show a link to /cart#bought-products page" do
|
|
expect(page).to have_link("cart", href: "/cart#bought-products")
|
|
click_on "cart"
|
|
expect(page).to have_text "#{prev_order.line_items.length} additional items already confirmed for this order cycle"
|
|
end
|
|
end
|
|
|
|
it "don't display any message if distributor don't allow order changes" do
|
|
order.distributor.allow_order_changes = false
|
|
order.distributor.save
|
|
visit checkout_step_path(:summary)
|
|
|
|
expect(page).to_not have_content("You have an order for this order cycle already.")
|
|
end
|
|
end
|
|
end
|
|
end
|