Merge pull request #13197 from dacook/reload-payments-12693

Fix obscure issue when choosing payment method in checkout
This commit is contained in:
Filipe
2025-03-18 12:04:33 +00:00
committed by GitHub
3 changed files with 52 additions and 2 deletions

View File

@@ -92,7 +92,10 @@ module Orders
# Verifies if the in-memory payment state is different from the one stored in the database
# This is be done without reloading the payment so that in-memory data is not changed
def different_from_db_payment_state?(in_memory_payment_state, payment_id)
in_memory_payment_state != Spree::Payment.find(payment_id).state
# Re-load payment from the DB (unless it was cleared by clear_invalid_payments)
db_payment = Spree::Payment.find_by(id: payment_id)
db_payment.present? && in_memory_payment_state != db_payment.state
end
end
end

View File

@@ -1,4 +1,5 @@
.flex
-# Prevent Turbo pre-fetch which changes cart state
.flex{'data-turbo-prefetch': "false"}
.columns.three.text-center.checkout-tab{"class": [("selected" if checkout_step?(:details)), ("success" unless checkout_step?(:details))]}
%div
%span.checkout-tab-number

View File

@@ -328,6 +328,52 @@ RSpec.describe CheckoutController, type: :controller do
expect_cable_ready_redirect(response)
end
end
context "with existing invalid payments" do
let(:invalid_payments) {
[
create(:payment, state: :failed),
create(:payment, state: :void),
]
}
before do
order.payments = invalid_payments
end
it "deletes invalid payments" do
expect{
put(:update, params:)
}.to change { order.payments.to_a }.from(invalid_payments)
end
end
context "with different payment method previously chosen" do
let(:other_payment_method) { build(:payment_method, distributors: [distributor]) }
let(:other_payment) {
build(:payment, amount: order.total, payment_method: other_payment_method)
}
before do
order.payments = [other_payment]
end
context "and order is in an earlier state" do
# This revealed obscure bug #12693. If you progress to order summary, go back to payment
# method, then open delivery details in a new tab (or hover over the link with Turbo
# enabled), then submit new payment details, this happens.
before do
order.back_to_address
end
it "deletes invalid (old) payments" do
put(:update, params:)
order.payments.reload
expect(order.payments).not_to include other_payment
end
end
end
end
context "with no payment source" do