chore: init commit

in worker.../repo/GITFOLDER.zip is the .git folder.
This commit is contained in:
2026-08-11 14:44:09 -04:00
parent 0012380fd3
commit 2854619bc9
782 changed files with 65944 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
# frozen_string_literal: true
require "test_helper"
class MonthlyPortfolioSnapshotJobTest < ActiveJob::TestCase
setup do
@user = create(:student)
@portfolio = @user.portfolio
@target_date = Date.new(2024, 12, 1)
end
test "creates snapshot calculating cash and stock holdings" do
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)
assert_difference("PortfolioSnapshot.count", 1) do
MonthlyPortfolioSnapshotJob.perform_now(@target_date)
end
snapshot = @portfolio.portfolio_snapshots.find_by(date: @target_date)
expected_value = @portfolio.calculate_total_value_cents
assert_equal expected_value, snapshot.worth_cents
end
test "handles empty portfolio database" do
Portfolio.delete_all
assert_no_difference("PortfolioSnapshot.count") do
MonthlyPortfolioSnapshotJob.perform_now(@target_date)
end
end
test "skips existing snapshots" do
create(:portfolio_snapshot, portfolio: @portfolio, date: @target_date)
assert_no_difference("PortfolioSnapshot.count") do
MonthlyPortfolioSnapshotJob.perform_now(@target_date)
end
end
end

View File

@@ -0,0 +1,53 @@
# frozen_string_literal: true
require "test_helper"
class OrderExecutionJobTest < ActiveJob::TestCase
test "with pending orders" do
portfolio1 = create(:portfolio)
student1 = create(:student, portfolio: portfolio1)
create(
:portfolio_transaction,
:deposit,
portfolio: portfolio1,
amount_cents: 10_000
)
portfolio2 = create(:portfolio)
student2 = create(:student, portfolio: portfolio2)
create(
:portfolio_transaction,
:deposit,
portfolio: portfolio2,
amount_cents: 10_000
)
stock = create(:stock, price_cents: 1_000)
order1 = create(:order, :pending, :buy, user: student1, stock:, shares: 1)
order2 = create(:order, :pending, :buy, user: student2, stock:, shares: 2)
ExecuteOrder.expects(:execute).with(order1).once
ExecuteOrder.expects(:execute).with(order2).once
TransactionFeeProcessor.expects(:execute).once
OrderExecutionJob.perform_now
end
test "with no pending orders" do
ExecuteOrder.expects(:execute).never
TransactionFeeProcessor.expects(:execute).never
OrderExecutionJob.perform_now
end
test "when an error occurs" do
portfolio = create(:portfolio)
student = create(:student, portfolio:)
create(:portfolio_transaction, :deposit, portfolio:, amount_cents: 10_000)
stock = create(:stock, price_cents: 1_000)
create(:order, :pending, :buy, user: student, stock:, shares: 1)
ExecuteOrder.stubs(:execute).raises(StandardError.new("Test error"))
assert_raises(StandardError) do
OrderExecutionJob.perform_now
end
end
end

View File

@@ -0,0 +1,74 @@
# frozen_string_literal: true
require "test_helper"
class StockAttributeUpdateJobTest < ActiveJob::TestCase
test "processes all stocks in the database" do
stock1 = create(:stock, ticker: "STOCK1")
stock2 = create(:stock, ticker: "STOCK2")
stock3 = create(:stock, ticker: "STOCK3")
Net::HTTP.expects(:get).times(3).returns(
{ "Symbol" => "STOCK1", "Name" => "Company 1" }.to_json,
{ "Symbol" => "STOCK2", "Name" => "Company 2" }.to_json,
{ "Symbol" => "STOCK3", "Name" => "Company 3" }.to_json
)
StockAttributeUpdateJob.perform_now
stock1.reload
stock2.reload
stock3.reload
assert_equal "Company 1", stock1.company_name
assert_equal "Company 2", stock2.company_name
assert_equal "Company 3", stock3.company_name
end
test "handles stocks with invalid API responses" do
stock1 = create(:stock, ticker: "VALID")
stock2 = create(:stock, ticker: "INVALID")
original_name = stock2.company_name
Net::HTTP.expects(:get).times(2).returns(
{ "Symbol" => "VALID", "Name" => "Valid Company" }.to_json,
"{}"
)
StockAttributeUpdateJob.perform_now
stock1.reload
stock2.reload
assert_equal "Valid Company", stock1.company_name
assert_equal original_name, stock2.company_name
end
test "skips stocks without ticker" do
stock_with_ticker = create(:stock, ticker: "HAS_TICKER")
stock_without_ticker = Stock.new(description: "Test stock")
stock_without_ticker.save(validate: false)
Net::HTTP.expects(:get).once.returns(
{ "Symbol" => "HAS_TICKER", "Name" => "Has Ticker Company" }.to_json
)
StockAttributeUpdateJob.perform_now
stock_with_ticker.reload
stock_without_ticker.reload
assert_equal "Has Ticker Company", stock_with_ticker.company_name
assert_nil stock_without_ticker.company_name
end
test "handles empty stock table" do
Stock.delete_all
Net::HTTP.expects(:get).never
assert_nothing_raised do
StockAttributeUpdateJob.perform_now
end
end
end

View File

@@ -0,0 +1,125 @@
# frozen_string_literal: true
require "test_helper"
class StockPricesUpdateJobTest < ActiveJob::TestCase
STOCK_URL_MATCHER = %r{https://www\.alphavantage\.co/query\?apikey=[^&]+&function=GLOBAL_QUOTE&symbol=[A-Z]+}
setup do
ENV["ALPHA_VANTAGE_API_KEY"] = "test_api_key"
@last_trading_date = Date.parse("2024-05-31")
stub_request(:get, STOCK_URL_MATCHER)
.with(
headers: {
"Accept" => "*/*",
"Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
"Host" => "www.alphavantage.co",
"User-Agent" => "Ruby"
}
)
.to_return(status: 200, body: Rails.root.join("./test/data/global_quote_f.json").open)
end
test "makes API calls" do
create(:stock, ticker: "AAPL")
create(:stock, ticker: "KO")
StockPricesUpdateJob.perform_now
assert_requested :get, STOCK_URL_MATCHER, times: 2
end
test "updates existing Stock records" do
stock1 = create(:stock, ticker: "AAPL", price_cents: 0)
stock2 = create(:stock, ticker: "KO", price_cents: 0)
assert_no_difference("Stock.count") do
StockPricesUpdateJob.perform_now
end
stock1.reload
stock2.reload
assert stock1.price_cents.positive?
assert stock2.price_cents.positive?
end
test "sets Stock ticker and price" do
test_tickers = %w[AAPL KO DIS]
test_tickers.each { |ticker| create(:stock, ticker: ticker, price_cents: 0) }
StockPricesUpdateJob.perform_now
test_tickers.each do |ticker|
stock = Stock.find_by(ticker: ticker)
assert stock.present?
assert stock.price_cents.present?
end
end
test "handles empty stock database gracefully" do
# Ensure no stocks exist
Stock.delete_all
assert_no_difference("Stock.count") do
assert_nothing_raised do
StockPricesUpdateJob.perform_now
end
end
assert_not_requested :get, STOCK_URL_MATCHER
end
test "stores current price as yesterday price before updating" do
initial_price = 12_345
stock = create(:stock, ticker: "AAPL", price_cents: initial_price, yesterday_price_cents: nil)
StockPricesUpdateJob.perform_now
stock.reload
assert_equal initial_price, stock.yesterday_price_cents
assert_not_equal initial_price, stock.price_cents
end
test "preserves yesterday price when API call fails" do
initial_price = 12_345
stock = create(:stock, ticker: "AAPL", price_cents: initial_price, yesterday_price_cents: nil)
stub_request(:get, STOCK_URL_MATCHER).to_return(status: 200, body: "{}")
StockPricesUpdateJob.perform_now
stock.reload
assert_equal initial_price, stock.yesterday_price_cents
assert_equal initial_price, stock.price_cents
end
test "stores trading day when updating stock price" do
stock = create(:stock, ticker: "AAPL", price_cents: 10_000, last_trading_day: nil)
StockPricesUpdateJob.perform_now
stock.reload
assert_equal @last_trading_date, stock.last_trading_day
end
test "skips update when trading day hasn't changed" do
initial_price = 10_000
stock = create(:stock, ticker: "AAPL", price_cents: initial_price, last_trading_day: @last_trading_date)
StockPricesUpdateJob.perform_now
stock.reload
assert_equal initial_price, stock.price_cents
assert_equal @last_trading_date, stock.last_trading_day
end
test "updates when trading day is newer" do
prev_trading_date = @last_trading_date - 1.day
stock = create(:stock, ticker: "AAPL", price_cents: 10_000, last_trading_day: prev_trading_date)
StockPricesUpdateJob.perform_now
stock.reload
assert_equal @last_trading_date, stock.last_trading_day
assert stock.price_cents.positive?
end
end