Testing Account Trade Operations in maybe-finance
This test suite validates the functionality of trade operations in a financial application, covering various transaction types including trades, deposits, withdrawals, and interest calculations. The tests ensure proper handling of account entries, transactions, and trade operations.
Test Coverage Overview
Implementation Analysis
Technical Details
Best Practices Demonstrated
maybe-finance/maybe
test/controllers/account/trades_controller_test.rb
require "test_helper"
class Account::TradesControllerTest < ActionDispatch::IntegrationTest
include EntryableResourceInterfaceTest
setup do
sign_in @user = users(:family_admin)
@entry = account_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: {
currency: "USD",
entryable_attributes: {
id: @entry.entryable_id,
qty: 20,
price: 20
}
}
}
end
@entry.reload
assert_enqueued_with job: SyncJob
assert_equal 20, @entry.account_trade.qty
assert_equal 20, @entry.account_trade.price
assert_equal "USD", @entry.currency
assert_redirected_to account_url(@entry.account)
end
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,
-> { Account::Transfer.count } => 1 do
post account_trades_url, params: {
account_entry: {
account_id: @entry.account_id,
type: "deposit",
date: Date.current,
amount: 10,
currency: "USD",
transfer_account_id: from_account.id
}
}
end
assert_redirected_to @entry.account
end
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,
-> { Account::Transfer.count } => 1 do
post account_trades_url, params: {
account_entry: {
account_id: @entry.account_id,
type: "withdrawal",
date: Date.current,
amount: 10,
currency: "USD",
transfer_account_id: to_account.id
}
}
end
assert_redirected_to @entry.account
end
test "deposit and withdrawal has optional transfer account" do
assert_difference -> { Account::Entry.count } => 1,
-> { Account::Transaction.count } => 1,
-> { Account::Transfer.count } => 0 do
post account_trades_url, params: {
account_entry: {
account_id: @entry.account_id,
type: "withdrawal",
date: Date.current,
amount: 10,
currency: "USD"
}
}
end
created_entry = Account::Entry.order(created_at: :desc).first
assert created_entry.amount.positive?
assert created_entry.marked_as_transfer
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: {
account_id: @entry.account_id,
type: "interest",
date: Date.current,
amount: 10,
currency: "USD"
}
}
end
created_entry = Account::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: {
account_id: @entry.account_id,
type: "buy",
date: Date.current,
ticker: "NVDA (NASDAQ)",
qty: 10,
price: 10,
currency: "USD"
}
}
end
created_entry = Account::Entry.order(created_at: :desc).first
assert created_entry.amount.positive?
assert created_entry.account_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: {
account_id: @entry.account_id,
type: "sell",
ticker: "AAPL (NYSE)",
date: Date.current,
currency: "USD",
qty: 10,
price: 10
}
}
end
created_entry = Account::Entry.order(created_at: :desc).first
assert created_entry.amount.negative?
assert created_entry.account_trade.qty.negative?
assert_equal "Entry created", flash[:notice]
assert_enqueued_with job: SyncJob
assert_redirected_to account_url(created_entry.account)
end
end