Files
sure/test/models/transaction_test.rb
Louis e96fb0c23f feat(enable-banking): enhance transaction import, metadata handling, and UI (#1406)
* feat(enable-banking): enhance transaction import, metadata handling, and UI

* fix(enable-banking): address security, sync edge cases and PR feedback

* fix(enable-banking): resolve silent failures, auth overrides, and sync logic bugs

* fix(enable-banking): resolve sync logic bugs, trailing whitespaces, and apply safe_psu_headers

* test(enable-banking): mock set_current_balance to return success result

* fix(budget): properly filter pending transactions and classify synced loan payments

* style: fix trailing whitespace detected by rubocop

* refactor: address code review feedback for Enable Banking sync and reporting

---------

Signed-off-by: Louis <contact@boul2gom.com>
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-04-10 23:19:48 +02:00

143 lines
4.7 KiB
Ruby

require "test_helper"
class TransactionTest < ActiveSupport::TestCase
test "pending? is true when extra.simplefin.pending is truthy" do
transaction = Transaction.new(extra: { "simplefin" => { "pending" => true } })
assert transaction.pending?
end
test "pending? is true when extra.plaid.pending is truthy" do
transaction = Transaction.new(extra: { "plaid" => { "pending" => "true" } })
assert transaction.pending?
end
test "pending? is true when extra.lunchflow.pending is truthy" do
transaction = Transaction.new(extra: { "lunchflow" => { "pending" => true } })
assert transaction.pending?
end
test "pending? is false when no provider pending metadata is present" do
transaction = Transaction.new(extra: { "plaid" => { "pending" => false } })
assert_not transaction.pending?
end
test "pending? returns true for enable_banking pending transactions" do
transaction = Transaction.new(extra: { "enable_banking" => { "pending" => true } })
assert transaction.pending?
end
test "pending? returns false for enable_banking non-pending transactions" do
transaction = Transaction.new(extra: { "enable_banking" => { "pending" => false } })
assert_not transaction.pending?
end
test "investment_contribution is a valid kind" do
transaction = Transaction.new(kind: "investment_contribution")
assert_equal "investment_contribution", transaction.kind
assert transaction.investment_contribution?
end
test "TRANSFER_KINDS constant matches transfer? method" do
Transaction::TRANSFER_KINDS.each do |kind|
assert Transaction.new(kind: kind).transfer?, "#{kind} should be a transfer kind"
end
non_transfer_kinds = Transaction.kinds.keys - Transaction::TRANSFER_KINDS
non_transfer_kinds.each do |kind|
assert_not Transaction.new(kind: kind).transfer?, "#{kind} should NOT be a transfer kind"
end
end
test "all transaction kinds are valid" do
valid_kinds = %w[standard funds_movement cc_payment loan_payment one_time investment_contribution]
valid_kinds.each do |kind|
transaction = Transaction.new(kind: kind)
assert_equal kind, transaction.kind, "#{kind} should be a valid transaction kind"
end
end
test "ACTIVITY_LABELS contains all valid labels" do
assert_includes Transaction::ACTIVITY_LABELS, "Buy"
assert_includes Transaction::ACTIVITY_LABELS, "Sell"
assert_includes Transaction::ACTIVITY_LABELS, "Sweep In"
assert_includes Transaction::ACTIVITY_LABELS, "Sweep Out"
assert_includes Transaction::ACTIVITY_LABELS, "Dividend"
assert_includes Transaction::ACTIVITY_LABELS, "Reinvestment"
assert_includes Transaction::ACTIVITY_LABELS, "Interest"
assert_includes Transaction::ACTIVITY_LABELS, "Fee"
assert_includes Transaction::ACTIVITY_LABELS, "Transfer"
assert_includes Transaction::ACTIVITY_LABELS, "Contribution"
assert_includes Transaction::ACTIVITY_LABELS, "Withdrawal"
assert_includes Transaction::ACTIVITY_LABELS, "Exchange"
assert_includes Transaction::ACTIVITY_LABELS, "Other"
end
test "exchange_rate getter returns nil when extra is nil" do
transaction = Transaction.new
assert_nil transaction.exchange_rate
end
test "exchange_rate setter stores normalized numeric value" do
transaction = Transaction.new
transaction.exchange_rate = "1.5"
assert_equal 1.5, transaction.exchange_rate
end
test "exchange_rate setter marks invalid input" do
transaction = Transaction.new
transaction.exchange_rate = "not a number"
assert_equal "not a number", transaction.extra["exchange_rate"]
assert transaction.extra["exchange_rate_invalid"]
end
test "exchange_rate validation rejects non-numeric input" do
transaction = Transaction.new(
category: categories(:income),
extra: { "exchange_rate" => "invalid" }
)
transaction.exchange_rate = "not a number"
assert_not transaction.valid?
assert_includes transaction.errors[:exchange_rate], "must be a number"
end
test "exchange_rate validation rejects zero values" do
transaction = Transaction.new(
category: categories(:income)
)
transaction.exchange_rate = 0
assert_not transaction.valid?
assert_includes transaction.errors[:exchange_rate], "must be greater than 0"
end
test "exchange_rate validation rejects negative values" do
transaction = Transaction.new(
category: categories(:income)
)
transaction.exchange_rate = -1.5
assert_not transaction.valid?
assert_includes transaction.errors[:exchange_rate], "must be greater than 0"
end
test "exchange_rate validation allows positive values" do
transaction = Transaction.new(
category: categories(:income)
)
transaction.exchange_rate = 1.5
assert transaction.valid?
end
end