Files
sure/test/models/market_data_importer_test.rb
soky srm be42988adf Add throttling and cross-rate for twelve data (#1396)
* Add throttling and cross-rate for twelve data

* FIX yahoo precision also

* FIXES

* Update importer.rb

* Fixes

* Revert job

* Fixes
2026-04-07 20:46:05 +02:00

93 lines
3.5 KiB
Ruby

require "test_helper"
require "ostruct"
class MarketDataImporterTest < ActiveSupport::TestCase
include ProviderTestHelper
SNAPSHOT_START_DATE = MarketDataImporter::SNAPSHOT_DAYS.days.ago.to_date
SECURITY_PRICE_BUFFER = Security::Price::Importer::PROVISIONAL_LOOKBACK_DAYS.days
EXCHANGE_RATE_BUFFER = 5.days
setup do
Security::Price.delete_all
ExchangeRate.delete_all
Trade.delete_all
Holding.delete_all
Security.delete_all
@provider = mock("provider")
Provider::Registry.any_instance
.stubs(:get_provider)
.with(:twelve_data)
.returns(@provider)
end
test "syncs required exchange rates" do
family = Family.create!(name: "Smith", currency: "USD")
family.accounts.create!(name: "Chequing",
currency: "CAD",
balance: 100,
accountable: Depository.new)
# Seed stale rate so only the next missing day is fetched
ExchangeRate.create!(from_currency: "CAD",
to_currency: "USD",
date: SNAPSHOT_START_DATE,
rate: 2.0)
ExchangeRate.create!(from_currency: "USD",
to_currency: "CAD",
date: SNAPSHOT_START_DATE,
rate: 0.5)
expected_start_date = (SNAPSHOT_START_DATE + 1.day) - EXCHANGE_RATE_BUFFER
end_date = Date.current.in_time_zone("America/New_York").to_date
# Only the forward pair (CAD→USD) should be fetched; inverse (USD→CAD) is computed automatically
@provider.expects(:fetch_exchange_rates)
.with(from: "CAD",
to: "USD",
start_date: expected_start_date,
end_date: end_date)
.returns(provider_success_response([
OpenStruct.new(from: "CAD", to: "USD", date: SNAPSHOT_START_DATE, rate: 1.5)
]))
before = ExchangeRate.count
MarketDataImporter.new(mode: :snapshot).import_exchange_rates
after = ExchangeRate.count
assert_operator after, :>, before + 1, "Should insert at least two new exchange-rate rows (forward + computed inverse)"
end
test "syncs security prices" do
security = Security.create!(ticker: "AAPL", exchange_operating_mic: "XNAS")
expected_start_date = SNAPSHOT_START_DATE - SECURITY_PRICE_BUFFER
end_date = Date.current.in_time_zone("America/New_York").to_date
@provider.expects(:fetch_security_prices)
.with(symbol: security.ticker,
exchange_operating_mic: security.exchange_operating_mic,
start_date: expected_start_date,
end_date: end_date)
.returns(provider_success_response([
OpenStruct.new(security: security,
date: SNAPSHOT_START_DATE,
price: 100,
currency: "USD")
]))
@provider.stubs(:fetch_security_info)
.with(symbol: "AAPL", exchange_operating_mic: "XNAS")
.returns(provider_success_response(OpenStruct.new(name: "Apple", logo_url: "logo")))
# Ignore exchange rate calls for this test
@provider.stubs(:fetch_exchange_rates).returns(provider_success_response([]))
MarketDataImporter.new(mode: :snapshot).import_security_prices
assert_equal 1, Security::Price.where(security: security, date: SNAPSHOT_START_DATE).count
end
end