mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-19 13:19:39 +02:00
Add currency validation to account, update demo data generator (#996)
* Add currency validation to account, update demo data generator * Fix tests
This commit is contained in:
parent
ef0f910b9b
commit
b200b71284
6 changed files with 44 additions and 27 deletions
|
@ -4,7 +4,7 @@ class Account < ApplicationRecord
|
||||||
|
|
||||||
broadcasts_refreshes
|
broadcasts_refreshes
|
||||||
|
|
||||||
validates :family, presence: true
|
validates :name, :balance, :currency, presence: true
|
||||||
|
|
||||||
belongs_to :family
|
belongs_to :family
|
||||||
belongs_to :institution, optional: true
|
belongs_to :institution, optional: true
|
||||||
|
|
|
@ -100,6 +100,7 @@ class Demo::Generator
|
||||||
accountable: CreditCard.new,
|
accountable: CreditCard.new,
|
||||||
name: "Chase Credit Card",
|
name: "Chase Credit Card",
|
||||||
balance: 2300,
|
balance: 2300,
|
||||||
|
currency: "USD",
|
||||||
institution: family.institutions.find_or_create_by(name: "Chase")
|
institution: family.institutions.find_or_create_by(name: "Chase")
|
||||||
|
|
||||||
50.times do
|
50.times do
|
||||||
|
@ -126,6 +127,7 @@ class Demo::Generator
|
||||||
accountable: Depository.new,
|
accountable: Depository.new,
|
||||||
name: "Chase Checking",
|
name: "Chase Checking",
|
||||||
balance: 15000,
|
balance: 15000,
|
||||||
|
currency: "USD",
|
||||||
institution: family.institutions.find_or_create_by(name: "Chase")
|
institution: family.institutions.find_or_create_by(name: "Chase")
|
||||||
|
|
||||||
10.times do
|
10.times do
|
||||||
|
@ -149,6 +151,7 @@ class Demo::Generator
|
||||||
accountable: Depository.new,
|
accountable: Depository.new,
|
||||||
name: "Demo Savings",
|
name: "Demo Savings",
|
||||||
balance: 40000,
|
balance: 40000,
|
||||||
|
currency: "USD",
|
||||||
subtype: "savings",
|
subtype: "savings",
|
||||||
institution: family.institutions.find_or_create_by(name: "Chase")
|
institution: family.institutions.find_or_create_by(name: "Chase")
|
||||||
|
|
||||||
|
@ -195,6 +198,7 @@ class Demo::Generator
|
||||||
accountable: Investment.new,
|
accountable: Investment.new,
|
||||||
name: "Robinhood",
|
name: "Robinhood",
|
||||||
balance: 100000,
|
balance: 100000,
|
||||||
|
currency: "USD",
|
||||||
institution: family.institutions.find_or_create_by(name: "Robinhood")
|
institution: family.institutions.find_or_create_by(name: "Robinhood")
|
||||||
|
|
||||||
aapl = Security.find_by(symbol: "AAPL")
|
aapl = Security.find_by(symbol: "AAPL")
|
||||||
|
@ -228,7 +232,8 @@ class Demo::Generator
|
||||||
house = family.accounts.create! \
|
house = family.accounts.create! \
|
||||||
accountable: Property.new,
|
accountable: Property.new,
|
||||||
name: "123 Maybe Way",
|
name: "123 Maybe Way",
|
||||||
balance: 560000
|
balance: 560000,
|
||||||
|
currency: "USD"
|
||||||
|
|
||||||
create_valuation!(house, 3.years.ago.to_date, 520000)
|
create_valuation!(house, 3.years.ago.to_date, 520000)
|
||||||
create_valuation!(house, 2.years.ago.to_date, 540000)
|
create_valuation!(house, 2.years.ago.to_date, 540000)
|
||||||
|
@ -237,19 +242,22 @@ class Demo::Generator
|
||||||
family.accounts.create! \
|
family.accounts.create! \
|
||||||
accountable: Loan.new,
|
accountable: Loan.new,
|
||||||
name: "Mortgage",
|
name: "Mortgage",
|
||||||
balance: 495000
|
balance: 495000,
|
||||||
|
currency: "USD"
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_car_and_loan!
|
def create_car_and_loan!
|
||||||
family.accounts.create! \
|
family.accounts.create! \
|
||||||
accountable: Vehicle.new,
|
accountable: Vehicle.new,
|
||||||
name: "Honda Accord",
|
name: "Honda Accord",
|
||||||
balance: 18000
|
balance: 18000,
|
||||||
|
currency: "USD"
|
||||||
|
|
||||||
family.accounts.create! \
|
family.accounts.create! \
|
||||||
accountable: Loan.new,
|
accountable: Loan.new,
|
||||||
name: "Car Loan",
|
name: "Car Loan",
|
||||||
balance: 8000
|
balance: 8000,
|
||||||
|
currency: "USD"
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_transaction!(attributes = {})
|
def create_transaction!(attributes = {})
|
||||||
|
|
|
@ -84,6 +84,7 @@ class AccountsControllerTest < ActionDispatch::IntegrationTest
|
||||||
assert_difference [ "Account.count", "Account::Valuation.count", "Account::Entry.count" ], 1 do
|
assert_difference [ "Account.count", "Account::Valuation.count", "Account::Entry.count" ], 1 do
|
||||||
post accounts_path, params: {
|
post accounts_path, params: {
|
||||||
account: {
|
account: {
|
||||||
|
name: "Test",
|
||||||
accountable_type: "Depository",
|
accountable_type: "Depository",
|
||||||
balance: 200,
|
balance: 200,
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
|
@ -101,6 +102,7 @@ class AccountsControllerTest < ActionDispatch::IntegrationTest
|
||||||
assert_difference -> { Account.count } => 1, -> { Account::Valuation.count } => 2 do
|
assert_difference -> { Account.count } => 1, -> { Account::Valuation.count } => 2 do
|
||||||
post accounts_path, params: {
|
post accounts_path, params: {
|
||||||
account: {
|
account: {
|
||||||
|
name: "Test",
|
||||||
accountable_type: "Depository",
|
accountable_type: "Depository",
|
||||||
balance: 200,
|
balance: 200,
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
|
|
|
@ -88,7 +88,7 @@ class TransactionsControllerTest < ActionDispatch::IntegrationTest
|
||||||
test "transaction count represents filtered total" do
|
test "transaction count represents filtered total" do
|
||||||
family = families(:empty)
|
family = families(:empty)
|
||||||
sign_in family.users.first
|
sign_in family.users.first
|
||||||
account = family.accounts.create! name: "Test", balance: 0, accountable: Depository.new
|
account = family.accounts.create! name: "Test", balance: 0, currency: "USD", accountable: Depository.new
|
||||||
|
|
||||||
3.times do
|
3.times do
|
||||||
create_transaction(account: account)
|
create_transaction(account: account)
|
||||||
|
@ -110,7 +110,7 @@ class TransactionsControllerTest < ActionDispatch::IntegrationTest
|
||||||
test "can paginate" do
|
test "can paginate" do
|
||||||
family = families(:empty)
|
family = families(:empty)
|
||||||
sign_in family.users.first
|
sign_in family.users.first
|
||||||
account = family.accounts.create! name: "Test", balance: 0, accountable: Depository.new
|
account = family.accounts.create! name: "Test", balance: 0, currency: "USD", accountable: Depository.new
|
||||||
|
|
||||||
11.times do
|
11.times do
|
||||||
create_transaction(account: account)
|
create_transaction(account: account)
|
||||||
|
|
|
@ -48,7 +48,7 @@ class Account::EntryTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
test "can search entries" do
|
test "can search entries" do
|
||||||
family = families(:empty)
|
family = families(:empty)
|
||||||
account = family.accounts.create! name: "Test", balance: 0, accountable: Depository.new
|
account = family.accounts.create! name: "Test", balance: 0, currency: "USD", accountable: Depository.new
|
||||||
category = family.categories.first
|
category = family.categories.first
|
||||||
merchant = family.merchants.first
|
merchant = family.merchants.first
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ class Account::EntryTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
test "can calculate total spending for a group of transactions" do
|
test "can calculate total spending for a group of transactions" do
|
||||||
family = families(:empty)
|
family = families(:empty)
|
||||||
account = family.accounts.create! name: "Test", balance: 0, accountable: Depository.new
|
account = family.accounts.create! name: "Test", balance: 0, currency: "USD", accountable: Depository.new
|
||||||
create_transaction(account: account, amount: 100)
|
create_transaction(account: account, amount: 100)
|
||||||
create_transaction(account: account, amount: 100)
|
create_transaction(account: account, amount: 100)
|
||||||
create_transaction(account: account, amount: -500) # income, will be ignored
|
create_transaction(account: account, amount: -500) # income, will be ignored
|
||||||
|
@ -80,7 +80,7 @@ class Account::EntryTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
test "can calculate total income for a group of transactions" do
|
test "can calculate total income for a group of transactions" do
|
||||||
family = families(:empty)
|
family = families(:empty)
|
||||||
account = family.accounts.create! name: "Test", balance: 0, accountable: Depository.new
|
account = family.accounts.create! name: "Test", balance: 0, currency: "USD", accountable: Depository.new
|
||||||
create_transaction(account: account, amount: -100)
|
create_transaction(account: account, amount: -100)
|
||||||
create_transaction(account: account, amount: -100)
|
create_transaction(account: account, amount: -100)
|
||||||
create_transaction(account: account, amount: 500) # income, will be ignored
|
create_transaction(account: account, amount: 500) # income, will be ignored
|
||||||
|
@ -95,7 +95,7 @@ class Account::EntryTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
test "cannot sell more shares of stock than owned" do
|
test "cannot sell more shares of stock than owned" do
|
||||||
account = families(:empty).accounts.create! name: "Test", balance: 0, accountable: Investment.new
|
account = families(:empty).accounts.create! name: "Test", balance: 0, currency: "USD", accountable: Investment.new
|
||||||
security = securities(:aapl)
|
security = securities(:aapl)
|
||||||
|
|
||||||
error = assert_raises ActiveRecord::RecordInvalid do
|
error = assert_raises ActiveRecord::RecordInvalid do
|
||||||
|
|
|
@ -11,9 +11,9 @@ class FamilyTest < ActiveSupport::TestCase
|
||||||
test "calculates assets" do
|
test "calculates assets" do
|
||||||
assert_equal Money.new(0, @family.currency), @family.assets
|
assert_equal Money.new(0, @family.currency), @family.assets
|
||||||
|
|
||||||
@family.accounts.create!(balance: 1000, accountable: Depository.new)
|
create_account(balance: 1000, accountable: Depository.new)
|
||||||
@family.accounts.create!(balance: 5000, accountable: OtherAsset.new)
|
create_account(balance: 5000, accountable: OtherAsset.new)
|
||||||
@family.accounts.create!(balance: 10000, accountable: CreditCard.new) # ignored
|
create_account(balance: 10000, accountable: CreditCard.new) # ignored
|
||||||
|
|
||||||
assert_equal Money.new(1000 + 5000, @family.currency), @family.assets
|
assert_equal Money.new(1000 + 5000, @family.currency), @family.assets
|
||||||
end
|
end
|
||||||
|
@ -21,9 +21,9 @@ class FamilyTest < ActiveSupport::TestCase
|
||||||
test "calculates liabilities" do
|
test "calculates liabilities" do
|
||||||
assert_equal Money.new(0, @family.currency), @family.liabilities
|
assert_equal Money.new(0, @family.currency), @family.liabilities
|
||||||
|
|
||||||
@family.accounts.create!(balance: 1000, accountable: CreditCard.new)
|
create_account(balance: 1000, accountable: CreditCard.new)
|
||||||
@family.accounts.create!(balance: 5000, accountable: OtherLiability.new)
|
create_account(balance: 5000, accountable: OtherLiability.new)
|
||||||
@family.accounts.create!(balance: 10000, accountable: Depository.new) # ignored
|
create_account(balance: 10000, accountable: Depository.new) # ignored
|
||||||
|
|
||||||
assert_equal Money.new(1000 + 5000, @family.currency), @family.liabilities
|
assert_equal Money.new(1000 + 5000, @family.currency), @family.liabilities
|
||||||
end
|
end
|
||||||
|
@ -31,15 +31,15 @@ class FamilyTest < ActiveSupport::TestCase
|
||||||
test "calculates net worth" do
|
test "calculates net worth" do
|
||||||
assert_equal Money.new(0, @family.currency), @family.net_worth
|
assert_equal Money.new(0, @family.currency), @family.net_worth
|
||||||
|
|
||||||
@family.accounts.create!(balance: 1000, accountable: CreditCard.new)
|
create_account(balance: 1000, accountable: CreditCard.new)
|
||||||
@family.accounts.create!(balance: 50000, accountable: Depository.new)
|
create_account(balance: 50000, accountable: Depository.new)
|
||||||
|
|
||||||
assert_equal Money.new(50000 - 1000, @family.currency), @family.net_worth
|
assert_equal Money.new(50000 - 1000, @family.currency), @family.net_worth
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should exclude disabled accounts from calculations" do
|
test "should exclude disabled accounts from calculations" do
|
||||||
cc = @family.accounts.create!(balance: 1000, accountable: CreditCard.new)
|
cc = create_account(balance: 1000, accountable: CreditCard.new)
|
||||||
@family.accounts.create!(balance: 50000, accountable: Depository.new)
|
create_account(balance: 50000, accountable: Depository.new)
|
||||||
|
|
||||||
assert_equal Money.new(50000 - 1000, @family.currency), @family.net_worth
|
assert_equal Money.new(50000 - 1000, @family.currency), @family.net_worth
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ class FamilyTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
test "syncs active accounts" do
|
test "syncs active accounts" do
|
||||||
account = @family.accounts.create!(balance: 1000, accountable: CreditCard.new, is_active: false)
|
account = create_account(balance: 1000, accountable: CreditCard.new, is_active: false)
|
||||||
|
|
||||||
Account.any_instance.expects(:sync_later).never
|
Account.any_instance.expects(:sync_later).never
|
||||||
|
|
||||||
|
@ -63,8 +63,8 @@ class FamilyTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
test "calculates snapshot" do
|
test "calculates snapshot" do
|
||||||
asset = @family.accounts.create!(balance: 500, accountable: Depository.new)
|
asset = create_account(balance: 500, accountable: Depository.new)
|
||||||
liability = @family.accounts.create!(balance: 100, accountable: CreditCard.new)
|
liability = create_account(balance: 100, accountable: CreditCard.new)
|
||||||
|
|
||||||
asset.balances.create! date: 1.day.ago.to_date, currency: "USD", balance: 450
|
asset.balances.create! date: 1.day.ago.to_date, currency: "USD", balance: 450
|
||||||
asset.balances.create! date: Date.current, currency: "USD", balance: 500
|
asset.balances.create! date: Date.current, currency: "USD", balance: 500
|
||||||
|
@ -93,8 +93,8 @@ class FamilyTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
test "calculates top movers" do
|
test "calculates top movers" do
|
||||||
checking_account = @family.accounts.create!(balance: 500, accountable: Depository.new)
|
checking_account = create_account(balance: 500, accountable: Depository.new)
|
||||||
savings_account = @family.accounts.create!(balance: 1000, accountable: Depository.new)
|
savings_account = create_account(balance: 1000, accountable: Depository.new)
|
||||||
|
|
||||||
create_transaction(account: checking_account, date: 2.days.ago.to_date, amount: -1000)
|
create_transaction(account: checking_account, date: 2.days.ago.to_date, amount: -1000)
|
||||||
create_transaction(account: checking_account, date: 1.day.ago.to_date, amount: 10)
|
create_transaction(account: checking_account, date: 1.day.ago.to_date, amount: 10)
|
||||||
|
@ -115,7 +115,7 @@ class FamilyTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
test "calculates rolling transaction totals" do
|
test "calculates rolling transaction totals" do
|
||||||
account = @family.accounts.create!(balance: 1000, accountable: Depository.new)
|
account = create_account(balance: 1000, accountable: Depository.new)
|
||||||
create_transaction(account: account, date: 2.days.ago.to_date, amount: -500)
|
create_transaction(account: account, date: 2.days.ago.to_date, amount: -500)
|
||||||
create_transaction(account: account, date: 1.day.ago.to_date, amount: 100)
|
create_transaction(account: account, date: 1.day.ago.to_date, amount: 100)
|
||||||
create_transaction(account: account, date: Date.current, amount: 20)
|
create_transaction(account: account, date: Date.current, amount: 20)
|
||||||
|
@ -146,4 +146,11 @@ class FamilyTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
assert_equal expected_savings_rate_series, snapshot[:savings_rate_series].values.map(&:value).map { |v| v.round(2) }
|
assert_equal expected_savings_rate_series, snapshot[:savings_rate_series].values.map(&:value).map { |v| v.round(2) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def create_account(attributes = {})
|
||||||
|
account = @family.accounts.create! name: "Test", currency: "USD", **attributes
|
||||||
|
account
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue