test(recurring): prove export roundtrip semantics (#1727)

* test(recurring): prove export roundtrip semantics

* test(recurring): assert export roundtrip payload
This commit is contained in:
ghost
2026-05-11 15:02:15 -07:00
committed by GitHub
parent 1fedc43f68
commit 9e6fbc1374

View File

@@ -313,6 +313,85 @@ class Family::DataImporterTest < ActiveSupport::TestCase
assert_equal(-89.99, recurring_transaction.expected_amount_avg.to_f)
end
test "round trips recurring transaction export semantics" do
source_family = Family.create!(name: "Recurring Source", currency: "USD")
source_account = source_family.accounts.create!(
name: "Source Checking",
accountable: Depository.new,
balance: 1000,
currency: "USD"
)
source_merchant = source_family.merchants.create!(name: "Internet Provider")
source_family.recurring_transactions.create!(
account: source_account,
merchant: source_merchant,
amount: -89.99,
currency: "USD",
expected_day_of_month: 14,
last_occurrence_date: Date.parse("2024-01-14"),
next_expected_date: Date.parse("2024-02-14"),
status: "active",
occurrence_count: 6,
manual: true,
expected_amount_min: -95,
expected_amount_max: -85,
expected_amount_avg: -89.99
)
source_family.recurring_transactions.create!(
name: "Quarterly Insurance",
amount: 240,
currency: "USD",
expected_day_of_month: 28,
last_occurrence_date: Date.parse("2024-01-28"),
next_expected_date: Date.parse("2024-04-28"),
status: "inactive",
occurrence_count: 2,
manual: false
)
ndjson = nil
Zip::File.open_buffer(Family::DataExporter.new(source_family).generate_export) do |zip|
ndjson = zip.read("all.ndjson")
end
assert_not_nil ndjson
assert ndjson.include?('"type":"RecurringTransaction"')
Family::DataImporter.new(@family, ndjson).import!
assert_equal 2, @family.recurring_transactions.count
restored_account = @family.accounts.find_by!(name: "Source Checking")
restored_merchant = @family.merchants.find_by!(name: "Internet Provider")
restored_provider = @family.recurring_transactions.find_by!(merchant: restored_merchant)
assert_equal restored_account, restored_provider.account
assert_equal(-89.99, restored_provider.amount.to_f)
assert_equal "USD", restored_provider.currency
assert_equal 14, restored_provider.expected_day_of_month
assert_equal Date.parse("2024-01-14"), restored_provider.last_occurrence_date
assert_equal Date.parse("2024-02-14"), restored_provider.next_expected_date
assert_equal "active", restored_provider.status
assert_equal 6, restored_provider.occurrence_count
assert_equal true, restored_provider.manual
assert_equal(-95.0, restored_provider.expected_amount_min.to_f)
assert_equal(-85.0, restored_provider.expected_amount_max.to_f)
assert_equal(-89.99, restored_provider.expected_amount_avg.to_f)
restored_named = @family.recurring_transactions.find_by!(name: "Quarterly Insurance")
assert_nil restored_named.account
assert_nil restored_named.merchant
assert_equal 240.0, restored_named.amount.to_f
assert_equal 28, restored_named.expected_day_of_month
assert_equal Date.parse("2024-01-28"), restored_named.last_occurrence_date
assert_equal Date.parse("2024-04-28"), restored_named.next_expected_date
assert_equal "inactive", restored_named.status
assert_equal 2, restored_named.occurrence_count
assert_equal false, restored_named.manual
end
test "imports recurring transactions with unknown status fallback" do
ndjson = build_ndjson([
{