mirror of
https://github.com/we-promise/sure.git
synced 2026-06-01 08:49:01 +00:00
fix(enable_banking): clear stuck pending flag when ASPSP reuses same transaction_id (#1982)
* fix(enable_banking): clear stuck pending flag when ASPSP reuses same transaction_id for booked version * fix: scope pending→booked bypass to user_modified entries only * refactor: extract clear_pending_flags_from_extra helper to deduplicate pending-flag removal logic * refactor: use clear_pending_flags_from_extra in user_modified bypass path * fix(provider_import_adapter): add type check in clear_pending_flags_from_extra Add a check to ensure that the value associated with a provider key in the `extra` hash is a Hash before attempting to call `delete` on it. This prevents a `NoMethodError` when encountering malformed data where the provider key exists but does not map to a Hash. * fix(provider_import_adapter): fix indentation and ensure proper return in clear_pending_flags_from_extra * fix(provider_import_adapter): make clear_pending_flags_from_extra private * fix: guard clear_pending_flags_from_extra against non-Hash extra values
This commit is contained in:
committed by
Juan José Mata
parent
77590d7cdf
commit
1bc227ea44
@@ -1445,4 +1445,77 @@ class Account::ProviderImportAdapterTest < ActiveSupport::TestCase
|
||||
pending1.reload
|
||||
assert_equal "plaid_pending_1", pending1.external_id
|
||||
end
|
||||
|
||||
# =========================================================================
|
||||
# Same-external-id pending → booked (e.g. Revolut Italy via Enable Banking)
|
||||
# Some ASPSPs reuse the same transaction_id for pending and booked, so the
|
||||
# entry is found by find_or_initialize_by (persisted), bypassing auto-claim.
|
||||
# =========================================================================
|
||||
|
||||
test "clears pending flag when same external_id is reused for booked version (not user-modified)" do
|
||||
pending_entry = @adapter.import_transaction(
|
||||
external_id: "eb_same_id_123",
|
||||
amount: 30.0,
|
||||
currency: "EUR",
|
||||
date: Date.today - 2.days,
|
||||
name: "Piero Fiorista",
|
||||
source: "enable_banking",
|
||||
extra: { "enable_banking" => { "pending" => true } }
|
||||
)
|
||||
assert pending_entry.transaction.pending?, "entry should start as pending"
|
||||
|
||||
# Booked version arrives with the SAME external_id (Revolut Italy behaviour).
|
||||
# extra is nil (no FX, no MCC) so the deep-merge block would normally be skipped.
|
||||
assert_no_difference "@account.entries.count" do
|
||||
booked_entry = @adapter.import_transaction(
|
||||
external_id: "eb_same_id_123",
|
||||
amount: 30.0,
|
||||
currency: "EUR",
|
||||
date: Date.today,
|
||||
name: "Piero Fiorista",
|
||||
source: "enable_banking",
|
||||
extra: nil
|
||||
)
|
||||
|
||||
assert_equal pending_entry.id, booked_entry.id, "should update the same entry"
|
||||
assert_not booked_entry.transaction.pending?,
|
||||
"pending flag should be cleared even when extra is nil"
|
||||
end
|
||||
end
|
||||
|
||||
test "clears pending flag when same external_id reused and entry is user-modified (Revolut Italy)" do
|
||||
pending_entry = @adapter.import_transaction(
|
||||
external_id: "eb_same_id_user_mod",
|
||||
amount: 50.0,
|
||||
currency: "EUR",
|
||||
date: Date.today - 3.days,
|
||||
name: "Clean Center",
|
||||
source: "enable_banking",
|
||||
extra: { "enable_banking" => { "pending" => true } }
|
||||
)
|
||||
assert pending_entry.transaction.pending?, "entry should start as pending"
|
||||
|
||||
# User categorises the pending entry — sets user_modified = true
|
||||
pending_entry.mark_user_modified!
|
||||
assert pending_entry.reload.user_modified?, "entry should be marked user-modified"
|
||||
|
||||
# Booked version with the same external_id arrives — protection check would normally
|
||||
# return early and leave the pending badge intact.
|
||||
assert_no_difference "@account.entries.count" do
|
||||
booked_entry = @adapter.import_transaction(
|
||||
external_id: "eb_same_id_user_mod",
|
||||
amount: 50.0,
|
||||
currency: "EUR",
|
||||
date: Date.today,
|
||||
name: "Clean Center",
|
||||
source: "enable_banking",
|
||||
extra: nil
|
||||
)
|
||||
|
||||
assert_equal pending_entry.id, booked_entry.id, "should reference the same entry"
|
||||
booked_entry.reload
|
||||
assert_not booked_entry.transaction.pending?,
|
||||
"pending flag must be cleared even for user-modified entries"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user