Files
sure/test/models/merchant/merger_test.rb
dripsmvcp ea316b4277 fix(merchants): preserve manual merchant edits across provider sync (#1981)
* fix(merchants): preserve manual merchant edits across provider sync

Fixes #1977.

Merging merchants, converting a synced (provider) merchant to a family
merchant, and unlinking a merchant all reassign transactions.merchant_id
via update_all without flagging the entries as user_modified. The next
provider sync sees the entries as unmodified and reverts the change.

Add Entry.mark_user_modified_for_transactions! and call it (before the
merchant_id update, so the scope still matches) in Merchant::Merger#merge!,
ProviderMerchant#convert_to_family_merchant_for, and #unlink_from_family.
The sync skip-guard already honours user_modified, so flagged entries are
left untouched on subsequent syncs.

* fix(merchants): pass transaction relation to bulk user_modified helper

Addresses PR #1981 review (CodeRabbit): mark_user_modified_for_transactions! now accepts an ActiveRecord::Relation and selects ids via subquery, so large merges/unlinks don't materialize ids or hit SQL parameter limits. Array of ids still supported. Callers pass the scope relation directly.
2026-05-30 23:27:18 +02:00

36 lines
1.3 KiB
Ruby

require "test_helper"
class Merchant::MergerTest < ActiveSupport::TestCase
include EntriesTestHelper
setup do
@family = families(:dylan_family)
@target = merchants(:netflix)
@source = merchants(:amazon)
end
# Regression: issue #1977. Merging merchants reassigns merchant_id via
# update_all; without flagging the entries as user_modified, the next
# provider sync reverts the merge.
test "merge! flags reassigned transactions as user_modified" do
entry = create_transaction(merchant: @source)
assert_not entry.user_modified?
Merchant::Merger.new(family: @family, target_merchant: @target, source_merchants: [ @source ]).merge!
entry.reload
assert_equal @target.id, entry.entryable.merchant_id, "transaction is reassigned to the target merchant"
assert entry.user_modified?, "merged transaction's entry must be flagged so provider sync won't revert it"
end
test "merge! does not touch entries of unrelated merchants" do
other = create_transaction(merchant: @target)
assert_not other.user_modified?
Merchant::Merger.new(family: @family, target_merchant: @target, source_merchants: [ @source ]).merge!
other.reload
assert_not other.user_modified?, "transactions already on the target are untouched"
end
end