chore: init commit
in worker.../repo/GITFOLDER.zip is the .git folder.
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "test_helper"
|
||||
|
||||
class PortfolioTest < ActiveSupport::TestCase
|
||||
test "factory" do
|
||||
assert build(:portfolio).validate!
|
||||
end
|
||||
|
||||
test "#cash_balance" do
|
||||
portfolio = create(:portfolio)
|
||||
user = portfolio.user
|
||||
|
||||
# should increase cash_balance
|
||||
create(:portfolio_transaction, :deposit, portfolio: portfolio, amount_cents: 10_00)
|
||||
|
||||
stock = create(:stock, price_cents: 100)
|
||||
|
||||
# This simulates previous completed purchases
|
||||
create(:portfolio_stock, portfolio: portfolio, stock: stock, shares: 20, purchase_price: 100)
|
||||
|
||||
# pending debit for stock purchase, should decrease cash_balance
|
||||
# -$2.00 - $1.00 fee = -$3.00
|
||||
create(:order, :pending, :buy, stock: stock, shares: 2, user: user)
|
||||
|
||||
# pending credit for stock sale, should NOT affect cash_balance
|
||||
create(:order, :pending, :sell, stock:, shares: 3, user:)
|
||||
|
||||
# canceled debit for stock purchase, should NOT affect cash_balance
|
||||
create(:order, :canceled, :buy, stock:, shares: 1, user:)
|
||||
|
||||
# canceled credit for stock sale, should NOT affect cash_balance
|
||||
create(:order, :canceled, :sell, stock:, shares: 4, user:)
|
||||
|
||||
# successful completed stock purchase, should decrease cash_balance
|
||||
# -$5.00
|
||||
buy_order = create(:order, :completed, :buy, stock: stock, shares: 5, user: user)
|
||||
create(
|
||||
:portfolio_transaction, :debit, portfolio: portfolio, amount_cents: 5_00,
|
||||
order: buy_order
|
||||
)
|
||||
create(:portfolio_stock, portfolio: portfolio, stock: stock, shares: 5, purchase_price: 100)
|
||||
|
||||
# successful completed stock sale, should increase cash_balance
|
||||
# # +$6.00
|
||||
sell_order = create(:order, :completed, :sell, stock: stock, shares: 6, user: user)
|
||||
create(
|
||||
:portfolio_transaction, :credit, portfolio: portfolio, amount_cents: 6_00,
|
||||
order: sell_order
|
||||
)
|
||||
create(:portfolio_stock, portfolio: portfolio, stock: stock, shares: -6, purchase_price: 100)
|
||||
|
||||
# withdrawal from the account, should decrease cash_balance
|
||||
create(:portfolio_transaction, :withdrawal, portfolio:, amount_cents: 2_00) # -$2.00
|
||||
|
||||
# fee, should decrease cash_balance
|
||||
# -$1.00
|
||||
create(:portfolio_transaction, :fee, portfolio:, amount_cents: 1_00)
|
||||
|
||||
# expected balance = (10.00 - 3.00 - 5.00 + 6.00 - 2.00 - 1.00) = 5.00
|
||||
result = portfolio.cash_balance
|
||||
assert_equal 5.0, result
|
||||
end
|
||||
|
||||
test "#shares_owned with single purchase" do
|
||||
portfolio = create(:portfolio)
|
||||
stock = create(:stock)
|
||||
create(:portfolio_stock, portfolio: portfolio, stock: stock, shares: 15, purchase_price: 200.0)
|
||||
|
||||
result = portfolio.shares_owned(stock.id)
|
||||
assert_equal 15, result
|
||||
end
|
||||
|
||||
test "#shares_owned with multiple purchases aggregates correctly" do
|
||||
portfolio = create(:portfolio)
|
||||
stock = create(:stock)
|
||||
|
||||
create(:portfolio_stock, portfolio: portfolio, stock: stock, shares: 10, purchase_price: 200.0)
|
||||
create(:portfolio_stock, portfolio: portfolio, stock: stock, shares: 5, purchase_price: 250.0)
|
||||
create(:portfolio_stock, portfolio: portfolio, stock: stock, shares: 3, purchase_price: 300.0)
|
||||
|
||||
result = portfolio.shares_owned(stock.id)
|
||||
assert_equal 18, result # 10 + 5 + 3
|
||||
end
|
||||
|
||||
test "#cash_balance with transactions without orders" do
|
||||
portfolio = create(:portfolio)
|
||||
create(:portfolio_transaction, :credit, portfolio: portfolio, amount_cents: 10_00)
|
||||
create(:portfolio_transaction, :debit, portfolio: portfolio, amount_cents: 5_00)
|
||||
|
||||
create(:portfolio_transaction, :deposit, portfolio: portfolio, amount_cents: 20_00)
|
||||
# expected balance = (2000 + 1000 - 500) / 100.0 = 25.0
|
||||
result = portfolio.cash_balance
|
||||
assert_equal 25.0, result
|
||||
end
|
||||
|
||||
test "#shares_owned with buy and sell orders" do
|
||||
portfolio = create(:portfolio)
|
||||
stock = create(:stock)
|
||||
|
||||
create(:portfolio_stock, portfolio: portfolio, stock: stock, shares: 20, purchase_price: 200.0)
|
||||
create(:portfolio_stock, portfolio: portfolio, stock: stock, shares: -7, purchase_price: 250.0)
|
||||
create(:portfolio_stock, portfolio: portfolio, stock: stock, shares: 3, purchase_price: 300.0)
|
||||
|
||||
result = portfolio.shares_owned(stock.id)
|
||||
assert_equal 16, result # 20 - 7 + 3
|
||||
end
|
||||
|
||||
test "#shares_owned returns 0 when no shares owned" do
|
||||
portfolio = create(:portfolio)
|
||||
stock = create(:stock)
|
||||
|
||||
result = portfolio.shares_owned(stock.id)
|
||||
assert_equal 0, result
|
||||
end
|
||||
|
||||
test "#shares_owned with different stocks" do
|
||||
portfolio = create(:portfolio)
|
||||
stock1 = create(:stock)
|
||||
stock2 = create(:stock)
|
||||
|
||||
create(:portfolio_stock, portfolio: portfolio, stock: stock1, shares: 10, purchase_price: 200.0)
|
||||
create(:portfolio_stock, portfolio: portfolio, stock: stock2, shares: 5, purchase_price: 300.0)
|
||||
|
||||
assert_equal 10, portfolio.shares_owned(stock1.id)
|
||||
assert_equal 5, portfolio.shares_owned(stock2.id)
|
||||
end
|
||||
|
||||
test "#holdings_value_cents calculates stock holdings value" do
|
||||
portfolio = create(:portfolio)
|
||||
stock1 = create(:stock, price_cents: 10_000)
|
||||
stock2 = create(:stock, price_cents: 20_000)
|
||||
|
||||
create(:portfolio_stock, portfolio: portfolio, stock: stock1, shares: 5)
|
||||
create(:portfolio_stock, portfolio: portfolio, stock: stock2, shares: 3)
|
||||
|
||||
expected_value = (5 * 10_000) + (3 * 20_000)
|
||||
assert_equal expected_value, portfolio.holdings_value_cents
|
||||
end
|
||||
|
||||
test "#calculate_total_value_cents includes cash and stock holdings" do
|
||||
portfolio = create(:portfolio)
|
||||
create(:portfolio_transaction, :deposit, portfolio: portfolio, amount_cents: 50_000)
|
||||
|
||||
stock = create(:stock, price_cents: 10_000)
|
||||
create(:portfolio_stock, portfolio: portfolio, stock: stock, shares: 10)
|
||||
|
||||
expected_value = 50_000 + (10 * 10_000)
|
||||
assert_equal expected_value, portfolio.calculate_total_value_cents
|
||||
end
|
||||
|
||||
test "#calculate_total_value converts cents to dollars" do
|
||||
portfolio = create(:portfolio)
|
||||
create(:portfolio_transaction, :deposit, portfolio: portfolio, amount_cents: 50_000)
|
||||
|
||||
assert_equal 500.0, portfolio.calculate_total_value
|
||||
end
|
||||
|
||||
test "#chart_data returns empty array when no snapshots exist" do
|
||||
portfolio = create(:portfolio)
|
||||
|
||||
result = portfolio.chart_data
|
||||
assert_equal [], result
|
||||
end
|
||||
|
||||
test "#chart_data returns formatted data for single snapshot" do
|
||||
portfolio = create(:portfolio)
|
||||
create(:portfolio_snapshot, portfolio: portfolio, date: Date.new(2025, 1, 1), worth_cents: 10_000)
|
||||
|
||||
result = portfolio.chart_data
|
||||
assert_equal 1, result.length
|
||||
assert_equal "Jan 2025", result.first[:label]
|
||||
assert_equal 100.0, result.first[:value]
|
||||
end
|
||||
|
||||
test "#chart_data returns last 12 snapshots in chronological order" do
|
||||
portfolio = create(:portfolio)
|
||||
|
||||
15.times do |i|
|
||||
create(
|
||||
:portfolio_snapshot,
|
||||
portfolio: portfolio,
|
||||
date: (14 - i).months.ago.beginning_of_month.to_date,
|
||||
worth_cents: (100 + (i * 10)) * 100
|
||||
)
|
||||
end
|
||||
|
||||
result = portfolio.chart_data
|
||||
assert_equal 12, result.length
|
||||
end
|
||||
|
||||
test "#chart_data formats dates as 'Mon YYYY'" do
|
||||
portfolio = create(:portfolio)
|
||||
create(:portfolio_snapshot, portfolio: portfolio, date: Date.new(2025, 3, 15), worth_cents: 15_000)
|
||||
create(:portfolio_snapshot, portfolio: portfolio, date: Date.new(2024, 12, 1), worth_cents: 20_000)
|
||||
|
||||
result = portfolio.chart_data
|
||||
assert_equal(["Dec 2024", "Mar 2025"], result.pluck(:label))
|
||||
end
|
||||
|
||||
test "#chart_data converts worth_cents to dollars" do
|
||||
portfolio = create(:portfolio)
|
||||
create(:portfolio_snapshot, portfolio: portfolio, date: Date.current, worth_cents: 123_456)
|
||||
|
||||
result = portfolio.chart_data
|
||||
assert_equal 1234.56, result.first[:value]
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user