1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-02 03:55:20 +02:00

Account:: namespace simplifications and cleanup (#2110)

* Flatten Holding model

* Flatten balance model

* Entries domain renames

* Fix valuations reference

* Fix trades stream

* Fix brakeman warnings

* Fix tests

* Replace existing entryable type references in DB
This commit is contained in:
Zach Gollwitzer 2025-04-14 11:40:34 -04:00 committed by GitHub
parent f181ba941f
commit e657c40d19
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
172 changed files with 1297 additions and 1258 deletions

View file

@ -1,119 +0,0 @@
require "test_helper"
class Account::TransactionsControllerTest < ActionDispatch::IntegrationTest
include EntryableResourceInterfaceTest
setup do
sign_in @user = users(:family_admin)
@entry = account_entries(:transaction)
end
test "creates with transaction details" do
assert_difference [ "Account::Entry.count", "Account::Transaction.count" ], 1 do
post account_transactions_url, params: {
account_entry: {
account_id: @entry.account_id,
name: "New transaction",
date: Date.current,
currency: "USD",
amount: 100,
nature: "inflow",
entryable_attributes: {
tag_ids: [ Tag.first.id, Tag.second.id ],
category_id: Category.first.id,
merchant_id: Merchant.first.id
}
}
}
end
created_entry = Account::Entry.order(:created_at).last
assert_redirected_to account_url(created_entry.account)
assert_equal "Entry created", flash[:notice]
assert_enqueued_with(job: SyncJob)
end
test "updates with transaction details" do
assert_no_difference [ "Account::Entry.count", "Account::Transaction.count" ] do
patch account_transaction_url(@entry), params: {
account_entry: {
name: "Updated name",
date: Date.current,
currency: "USD",
amount: 100,
nature: "inflow",
entryable_type: @entry.entryable_type,
notes: "test notes",
excluded: false,
entryable_attributes: {
id: @entry.entryable_id,
tag_ids: [ Tag.first.id, Tag.second.id ],
category_id: Category.first.id,
merchant_id: Merchant.first.id
}
}
}
end
@entry.reload
assert_equal "Updated name", @entry.name
assert_equal Date.current, @entry.date
assert_equal "USD", @entry.currency
assert_equal -100, @entry.amount
assert_equal [ Tag.first.id, Tag.second.id ], @entry.entryable.tag_ids.sort
assert_equal Category.first.id, @entry.entryable.category_id
assert_equal Merchant.first.id, @entry.entryable.merchant_id
assert_equal "test notes", @entry.notes
assert_equal false, @entry.excluded
assert_equal "Entry updated", flash[:notice]
assert_redirected_to account_url(@entry.account)
assert_enqueued_with(job: SyncJob)
end
test "can destroy many transactions at once" do
transactions = @user.family.entries.account_transactions
delete_count = transactions.size
assert_difference([ "Account::Transaction.count", "Account::Entry.count" ], -delete_count) do
post bulk_delete_account_transactions_url, params: {
bulk_delete: {
entry_ids: transactions.pluck(:id)
}
}
end
assert_redirected_to transactions_url
assert_equal "#{delete_count} transactions deleted", flash[:notice]
end
test "can update many transactions at once" do
transactions = @user.family.entries.account_transactions
assert_difference [ "Account::Entry.count", "Account::Transaction.count" ], 0 do
post bulk_update_account_transactions_url, params: {
bulk_update: {
entry_ids: transactions.map(&:id),
date: 1.day.ago.to_date,
category_id: Category.second.id,
merchant_id: Merchant.second.id,
tag_ids: [ Tag.first.id, Tag.second.id ],
notes: "Updated note"
}
}
end
assert_redirected_to transactions_url
assert_equal "#{transactions.count} transactions updated", flash[:notice]
transactions.reload.each do |transaction|
assert_equal 1.day.ago.to_date, transaction.date
assert_equal Category.second, transaction.account_transaction.category
assert_equal Merchant.second, transaction.account_transaction.merchant
assert_equal "Updated note", transaction.notes
assert_equal [ Tag.first.id, Tag.second.id ], transaction.entryable.tag_ids.sort
end
end
end

View file

@ -3,7 +3,7 @@ require "test_helper"
class CategoriesControllerTest < ActionDispatch::IntegrationTest
setup do
sign_in users(:family_admin)
@transaction = account_transactions :one
@transaction = transactions :one
end
test "index" do

View file

@ -30,7 +30,7 @@ class Category::DeletionsControllerTest < ActionDispatch::IntegrationTest
assert_not_empty @category.transactions
assert_difference "Category.count", -1 do
assert_difference "Account::Transaction.where(category: nil).count", @category.transactions.count do
assert_difference "Transaction.where(category: nil).count", @category.transactions.count do
post category_deletions_url(@category)
end
end

View file

@ -11,8 +11,8 @@ class CreditCardsControllerTest < ActionDispatch::IntegrationTest
test "creates with credit card details" do
assert_difference -> { Account.count } => 1,
-> { CreditCard.count } => 1,
-> { Account::Valuation.count } => 2,
-> { Account::Entry.count } => 2 do
-> { Valuation.count } => 2,
-> { Entry.count } => 2 do
post credit_cards_path, params: {
account: {
name: "New Credit Card",

View file

@ -1,6 +1,6 @@
require "test_helper"
class Account::HoldingsControllerTest < ActionDispatch::IntegrationTest
class HoldingsControllerTest < ActionDispatch::IntegrationTest
setup do
sign_in users(:family_admin)
@account = accounts(:investment)
@ -8,20 +8,20 @@ class Account::HoldingsControllerTest < ActionDispatch::IntegrationTest
end
test "gets holdings" do
get account_holdings_url(account_id: @account.id)
get holdings_url(account_id: @account.id)
assert_response :success
end
test "gets holding" do
get account_holding_path(@holding)
get holding_path(@holding)
assert_response :success
end
test "destroys holding and associated entries" do
assert_difference -> { Account::Holding.count } => -1,
-> { Account::Entry.count } => -1 do
delete account_holding_path(@holding)
assert_difference -> { Holding.count } => -1,
-> { Entry.count } => -1 do
delete holding_path(@holding)
end
assert_redirected_to account_path(@holding.account)

View file

@ -11,8 +11,8 @@ class LoansControllerTest < ActionDispatch::IntegrationTest
test "creates with loan details" do
assert_difference -> { Account.count } => 1,
-> { Loan.count } => 1,
-> { Account::Valuation.count } => 2,
-> { Account::Entry.count } => 2 do
-> { Valuation.count } => 2,
-> { Entry.count } => 2 do
post loans_path, params: {
account: {
name: "New Loan",

View file

@ -11,8 +11,8 @@ class PropertiesControllerTest < ActionDispatch::IntegrationTest
test "creates with property details" do
assert_difference -> { Account.count } => 1,
-> { Property.count } => 1,
-> { Account::Valuation.count } => 2,
-> { Account::Entry.count } => 2 do
-> { Valuation.count } => 2,
-> { Entry.count } => 2 do
post properties_path, params: {
account: {
name: "Property",

View file

@ -64,8 +64,8 @@ class Settings::HostingsControllerTest < ActionDispatch::IntegrationTest
assert_not ExchangeRate.exists?(exchange_rate.id)
assert_not Security::Price.exists?(security_price.id)
assert_not Account::Holding.exists?(holding.id)
assert_not Account::Balance.exists?(account_balance.id)
assert_not Holding.exists?(holding.id)
assert_not Balance.exists?(account_balance.id)
end
test "can clear data only when admin" do

View file

@ -1,17 +1,17 @@
require "test_helper"
class Account::TradesControllerTest < ActionDispatch::IntegrationTest
class TradesControllerTest < ActionDispatch::IntegrationTest
include EntryableResourceInterfaceTest
setup do
sign_in @user = users(:family_admin)
@entry = account_entries(:trade)
@entry = entries(:trade)
end
test "updates trade entry" do
assert_no_difference [ "Account::Entry.count", "Account::Trade.count" ] do
patch account_trade_url(@entry), params: {
account_entry: {
assert_no_difference [ "Entry.count", "Trade.count" ] do
patch trade_url(@entry), params: {
entry: {
currency: "USD",
entryable_attributes: {
id: @entry.entryable_id,
@ -26,8 +26,8 @@ class Account::TradesControllerTest < ActionDispatch::IntegrationTest
assert_enqueued_with job: SyncJob
assert_equal 20, @entry.account_trade.qty
assert_equal 20, @entry.account_trade.price
assert_equal 20, @entry.trade.qty
assert_equal 20, @entry.trade.price
assert_equal "USD", @entry.currency
assert_redirected_to account_url(@entry.account)
@ -36,11 +36,11 @@ class Account::TradesControllerTest < ActionDispatch::IntegrationTest
test "creates deposit entry" do
from_account = accounts(:depository) # Account the deposit is coming from
assert_difference -> { Account::Entry.count } => 2,
-> { Account::Transaction.count } => 2,
assert_difference -> { Entry.count } => 2,
-> { Transaction.count } => 2,
-> { Transfer.count } => 1 do
post account_trades_url, params: {
account_entry: {
post trades_url, params: {
entry: {
account_id: @entry.account_id,
type: "deposit",
date: Date.current,
@ -57,11 +57,11 @@ class Account::TradesControllerTest < ActionDispatch::IntegrationTest
test "creates withdrawal entry" do
to_account = accounts(:depository) # Account the withdrawal is going to
assert_difference -> { Account::Entry.count } => 2,
-> { Account::Transaction.count } => 2,
assert_difference -> { Entry.count } => 2,
-> { Transaction.count } => 2,
-> { Transfer.count } => 1 do
post account_trades_url, params: {
account_entry: {
post trades_url, params: {
entry: {
account_id: @entry.account_id,
type: "withdrawal",
date: Date.current,
@ -76,11 +76,11 @@ class Account::TradesControllerTest < ActionDispatch::IntegrationTest
end
test "deposit and withdrawal has optional transfer account" do
assert_difference -> { Account::Entry.count } => 1,
-> { Account::Transaction.count } => 1,
assert_difference -> { Entry.count } => 1,
-> { Transaction.count } => 1,
-> { Transfer.count } => 0 do
post account_trades_url, params: {
account_entry: {
post trades_url, params: {
entry: {
account_id: @entry.account_id,
type: "withdrawal",
date: Date.current,
@ -90,16 +90,16 @@ class Account::TradesControllerTest < ActionDispatch::IntegrationTest
}
end
created_entry = Account::Entry.order(created_at: :desc).first
created_entry = Entry.order(created_at: :desc).first
assert created_entry.amount.positive?
assert_redirected_to @entry.account
end
test "creates interest entry" do
assert_difference [ "Account::Entry.count", "Account::Transaction.count" ], 1 do
post account_trades_url, params: {
account_entry: {
assert_difference [ "Entry.count", "Transaction.count" ], 1 do
post trades_url, params: {
entry: {
account_id: @entry.account_id,
type: "interest",
date: Date.current,
@ -109,16 +109,16 @@ class Account::TradesControllerTest < ActionDispatch::IntegrationTest
}
end
created_entry = Account::Entry.order(created_at: :desc).first
created_entry = Entry.order(created_at: :desc).first
assert created_entry.amount.negative?
assert_redirected_to @entry.account
end
test "creates trade buy entry" do
assert_difference [ "Account::Entry.count", "Account::Trade.count", "Security.count" ], 1 do
post account_trades_url, params: {
account_entry: {
assert_difference [ "Entry.count", "Trade.count", "Security.count" ], 1 do
post trades_url, params: {
entry: {
account_id: @entry.account_id,
type: "buy",
date: Date.current,
@ -130,19 +130,19 @@ class Account::TradesControllerTest < ActionDispatch::IntegrationTest
}
end
created_entry = Account::Entry.order(created_at: :desc).first
created_entry = Entry.order(created_at: :desc).first
assert created_entry.amount.positive?
assert created_entry.account_trade.qty.positive?
assert created_entry.trade.qty.positive?
assert_equal "Entry created", flash[:notice]
assert_enqueued_with job: SyncJob
assert_redirected_to account_url(created_entry.account)
end
test "creates trade sell entry" do
assert_difference [ "Account::Entry.count", "Account::Trade.count" ], 1 do
post account_trades_url, params: {
account_entry: {
assert_difference [ "Entry.count", "Trade.count" ], 1 do
post trades_url, params: {
entry: {
account_id: @entry.account_id,
type: "sell",
ticker: "AAPL (NYSE)",
@ -154,10 +154,10 @@ class Account::TradesControllerTest < ActionDispatch::IntegrationTest
}
end
created_entry = Account::Entry.order(created_at: :desc).first
created_entry = Entry.order(created_at: :desc).first
assert created_entry.amount.negative?
assert created_entry.account_trade.qty.negative?
assert created_entry.trade.qty.negative?
assert_equal "Entry created", flash[:notice]
assert_enqueued_with job: SyncJob
assert_redirected_to account_url(created_entry.account)

View file

@ -0,0 +1,24 @@
require "test_helper"
class Transactions::BulkDeletionsControllerTest < ActionDispatch::IntegrationTest
setup do
sign_in @user = users(:family_admin)
@entry = entries(:transaction)
end
test "bulk delete" do
transactions = @user.family.entries.transactions
delete_count = transactions.size
assert_difference([ "Transaction.count", "Entry.count" ], -delete_count) do
post transactions_bulk_deletion_url, params: {
bulk_delete: {
entry_ids: transactions.pluck(:id)
}
}
end
assert_redirected_to transactions_url
assert_equal "#{delete_count} transactions deleted", flash[:notice]
end
end

View file

@ -0,0 +1,35 @@
require "test_helper"
class Transactions::BulkUpdatesControllerTest < ActionDispatch::IntegrationTest
setup do
sign_in @user = users(:family_admin)
end
test "bulk update" do
transactions = @user.family.entries.transactions
assert_difference [ "Entry.count", "Transaction.count" ], 0 do
post transactions_bulk_update_url, params: {
bulk_update: {
entry_ids: transactions.map(&:id),
date: 1.day.ago.to_date,
category_id: Category.second.id,
merchant_id: Merchant.second.id,
tag_ids: [ Tag.first.id, Tag.second.id ],
notes: "Updated note"
}
}
end
assert_redirected_to transactions_url
assert_equal "#{transactions.count} transactions updated", flash[:notice]
transactions.reload.each do |transaction|
assert_equal 1.day.ago.to_date, transaction.date
assert_equal Category.second, transaction.transaction.category
assert_equal Merchant.second, transaction.transaction.merchant
assert_equal "Updated note", transaction.notes
assert_equal [ Tag.first.id, Tag.second.id ], transaction.entryable.tag_ids.sort
end
end
end

View file

@ -1,11 +1,77 @@
require "test_helper"
class TransactionsControllerTest < ActionDispatch::IntegrationTest
include Account::EntriesTestHelper
include EntryableResourceInterfaceTest, EntriesTestHelper
setup do
sign_in @user = users(:family_admin)
@transaction = account_entries(:transaction)
@entry = entries(:transaction)
end
test "creates with transaction details" do
assert_difference [ "Entry.count", "Transaction.count" ], 1 do
post transactions_url, params: {
entry: {
account_id: @entry.account_id,
name: "New transaction",
date: Date.current,
currency: "USD",
amount: 100,
nature: "inflow",
entryable_type: @entry.entryable_type,
entryable_attributes: {
tag_ids: [ Tag.first.id, Tag.second.id ],
category_id: Category.first.id,
merchant_id: Merchant.first.id
}
}
}
end
created_entry = Entry.order(:created_at).last
assert_redirected_to account_url(created_entry.account)
assert_equal "Transaction created", flash[:notice]
assert_enqueued_with(job: SyncJob)
end
test "updates with transaction details" do
assert_no_difference [ "Entry.count", "Transaction.count" ] do
patch transaction_url(@entry), params: {
entry: {
name: "Updated name",
date: Date.current,
currency: "USD",
amount: 100,
nature: "inflow",
entryable_type: @entry.entryable_type,
notes: "test notes",
excluded: false,
entryable_attributes: {
id: @entry.entryable_id,
tag_ids: [ Tag.first.id, Tag.second.id ],
category_id: Category.first.id,
merchant_id: Merchant.first.id
}
}
}
end
@entry.reload
assert_equal "Updated name", @entry.name
assert_equal Date.current, @entry.date
assert_equal "USD", @entry.currency
assert_equal -100, @entry.amount
assert_equal [ Tag.first.id, Tag.second.id ], @entry.entryable.tag_ids.sort
assert_equal Category.first.id, @entry.entryable.category_id
assert_equal Merchant.first.id, @entry.entryable.merchant_id
assert_equal "test notes", @entry.notes
assert_equal false, @entry.excluded
assert_equal "Transaction updated", flash[:notice]
assert_redirected_to account_url(@entry.account)
assert_enqueued_with(job: SyncJob)
end
test "transaction count represents filtered total" do
@ -19,7 +85,7 @@ class TransactionsControllerTest < ActionDispatch::IntegrationTest
get transactions_url(per_page: 10)
assert_dom "#total-transactions", count: 1, text: family.entries.account_transactions.size.to_s
assert_dom "#total-transactions", count: 1, text: family.entries.transactions.size.to_s
searchable_transaction = create_transaction(account: account, name: "Unique test name")
@ -39,7 +105,7 @@ class TransactionsControllerTest < ActionDispatch::IntegrationTest
create_transaction(account: account)
end
sorted_transactions = family.entries.account_transactions.reverse_chronological.to_a
sorted_transactions = family.entries.transactions.reverse_chronological.to_a
assert_equal 11, sorted_transactions.count

View file

@ -1,7 +1,7 @@
require "test_helper"
class Account::TransferMatchesControllerTest < ActionDispatch::IntegrationTest
include Account::EntriesTestHelper
class TransferMatchesControllerTest < ActionDispatch::IntegrationTest
include EntriesTestHelper
setup do
sign_in @user = users(:family_admin)
@ -12,7 +12,7 @@ class Account::TransferMatchesControllerTest < ActionDispatch::IntegrationTest
outflow_transaction = create_transaction(amount: -100, account: accounts(:investment))
assert_difference "Transfer.count", 1 do
post account_transaction_transfer_match_path(inflow_transaction), params: {
post transaction_transfer_match_path(inflow_transaction), params: {
transfer_match: {
method: "existing",
matched_entry_id: outflow_transaction.id
@ -27,8 +27,8 @@ class Account::TransferMatchesControllerTest < ActionDispatch::IntegrationTest
test "creates transfer for target account" do
inflow_transaction = create_transaction(amount: 100, account: accounts(:depository))
assert_difference [ "Transfer.count", "Account::Entry.count", "Account::Transaction.count" ], 1 do
post account_transaction_transfer_match_path(inflow_transaction), params: {
assert_difference [ "Transfer.count", "Entry.count", "Transaction.count" ], 1 do
post transaction_transfer_match_path(inflow_transaction), params: {
transfer_match: {
method: "new",
target_account_id: accounts(:investment).id

View file

@ -1,17 +1,18 @@
require "test_helper"
class Account::ValuationsControllerTest < ActionDispatch::IntegrationTest
class ValuationsControllerTest < ActionDispatch::IntegrationTest
include EntryableResourceInterfaceTest
setup do
sign_in @user = users(:family_admin)
@entry = account_entries(:valuation)
@entry = entries(:valuation)
end
test "error when valuation already exists for date" do
assert_no_difference [ "Account::Entry.count", "Account::Valuation.count" ] do
post account_valuations_url(@entry.account), params: {
account_entry: {
assert_no_difference [ "Entry.count", "Valuation.count" ] do
post valuations_url(@entry.account), params: {
entry: {
account_id: @entry.account_id,
amount: 19800,
date: @entry.date,
currency: "USD"
@ -23,9 +24,9 @@ class Account::ValuationsControllerTest < ActionDispatch::IntegrationTest
end
test "creates entry with basic attributes" do
assert_difference [ "Account::Entry.count", "Account::Valuation.count" ], 1 do
post account_valuations_url, params: {
account_entry: {
assert_difference [ "Entry.count", "Valuation.count" ], 1 do
post valuations_url, params: {
entry: {
name: "New entry",
amount: 10000,
currency: "USD",
@ -35,7 +36,7 @@ class Account::ValuationsControllerTest < ActionDispatch::IntegrationTest
}
end
created_entry = Account::Entry.order(created_at: :desc).first
created_entry = Entry.order(created_at: :desc).first
assert_enqueued_with job: SyncJob
@ -43,9 +44,9 @@ class Account::ValuationsControllerTest < ActionDispatch::IntegrationTest
end
test "updates entry with basic attributes" do
assert_no_difference [ "Account::Entry.count", "Account::Valuation.count" ] do
patch account_valuation_url(@entry), params: {
account_entry: {
assert_no_difference [ "Entry.count", "Valuation.count" ] do
patch valuation_url(@entry), params: {
entry: {
name: "Updated entry",
amount: 20000,
currency: "USD",

View file

@ -11,8 +11,8 @@ class VehiclesControllerTest < ActionDispatch::IntegrationTest
test "creates with vehicle details" do
assert_difference -> { Account.count } => 1,
-> { Vehicle.count } => 1,
-> { Account::Valuation.count } => 2,
-> { Account::Entry.count } => 2 do
-> { Valuation.count } => 2,
-> { Entry.count } => 2 do
post vehicles_path, params: {
account: {
name: "Vehicle",

View file

@ -4,7 +4,7 @@ valuation:
amount: 4995
currency: USD
account: depository
entryable_type: Account::Valuation
entryable_type: Valuation
entryable: one
trade:
@ -13,7 +13,7 @@ trade:
amount: 2140 # 10 shares * $214 per share
currency: USD
account: investment
entryable_type: Account::Trade
entryable_type: Trade
entryable: one
transaction:
@ -22,7 +22,7 @@ transaction:
amount: 10
currency: USD
account: depository
entryable_type: Account::Transaction
entryable_type: Transaction
entryable: one
transfer_out:
@ -31,7 +31,7 @@ transfer_out:
amount: 100
currency: USD
account: depository
entryable_type: Account::Transaction
entryable_type: Transaction
entryable: transfer_out
transfer_in:
@ -40,5 +40,5 @@ transfer_in:
amount: -100
currency: USD
account: credit_card
entryable_type: Account::Transaction
entryable_type: Transaction
entryable: transfer_in

View file

@ -1,10 +1,10 @@
one:
tag: one
taggable: one
taggable_type: Account::Transaction
taggable_type: Transaction
two:
tag: two
taggable: one
taggable_type: Account::Transaction
taggable_type: Transaction

View file

@ -60,7 +60,7 @@ module AccountableResourceInterfaceTest
end
test "updates account balance by creating new valuation if balance has changed" do
assert_difference [ "Account::Entry.count", "Account::Valuation.count" ], 1 do
assert_difference [ "Entry.count", "Valuation.count" ], 1 do
patch account_url(@account), params: {
account: {
balance: 12000
@ -74,9 +74,9 @@ module AccountableResourceInterfaceTest
end
test "updates account balance by editing existing valuation for today" do
@account.entries.create! date: Date.current, amount: 6000, currency: "USD", name: "Balance update", entryable: Account::Valuation.new
@account.entries.create! date: Date.current, amount: 6000, currency: "USD", name: "Balance update", entryable: Valuation.new
assert_no_difference [ "Account::Entry.count", "Account::Valuation.count" ] do
assert_no_difference [ "Entry.count", "Valuation.count" ] do
patch account_url(@account), params: {
account: {
balance: 12000

View file

@ -9,13 +9,13 @@ module EntryableResourceInterfaceTest
end
test "shows editing drawer" do
get account_entry_url(@entry)
get entry_url(@entry)
assert_response :success
end
test "destroys entry" do
assert_difference "Account::Entry.count", -1 do
delete account_entry_url(@entry)
assert_difference "Entry.count", -1 do
delete entry_url(@entry)
end
assert_enqueued_with job: SyncJob

View file

@ -1,51 +0,0 @@
require "test_helper"
class Account::Balance::SyncerTest < ActiveSupport::TestCase
include Account::EntriesTestHelper
setup do
@account = families(:empty).accounts.create!(
name: "Test",
balance: 20000,
cash_balance: 20000,
currency: "USD",
accountable: Investment.new
)
end
test "syncs balances" do
Account::Holding::Syncer.any_instance.expects(:sync_holdings).returns([]).once
@account.expects(:start_date).returns(2.days.ago.to_date)
Account::Balance::ForwardCalculator.any_instance.expects(:calculate).returns(
[
Account::Balance.new(date: 1.day.ago.to_date, balance: 1000, cash_balance: 1000, currency: "USD"),
Account::Balance.new(date: Date.current, balance: 1000, cash_balance: 1000, currency: "USD")
]
)
assert_difference "@account.balances.count", 2 do
Account::Balance::Syncer.new(@account, strategy: :forward).sync_balances
end
end
test "purges stale balances and holdings" do
# Balance before start date is stale
@account.expects(:start_date).returns(2.days.ago.to_date).twice
stale_balance = Account::Balance.new(date: 3.days.ago.to_date, balance: 10000, cash_balance: 10000, currency: "USD")
Account::Balance::ForwardCalculator.any_instance.expects(:calculate).returns(
[
stale_balance,
Account::Balance.new(date: 2.days.ago.to_date, balance: 10000, cash_balance: 10000, currency: "USD"),
Account::Balance.new(date: 1.day.ago.to_date, balance: 1000, cash_balance: 1000, currency: "USD"),
Account::Balance.new(date: Date.current, balance: 1000, cash_balance: 1000, currency: "USD")
]
)
assert_difference "@account.balances.count", 3 do
Account::Balance::Syncer.new(@account, strategy: :forward).sync_balances
end
end
end

View file

@ -2,7 +2,7 @@ require "test_helper"
require "ostruct"
class Account::ConvertibleTest < ActiveSupport::TestCase
include Account::EntriesTestHelper, ProviderTestHelper
include EntriesTestHelper, ProviderTestHelper
setup do
@family = families(:empty)

View file

@ -1,10 +1,10 @@
require "test_helper"
class Account::EntryTest < ActiveSupport::TestCase
include Account::EntriesTestHelper
class EntryTest < ActiveSupport::TestCase
include EntriesTestHelper
setup do
@entry = account_entries :transaction
@entry = entries :transaction
end
test "entry cannot be older than 10 years ago" do
@ -14,10 +14,10 @@ class Account::EntryTest < ActiveSupport::TestCase
end
test "valuations cannot have more than one entry per day" do
existing_valuation = account_entries :valuation
existing_valuation = entries :valuation
new_valuation = Account::Entry.new \
entryable: Account::Valuation.new,
new_valuation = Entry.new \
entryable: Valuation.new,
account: existing_valuation.account,
date: existing_valuation.date, # invalid
currency: existing_valuation.currency,
@ -76,7 +76,7 @@ class Account::EntryTest < ActiveSupport::TestCase
accounts(:credit_card).update!(is_active: false)
# Test the scope
active_entries = Account::Entry.active
active_entries = Entry.active
# Should include entry from active account
assert_includes active_entries, active_transaction

View file

@ -1,5 +1,5 @@
require "test_helper"
class Account::TransactionTest < ActiveSupport::TestCase
include Account::EntriesTestHelper
class TransactionTest < ActiveSupport::TestCase
include EntriesTestHelper
end

View file

@ -1,7 +1,7 @@
require "test_helper"
class AccountTest < ActiveSupport::TestCase
include SyncableInterfaceTest, Account::EntriesTestHelper
include SyncableInterfaceTest, EntriesTestHelper
setup do
@account = @syncable = accounts(:depository)

View file

@ -1,7 +1,7 @@
require "test_helper"
class Account::Balance::ForwardCalculatorTest < ActiveSupport::TestCase
include Account::EntriesTestHelper
class Balance::ForwardCalculatorTest < ActiveSupport::TestCase
include EntriesTestHelper
setup do
@account = families(:empty).accounts.create!(
@ -18,7 +18,7 @@ class Account::Balance::ForwardCalculatorTest < ActiveSupport::TestCase
assert_equal 0, @account.balances.count
expected = [ 0, 0 ]
calculated = Account::Balance::ForwardCalculator.new(@account).calculate
calculated = Balance::ForwardCalculator.new(@account).calculate
assert_equal expected, calculated.map(&:balance)
end
@ -28,7 +28,7 @@ class Account::Balance::ForwardCalculatorTest < ActiveSupport::TestCase
create_valuation(account: @account, date: 2.days.ago.to_date, amount: 19000)
expected = [ 0, 17000, 17000, 19000, 19000, 19000 ]
calculated = Account::Balance::ForwardCalculator.new(@account).calculate.sort_by(&:date).map(&:balance)
calculated = Balance::ForwardCalculator.new(@account).calculate.sort_by(&:date).map(&:balance)
assert_equal expected, calculated
end
@ -38,7 +38,7 @@ class Account::Balance::ForwardCalculatorTest < ActiveSupport::TestCase
create_transaction(account: @account, date: 2.days.ago.to_date, amount: 100) # expense
expected = [ 0, 500, 500, 400, 400, 400 ]
calculated = Account::Balance::ForwardCalculator.new(@account).calculate.sort_by(&:date).map(&:balance)
calculated = Balance::ForwardCalculator.new(@account).calculate.sort_by(&:date).map(&:balance)
assert_equal expected, calculated
end
@ -52,7 +52,7 @@ class Account::Balance::ForwardCalculatorTest < ActiveSupport::TestCase
create_transaction(account: @account, date: 1.day.ago.to_date, amount: 100)
expected = [ 0, 5000, 5000, 17000, 17000, 17500, 17000, 17000, 16900, 16900 ]
calculated = Account::Balance::ForwardCalculator.new(@account).calculate.sort_by(&:date).map(&:balance)
calculated = Balance::ForwardCalculator.new(@account).calculate.sort_by(&:date).map(&:balance)
assert_equal expected, calculated
end
@ -67,7 +67,7 @@ class Account::Balance::ForwardCalculatorTest < ActiveSupport::TestCase
create_transaction(account: @account, date: 1.day.ago.to_date, amount: -500, currency: "EUR") # €500 * 1.2 = $600
expected = [ 0, 100, 400, 1000, 1000 ]
calculated = Account::Balance::ForwardCalculator.new(@account).calculate.sort_by(&:date).map(&:balance)
calculated = Balance::ForwardCalculator.new(@account).calculate.sort_by(&:date).map(&:balance)
assert_equal expected, calculated
end

View file

@ -1,7 +1,7 @@
require "test_helper"
class Account::Balance::ReverseCalculatorTest < ActiveSupport::TestCase
include Account::EntriesTestHelper
class Balance::ReverseCalculatorTest < ActiveSupport::TestCase
include EntriesTestHelper
setup do
@account = families(:empty).accounts.create!(
@ -18,7 +18,7 @@ class Account::Balance::ReverseCalculatorTest < ActiveSupport::TestCase
assert_equal 0, @account.balances.count
expected = [ @account.balance, @account.balance ]
calculated = Account::Balance::ReverseCalculator.new(@account).calculate
calculated = Balance::ReverseCalculator.new(@account).calculate
assert_equal expected, calculated.map(&:balance)
end
@ -28,7 +28,7 @@ class Account::Balance::ReverseCalculatorTest < ActiveSupport::TestCase
create_valuation(account: @account, date: 2.days.ago.to_date, amount: 19000)
expected = [ 17000, 17000, 19000, 19000, 20000, 20000 ]
calculated = Account::Balance::ReverseCalculator.new(@account).calculate.sort_by(&:date).map(&:balance)
calculated = Balance::ReverseCalculator.new(@account).calculate.sort_by(&:date).map(&:balance)
assert_equal expected, calculated
end
@ -38,7 +38,7 @@ class Account::Balance::ReverseCalculatorTest < ActiveSupport::TestCase
create_transaction(account: @account, date: 2.days.ago.to_date, amount: 100) # expense
expected = [ 19600, 20100, 20100, 20000, 20000, 20000 ]
calculated = Account::Balance::ReverseCalculator.new(@account).calculate.sort_by(&:date).map(&:balance)
calculated = Balance::ReverseCalculator.new(@account).calculate.sort_by(&:date).map(&:balance)
assert_equal expected, calculated
end
@ -52,7 +52,7 @@ class Account::Balance::ReverseCalculatorTest < ActiveSupport::TestCase
create_transaction(account: @account, date: 1.day.ago.to_date, amount: 100)
expected = [ 12000, 17000, 17000, 17000, 16500, 17000, 17000, 20100, 20000, 20000 ]
calculated = Account::Balance::ReverseCalculator.new(@account).calculate.sort_by(&:date).map(&:balance)
calculated = Balance::ReverseCalculator.new(@account).calculate.sort_by(&:date).map(&:balance)
assert_equal expected, calculated
end

View file

@ -0,0 +1,51 @@
require "test_helper"
class Balance::SyncerTest < ActiveSupport::TestCase
include EntriesTestHelper
setup do
@account = families(:empty).accounts.create!(
name: "Test",
balance: 20000,
cash_balance: 20000,
currency: "USD",
accountable: Investment.new
)
end
test "syncs balances" do
Holding::Syncer.any_instance.expects(:sync_holdings).returns([]).once
@account.expects(:start_date).returns(2.days.ago.to_date)
Balance::ForwardCalculator.any_instance.expects(:calculate).returns(
[
Balance.new(date: 1.day.ago.to_date, balance: 1000, cash_balance: 1000, currency: "USD"),
Balance.new(date: Date.current, balance: 1000, cash_balance: 1000, currency: "USD")
]
)
assert_difference "@account.balances.count", 2 do
Balance::Syncer.new(@account, strategy: :forward).sync_balances
end
end
test "purges stale balances and holdings" do
# Balance before start date is stale
@account.expects(:start_date).returns(2.days.ago.to_date).twice
stale_balance = Balance.new(date: 3.days.ago.to_date, balance: 10000, cash_balance: 10000, currency: "USD")
Balance::ForwardCalculator.any_instance.expects(:calculate).returns(
[
stale_balance,
Balance.new(date: 2.days.ago.to_date, balance: 10000, cash_balance: 10000, currency: "USD"),
Balance.new(date: 1.day.ago.to_date, balance: 1000, cash_balance: 1000, currency: "USD"),
Balance.new(date: Date.current, balance: 1000, cash_balance: 1000, currency: "USD")
]
)
assert_difference "@account.balances.count", 3 do
Balance::Syncer.new(@account, strategy: :forward).sync_balances
end
end
end

View file

@ -1,7 +1,7 @@
require "test_helper"
class Family::AutoTransferMatchableTest < ActiveSupport::TestCase
include Account::EntriesTestHelper
include EntriesTestHelper
setup do
@family = families(:dylan_family)

View file

@ -2,7 +2,7 @@ require "test_helper"
require "csv"
class FamilyTest < ActiveSupport::TestCase
include Account::EntriesTestHelper
include EntriesTestHelper
include SyncableInterfaceTest
def setup

View file

@ -1,7 +1,7 @@
require "test_helper"
class Account::Holding::ForwardCalculatorTest < ActiveSupport::TestCase
include Account::EntriesTestHelper
class Holding::ForwardCalculatorTest < ActiveSupport::TestCase
include EntriesTestHelper
setup do
@account = families(:empty).accounts.create!(
@ -14,7 +14,7 @@ class Account::Holding::ForwardCalculatorTest < ActiveSupport::TestCase
end
test "no holdings" do
calculated = Account::Holding::ForwardCalculator.new(@account).calculate
calculated = Holding::ForwardCalculator.new(@account).calculate
assert_equal [], calculated
end
@ -35,32 +35,32 @@ class Account::Holding::ForwardCalculatorTest < ActiveSupport::TestCase
expected = [
# 4 days ago
Account::Holding.new(security: @voo, date: 4.days.ago.to_date, qty: 0, price: 460, amount: 0),
Account::Holding.new(security: @wmt, date: 4.days.ago.to_date, qty: 0, price: 100, amount: 0),
Account::Holding.new(security: @amzn, date: 4.days.ago.to_date, qty: 0, price: 200, amount: 0),
Holding.new(security: @voo, date: 4.days.ago.to_date, qty: 0, price: 460, amount: 0),
Holding.new(security: @wmt, date: 4.days.ago.to_date, qty: 0, price: 100, amount: 0),
Holding.new(security: @amzn, date: 4.days.ago.to_date, qty: 0, price: 200, amount: 0),
# 3 days ago
Account::Holding.new(security: @voo, date: 3.days.ago.to_date, qty: 20, price: 470, amount: 9400),
Account::Holding.new(security: @wmt, date: 3.days.ago.to_date, qty: 0, price: 100, amount: 0),
Account::Holding.new(security: @amzn, date: 3.days.ago.to_date, qty: 0, price: 200, amount: 0),
Holding.new(security: @voo, date: 3.days.ago.to_date, qty: 20, price: 470, amount: 9400),
Holding.new(security: @wmt, date: 3.days.ago.to_date, qty: 0, price: 100, amount: 0),
Holding.new(security: @amzn, date: 3.days.ago.to_date, qty: 0, price: 200, amount: 0),
# 2 days ago
Account::Holding.new(security: @voo, date: 2.days.ago.to_date, qty: 5, price: 480, amount: 2400),
Account::Holding.new(security: @wmt, date: 2.days.ago.to_date, qty: 0, price: 100, amount: 0),
Account::Holding.new(security: @amzn, date: 2.days.ago.to_date, qty: 1, price: 200, amount: 200),
Holding.new(security: @voo, date: 2.days.ago.to_date, qty: 5, price: 480, amount: 2400),
Holding.new(security: @wmt, date: 2.days.ago.to_date, qty: 0, price: 100, amount: 0),
Holding.new(security: @amzn, date: 2.days.ago.to_date, qty: 1, price: 200, amount: 200),
# 1 day ago
Account::Holding.new(security: @voo, date: 1.day.ago.to_date, qty: 10, price: 490, amount: 4900),
Account::Holding.new(security: @wmt, date: 1.day.ago.to_date, qty: 100, price: 100, amount: 10000),
Account::Holding.new(security: @amzn, date: 1.day.ago.to_date, qty: 0, price: 200, amount: 0),
Holding.new(security: @voo, date: 1.day.ago.to_date, qty: 10, price: 490, amount: 4900),
Holding.new(security: @wmt, date: 1.day.ago.to_date, qty: 100, price: 100, amount: 10000),
Holding.new(security: @amzn, date: 1.day.ago.to_date, qty: 0, price: 200, amount: 0),
# Today
Account::Holding.new(security: @voo, date: Date.current, qty: 10, price: 500, amount: 5000),
Account::Holding.new(security: @wmt, date: Date.current, qty: 100, price: 100, amount: 10000),
Account::Holding.new(security: @amzn, date: Date.current, qty: 0, price: 200, amount: 0)
Holding.new(security: @voo, date: Date.current, qty: 10, price: 500, amount: 5000),
Holding.new(security: @wmt, date: Date.current, qty: 100, price: 100, amount: 10000),
Holding.new(security: @amzn, date: Date.current, qty: 0, price: 200, amount: 0)
]
calculated = Account::Holding::ForwardCalculator.new(@account).calculate
calculated = Holding::ForwardCalculator.new(@account).calculate
assert_equal expected.length, calculated.length
assert_holdings(expected, calculated)
@ -74,9 +74,9 @@ class Account::Holding::ForwardCalculatorTest < ActiveSupport::TestCase
create_trade(@wmt, qty: 100, date: 1.day.ago.to_date, price: 100, account: @account)
expected = [
Account::Holding.new(security: @wmt, date: 2.days.ago.to_date, qty: 0, price: 100, amount: 0),
Account::Holding.new(security: @wmt, date: 1.day.ago.to_date, qty: 100, price: 100, amount: 10000),
Account::Holding.new(security: @wmt, date: Date.current, qty: 100, price: 100, amount: 10000)
Holding.new(security: @wmt, date: 2.days.ago.to_date, qty: 0, price: 100, amount: 0),
Holding.new(security: @wmt, date: 1.day.ago.to_date, qty: 100, price: 100, amount: 10000),
Holding.new(security: @wmt, date: Date.current, qty: 100, price: 100, amount: 10000)
]
# Price missing today, so we should carry forward the holding from 1 day ago
@ -85,7 +85,7 @@ class Account::Holding::ForwardCalculatorTest < ActiveSupport::TestCase
Security::Price.stubs(:find_price).with(security: @wmt, date: 1.day.ago.to_date).returns(Security::Price.new(price: 100))
Security::Price.stubs(:find_price).with(security: @wmt, date: Date.current).returns(nil)
calculated = Account::Holding::ForwardCalculator.new(@account).calculate
calculated = Holding::ForwardCalculator.new(@account).calculate
assert_equal expected.length, calculated.length
assert_holdings(expected, calculated)
@ -98,13 +98,13 @@ class Account::Holding::ForwardCalculatorTest < ActiveSupport::TestCase
create_trade(offline_security, qty: 1, date: 1.day.ago.to_date, price: 100, account: @account)
expected = [
Account::Holding.new(security: offline_security, date: 3.days.ago.to_date, qty: 1, price: 90, amount: 90),
Account::Holding.new(security: offline_security, date: 2.days.ago.to_date, qty: 1, price: 90, amount: 90),
Account::Holding.new(security: offline_security, date: 1.day.ago.to_date, qty: 2, price: 100, amount: 200),
Account::Holding.new(security: offline_security, date: Date.current, qty: 2, price: 100, amount: 200)
Holding.new(security: offline_security, date: 3.days.ago.to_date, qty: 1, price: 90, amount: 90),
Holding.new(security: offline_security, date: 2.days.ago.to_date, qty: 1, price: 90, amount: 90),
Holding.new(security: offline_security, date: 1.day.ago.to_date, qty: 2, price: 100, amount: 200),
Holding.new(security: offline_security, date: Date.current, qty: 2, price: 100, amount: 200)
]
calculated = Account::Holding::ForwardCalculator.new(@account).calculate
calculated = Holding::ForwardCalculator.new(@account).calculate
assert_equal expected.length, calculated.length
assert_holdings(expected, calculated)

View file

@ -1,7 +1,7 @@
require "test_helper"
class Account::Holding::PortfolioCacheTest < ActiveSupport::TestCase
include Account::EntriesTestHelper, ProviderTestHelper
class Holding::PortfolioCacheTest < ActiveSupport::TestCase
include EntriesTestHelper, ProviderTestHelper
setup do
@provider = mock
@ -16,7 +16,7 @@ class Account::Holding::PortfolioCacheTest < ActiveSupport::TestCase
@security = Security.create!(name: "Test Security", ticker: "TEST", exchange_operating_mic: "TEST")
@trade = create_trade(@security, account: @account, qty: 1, date: 2.days.ago.to_date, price: 210.23).account_trade
@trade = create_trade(@security, account: @account, qty: 1, date: 2.days.ago.to_date, price: 210.23).trade
end
test "gets price from DB if available" do
@ -30,7 +30,7 @@ class Account::Holding::PortfolioCacheTest < ActiveSupport::TestCase
expect_provider_prices([], start_date: @account.start_date)
cache = Account::Holding::PortfolioCache.new(@account)
cache = Holding::PortfolioCache.new(@account)
assert_equal db_price, cache.get_price(@security.id, Date.current).price
end
@ -46,7 +46,7 @@ class Account::Holding::PortfolioCacheTest < ActiveSupport::TestCase
expect_provider_prices([ provider_price ], start_date: @account.start_date)
cache = Account::Holding::PortfolioCache.new(@account)
cache = Holding::PortfolioCache.new(@account)
assert_equal provider_price.price, cache.get_price(@security.id, Date.current).price
end
@ -54,15 +54,15 @@ class Account::Holding::PortfolioCacheTest < ActiveSupport::TestCase
Security::Price.destroy_all
expect_provider_prices([], start_date: @account.start_date)
cache = Account::Holding::PortfolioCache.new(@account)
cache = Holding::PortfolioCache.new(@account)
assert_equal @trade.price, cache.get_price(@security.id, @trade.entry.date).price
end
test "if no price from db, provider, or trades, search holdings" do
Security::Price.delete_all
Account::Entry.delete_all
Entry.delete_all
holding = Account::Holding.create!(
holding = Holding.create!(
security: @security,
account: @account,
date: Date.current,
@ -74,7 +74,7 @@ class Account::Holding::PortfolioCacheTest < ActiveSupport::TestCase
expect_provider_prices([], start_date: @account.start_date)
cache = Account::Holding::PortfolioCache.new(@account, use_holdings: true)
cache = Holding::PortfolioCache.new(@account, use_holdings: true)
assert_equal holding.price, cache.get_price(@security.id, holding.date).price
end

View file

@ -1,7 +1,7 @@
require "test_helper"
class Account::Holding::ReverseCalculatorTest < ActiveSupport::TestCase
include Account::EntriesTestHelper
class Holding::ReverseCalculatorTest < ActiveSupport::TestCase
include EntriesTestHelper
setup do
@account = families(:empty).accounts.create!(
@ -14,7 +14,7 @@ class Account::Holding::ReverseCalculatorTest < ActiveSupport::TestCase
end
test "no holdings" do
calculated = Account::Holding::ReverseCalculator.new(@account).calculate
calculated = Holding::ReverseCalculator.new(@account).calculate
assert_equal [], calculated
end
@ -26,7 +26,7 @@ class Account::Holding::ReverseCalculatorTest < ActiveSupport::TestCase
create_trade(voo, qty: -10, date: Date.current, price: 470, account: @account)
calculated = Account::Holding::ReverseCalculator.new(@account).calculate
calculated = Holding::ReverseCalculator.new(@account).calculate
assert_equal 2, calculated.length
end
@ -47,32 +47,32 @@ class Account::Holding::ReverseCalculatorTest < ActiveSupport::TestCase
expected = [
# 4 days ago
Account::Holding.new(security: @voo, date: 4.days.ago.to_date, qty: 0, price: 460, amount: 0),
Account::Holding.new(security: @wmt, date: 4.days.ago.to_date, qty: 0, price: 100, amount: 0),
Account::Holding.new(security: @amzn, date: 4.days.ago.to_date, qty: 0, price: 200, amount: 0),
Holding.new(security: @voo, date: 4.days.ago.to_date, qty: 0, price: 460, amount: 0),
Holding.new(security: @wmt, date: 4.days.ago.to_date, qty: 0, price: 100, amount: 0),
Holding.new(security: @amzn, date: 4.days.ago.to_date, qty: 0, price: 200, amount: 0),
# 3 days ago
Account::Holding.new(security: @voo, date: 3.days.ago.to_date, qty: 20, price: 470, amount: 9400),
Account::Holding.new(security: @wmt, date: 3.days.ago.to_date, qty: 0, price: 100, amount: 0),
Account::Holding.new(security: @amzn, date: 3.days.ago.to_date, qty: 0, price: 200, amount: 0),
Holding.new(security: @voo, date: 3.days.ago.to_date, qty: 20, price: 470, amount: 9400),
Holding.new(security: @wmt, date: 3.days.ago.to_date, qty: 0, price: 100, amount: 0),
Holding.new(security: @amzn, date: 3.days.ago.to_date, qty: 0, price: 200, amount: 0),
# 2 days ago
Account::Holding.new(security: @voo, date: 2.days.ago.to_date, qty: 5, price: 480, amount: 2400),
Account::Holding.new(security: @wmt, date: 2.days.ago.to_date, qty: 0, price: 100, amount: 0),
Account::Holding.new(security: @amzn, date: 2.days.ago.to_date, qty: 1, price: 200, amount: 200),
Holding.new(security: @voo, date: 2.days.ago.to_date, qty: 5, price: 480, amount: 2400),
Holding.new(security: @wmt, date: 2.days.ago.to_date, qty: 0, price: 100, amount: 0),
Holding.new(security: @amzn, date: 2.days.ago.to_date, qty: 1, price: 200, amount: 200),
# 1 day ago
Account::Holding.new(security: @voo, date: 1.day.ago.to_date, qty: 10, price: 490, amount: 4900),
Account::Holding.new(security: @wmt, date: 1.day.ago.to_date, qty: 100, price: 100, amount: 10000),
Account::Holding.new(security: @amzn, date: 1.day.ago.to_date, qty: 0, price: 200, amount: 0),
Holding.new(security: @voo, date: 1.day.ago.to_date, qty: 10, price: 490, amount: 4900),
Holding.new(security: @wmt, date: 1.day.ago.to_date, qty: 100, price: 100, amount: 10000),
Holding.new(security: @amzn, date: 1.day.ago.to_date, qty: 0, price: 200, amount: 0),
# Today
Account::Holding.new(security: @voo, date: Date.current, qty: 10, price: 500, amount: 5000),
Account::Holding.new(security: @wmt, date: Date.current, qty: 100, price: 100, amount: 10000),
Account::Holding.new(security: @amzn, date: Date.current, qty: 0, price: 200, amount: 0)
Holding.new(security: @voo, date: Date.current, qty: 10, price: 500, amount: 5000),
Holding.new(security: @wmt, date: Date.current, qty: 100, price: 100, amount: 10000),
Holding.new(security: @amzn, date: Date.current, qty: 0, price: 200, amount: 0)
]
calculated = Account::Holding::ReverseCalculator.new(@account).calculate
calculated = Holding::ReverseCalculator.new(@account).calculate
assert_equal expected.length, calculated.length

View file

@ -1,7 +1,7 @@
require "test_helper"
class Account::Holding::SyncerTest < ActiveSupport::TestCase
include Account::EntriesTestHelper
class Holding::SyncerTest < ActiveSupport::TestCase
include EntriesTestHelper
setup do
@family = families(:empty)
@ -14,16 +14,16 @@ class Account::Holding::SyncerTest < ActiveSupport::TestCase
# Should have yesterday's and today's holdings
assert_difference "@account.holdings.count", 2 do
Account::Holding::Syncer.new(@account, strategy: :forward).sync_holdings
Holding::Syncer.new(@account, strategy: :forward).sync_holdings
end
end
test "purges stale holdings for unlinked accounts" do
# Since the account has no entries, there should be no holdings
Account::Holding.create!(account: @account, security: @aapl, qty: 1, price: 100, amount: 100, currency: "USD", date: Date.current)
Holding.create!(account: @account, security: @aapl, qty: 1, price: 100, amount: 100, currency: "USD", date: Date.current)
assert_difference "Account::Holding.count", -1 do
Account::Holding::Syncer.new(@account, strategy: :forward).sync_holdings
assert_difference "Holding.count", -1 do
Holding::Syncer.new(@account, strategy: :forward).sync_holdings
end
end
end

View file

@ -1,8 +1,8 @@
require "test_helper"
require "ostruct"
class Account::HoldingTest < ActiveSupport::TestCase
include Account::EntriesTestHelper, SecuritiesTestHelper
class HoldingTest < ActiveSupport::TestCase
include EntriesTestHelper, SecuritiesTestHelper
setup do
@account = families(:empty).accounts.create!(name: "Test Brokerage", balance: 20000, cash_balance: 0, currency: "USD", accountable: Investment.new)

View file

@ -1,7 +1,7 @@
require "test_helper"
class IncomeStatementTest < ActiveSupport::TestCase
include Account::EntriesTestHelper
include EntriesTestHelper
setup do
@family = families(:empty)

View file

@ -43,9 +43,9 @@ class PlaidInvestmentSyncTest < ActiveSupport::TestCase
]
# Cash holding should be ignored, resulting in 1, NOT 2 total holdings after sync
assert_difference -> { Account::Trade.count } => 1,
-> { Account::Transaction.count } => 0,
-> { Account::Holding.count } => 1,
assert_difference -> { Trade.count } => 1,
-> { Transaction.count } => 0,
-> { Holding.count } => 1,
-> { Security.count } => 0 do
PlaidInvestmentSync.new(@plaid_account).sync!(
transactions: transactions,
@ -69,8 +69,8 @@ class PlaidInvestmentSyncTest < ActiveSupport::TestCase
})
]
assert_difference -> { Account::Trade.count } => 0,
-> { Account::Transaction.count } => 1,
assert_difference -> { Trade.count } => 0,
-> { Transaction.count } => 1,
-> { Security.count } => 0 do
PlaidInvestmentSync.new(@plaid_account).sync!(
transactions: transactions,

View file

@ -53,8 +53,8 @@ class TradeImportTest < ActiveSupport::TestCase
@import.reload
assert_difference [
-> { Account::Entry.count },
-> { Account::Trade.count }
-> { Entry.count },
-> { Trade.count }
], 2 do
assert_difference [
-> { Security.count },

View file

@ -58,8 +58,8 @@ class TransactionImportTest < ActiveSupport::TestCase
@import.reload
assert_difference -> { Account::Entry.count } => 3,
-> { Account::Transaction.count } => 3,
assert_difference -> { Entry.count } => 3,
-> { Transaction.count } => 3,
-> { Tag.count } => 1,
-> { Category.count } => 1,
-> { Account.count } => 1 do

View file

@ -1,15 +1,15 @@
require "test_helper"
class TransferTest < ActiveSupport::TestCase
include Account::EntriesTestHelper
include EntriesTestHelper
setup do
@outflow = account_transactions(:transfer_out)
@inflow = account_transactions(:transfer_in)
@outflow = transactions(:transfer_out)
@inflow = transactions(:transfer_in)
end
test "transfer destroyed if either transaction is destroyed" do
assert_difference [ "Transfer.count", "Account::Transaction.count", "Account::Entry.count" ], -1 do
assert_difference [ "Transfer.count", "Transaction.count", "Entry.count" ], -1 do
@outflow.entry.destroy
end
end
@ -20,8 +20,8 @@ class TransferTest < ActiveSupport::TestCase
assert_difference -> { Transfer.count } => 1 do
Transfer.create!(
inflow_transaction: inflow_entry.account_transaction,
outflow_transaction: outflow_entry.account_transaction,
inflow_transaction: inflow_entry.transaction,
outflow_transaction: outflow_entry.transaction,
)
end
end
@ -31,8 +31,8 @@ class TransferTest < ActiveSupport::TestCase
inflow_entry = create_transaction(date: 1.day.ago.to_date, account: accounts(:depository), amount: -500)
transfer = Transfer.new(
inflow_transaction: inflow_entry.account_transaction,
outflow_transaction: outflow_entry.account_transaction,
inflow_transaction: inflow_entry.transaction,
outflow_transaction: outflow_entry.transaction,
)
assert_no_difference -> { Transfer.count } do
@ -47,8 +47,8 @@ class TransferTest < ActiveSupport::TestCase
inflow_entry = create_transaction(date: Date.current, account: accounts(:credit_card), amount: -400)
transfer = Transfer.new(
inflow_transaction: inflow_entry.account_transaction,
outflow_transaction: outflow_entry.account_transaction,
inflow_transaction: inflow_entry.transaction,
outflow_transaction: outflow_entry.transaction,
)
assert_no_difference -> { Transfer.count } do
@ -63,8 +63,8 @@ class TransferTest < ActiveSupport::TestCase
inflow_entry = create_transaction(date: 5.days.ago.to_date, account: accounts(:credit_card), amount: -500)
transfer = Transfer.new(
inflow_transaction: inflow_entry.account_transaction,
outflow_transaction: outflow_entry.account_transaction,
inflow_transaction: inflow_entry.transaction,
outflow_transaction: outflow_entry.transaction,
)
assert_no_difference -> { Transfer.count } do
@ -85,8 +85,8 @@ class TransferTest < ActiveSupport::TestCase
inflow_txn = create_transaction(date: Date.current, account: family2_account, amount: -500)
transfer = Transfer.new(
inflow_transaction: inflow_txn.account_transaction,
outflow_transaction: outflow_txn.account_transaction,
inflow_transaction: inflow_txn.transaction,
outflow_transaction: outflow_txn.transaction,
)
assert transfer.invalid?
@ -128,10 +128,10 @@ class TransferTest < ActiveSupport::TestCase
inflow_entry1 = create_transaction(date: Date.current, account: accounts(:credit_card), amount: -500)
inflow_entry2 = create_transaction(date: Date.current, account: accounts(:credit_card), amount: -500)
Transfer.create!(inflow_transaction: inflow_entry1.account_transaction, outflow_transaction: outflow_entry.account_transaction)
Transfer.create!(inflow_transaction: inflow_entry1.transaction, outflow_transaction: outflow_entry.transaction)
assert_raises ActiveRecord::RecordInvalid do
Transfer.create!(inflow_transaction: inflow_entry2.account_transaction, outflow_transaction: outflow_entry.account_transaction)
Transfer.create!(inflow_transaction: inflow_entry2.transaction, outflow_transaction: outflow_entry.transaction)
end
end
end

View file

@ -1,4 +1,4 @@
module Account::EntriesTestHelper
module EntriesTestHelper
def create_transaction(attributes = {})
entry_attributes = attributes.except(:category, :tags, :merchant)
transaction_attributes = attributes.slice(:category, :tags, :merchant)
@ -9,10 +9,10 @@ module Account::EntriesTestHelper
date: Date.current,
currency: "USD",
amount: 100,
entryable: Account::Transaction.new(transaction_attributes)
entryable: Transaction.new(transaction_attributes)
}
Account::Entry.create! entry_defaults.merge(entry_attributes)
Entry.create! entry_defaults.merge(entry_attributes)
end
def create_valuation(attributes = {})
@ -22,16 +22,16 @@ module Account::EntriesTestHelper
date: 1.day.ago.to_date,
currency: "USD",
amount: 5000,
entryable: Account::Valuation.new
entryable: Valuation.new
}
Account::Entry.create! entry_defaults.merge(attributes)
Entry.create! entry_defaults.merge(attributes)
end
def create_trade(security, account:, qty:, date:, price: nil)
trade_price = price || Security::Price.find_by!(security: security, date: date).price
trade = Account::Trade.new \
trade = Trade.new \
qty: qty,
security: security,
price: trade_price,

View file

@ -22,11 +22,11 @@ class TradesTest < ApplicationSystemTestCase
fill_in "Ticker symbol", with: "AAPL"
fill_in "Date", with: Date.current
fill_in "Quantity", with: shares_qty
fill_in "account_entry[price]", with: 214.23
fill_in "entry[price]", with: 214.23
click_button "Add transaction"
visit_account_trades
visit_trades
within_trades do
assert_text "Purchase 10 shares of AAPL"
@ -43,11 +43,11 @@ class TradesTest < ApplicationSystemTestCase
fill_in "Ticker symbol", with: aapl.ticker
fill_in "Date", with: Date.current
fill_in "Quantity", with: aapl.qty
fill_in "account_entry[price]", with: 215.33
fill_in "entry[price]", with: 215.33
click_button "Add transaction"
visit_account_trades
visit_trades
within_trades do
assert_text "Sell #{aapl.qty.round} shares of AAPL"
@ -64,7 +64,7 @@ class TradesTest < ApplicationSystemTestCase
within "#" + dom_id(@account, "entries"), &block
end
def visit_account_trades
def visit_trades
visit account_path(@account, tab: "activity")
end

View file

@ -4,7 +4,7 @@ class TransactionsTest < ApplicationSystemTestCase
setup do
sign_in @user = users(:family_admin)
Account::Entry.delete_all # clean slate
Entry.delete_all # clean slate
create_transaction("one", 12.days.ago.to_date, 100)
create_transaction("two", 10.days.ago.to_date, 100)
@ -19,7 +19,7 @@ class TransactionsTest < ApplicationSystemTestCase
create_transaction("eleven", Date.current, 100, category: categories(:food_and_drink), tags: [ tags(:one) ], merchant: merchants(:amazon))
@transactions = @user.family.entries
.account_transactions
.transactions
.reverse_chronological
@transaction = @transactions.first
@ -49,7 +49,7 @@ class TransactionsTest < ApplicationSystemTestCase
within "#transaction-filters-menu" do
check(@transaction.account.name)
click_button "Category"
check(@transaction.account_transaction.category.name)
check(@transaction.transaction.category.name)
click_button "Apply"
end
@ -57,7 +57,7 @@ class TransactionsTest < ApplicationSystemTestCase
within "#transaction-search-filters" do
assert_text @transaction.account.name
assert_text @transaction.account_transaction.category.name
assert_text @transaction.transaction.category.name
end
end
@ -77,7 +77,7 @@ class TransactionsTest < ApplicationSystemTestCase
within "#transaction-filters-menu" do
click_button "Category"
check(@transaction.account_transaction.category.name)
check(@transaction.transaction.category.name)
click_button "Apply"
end
@ -89,8 +89,8 @@ class TransactionsTest < ApplicationSystemTestCase
find("#transaction-filters-button").click
account = @transaction.account
category = @transaction.account_transaction.category
merchant = @transaction.account_transaction.merchant
category = @transaction.transaction.category
merchant = @transaction.transaction.merchant
within "#transaction-filters-menu" do
click_button "Account"
@ -180,7 +180,7 @@ class TransactionsTest < ApplicationSystemTestCase
test "can create deposit transaction for investment account" do
investment_account = accounts(:investment)
investment_account.entries.create!(name: "Investment account", date: Date.current, amount: 1000, currency: "USD", entryable: Account::Transaction.new)
investment_account.entries.create!(name: "Investment account", date: Date.current, amount: 1000, currency: "USD", entryable: Transaction.new)
transfer_date = Date.current
visit account_url(investment_account, tab: "activity")
within "[data-testid='activity-menu']" do
@ -189,7 +189,7 @@ class TransactionsTest < ApplicationSystemTestCase
end
select "Deposit", from: "Type"
fill_in "Date", with: transfer_date
fill_in "account_entry[amount]", with: 175.25
fill_in "entry[amount]", with: 175.25
click_button "Add transaction"
within "#entry-group-" + transfer_date.to_s do
assert_text "175.25"
@ -218,7 +218,7 @@ class TransactionsTest < ApplicationSystemTestCase
date: date,
amount: amount,
currency: "USD",
entryable: Account::Transaction.new(category: category, merchant: merchant, tags: tags)
entryable: Transaction.new(category: category, merchant: merchant, tags: tags)
end
def number_of_transactions_on_page