Files
sure/test/models/provider_merchant_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

38 lines
1.4 KiB
Ruby

require "test_helper"
class ProviderMerchantTest < ActiveSupport::TestCase
include EntriesTestHelper
setup do
@family = families(:dylan_family)
@provider_merchant = ProviderMerchant.create!(name: "Acme Synced", source: "plaid")
end
# Regression: issue #1977. Converting a synced merchant to a family merchant
# reassigns merchant_id via update_all; the entries must be flagged so the
# next provider sync doesn't revert the conversion.
test "convert_to_family_merchant_for flags reassigned transactions as user_modified" do
entry = create_transaction(merchant: @provider_merchant)
assert_not entry.user_modified?
family_merchant = @provider_merchant.convert_to_family_merchant_for(@family)
entry.reload
assert_equal family_merchant.id, entry.entryable.merchant_id
assert entry.user_modified?, "converted transaction's entry must be flagged so provider sync won't revert it"
end
# Regression: issue #1977. Unlinking a synced merchant nulls merchant_id;
# without the flag the next sync re-links it.
test "unlink_from_family flags affected transactions as user_modified" do
entry = create_transaction(merchant: @provider_merchant)
assert_not entry.user_modified?
@provider_merchant.unlink_from_family(@family)
entry.reload
assert_nil entry.entryable.merchant_id
assert entry.user_modified?, "unlinked transaction's entry must be flagged so provider sync won't re-link it"
end
end