1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-06 22:15:20 +02:00
Maybe/test/models/security/price/importer_test.rb

144 lines
5.1 KiB
Ruby
Raw Permalink Normal View History

require "test_helper"
require "ostruct"
class Security::Price::ImporterTest < ActiveSupport::TestCase
include ProviderTestHelper
setup do
@provider = mock
@security = Security.create!(ticker: "AAPL")
end
test "syncs missing prices from provider" do
Security::Price.delete_all
provider_response = provider_success_response([
OpenStruct.new(security: @security, date: 2.days.ago.to_date, price: 150, currency: "USD"),
OpenStruct.new(security: @security, date: 1.day.ago.to_date, price: 155, currency: "USD"),
OpenStruct.new(security: @security, date: Date.current, price: 160, currency: "USD")
])
@provider.expects(:fetch_security_prices)
.with(symbol: @security.ticker, exchange_operating_mic: @security.exchange_operating_mic,
start_date: get_provider_fetch_start_date(2.days.ago.to_date), end_date: Date.current)
.returns(provider_response)
Security::Price::Importer.new(
security: @security,
security_provider: @provider,
start_date: 2.days.ago.to_date,
end_date: Date.current
).import_provider_prices
db_prices = Security::Price.where(security: @security, date: 2.days.ago.to_date..Date.current).order(:date)
assert_equal 3, db_prices.count
assert_equal [ 150, 155, 160 ], db_prices.map(&:price)
end
test "syncs diff when some prices already exist" do
Security::Price.delete_all
# Pre-populate DB with first two days
Security::Price.create!(security: @security, date: 3.days.ago.to_date, price: 140, currency: "USD")
Security::Price.create!(security: @security, date: 2.days.ago.to_date, price: 145, currency: "USD")
provider_response = provider_success_response([
OpenStruct.new(security: @security, date: 1.day.ago.to_date, price: 150, currency: "USD")
])
@provider.expects(:fetch_security_prices)
.with(symbol: @security.ticker, exchange_operating_mic: @security.exchange_operating_mic,
start_date: get_provider_fetch_start_date(1.day.ago.to_date), end_date: Date.current)
.returns(provider_response)
Security::Price::Importer.new(
security: @security,
security_provider: @provider,
start_date: 3.days.ago.to_date,
end_date: Date.current
).import_provider_prices
db_prices = Security::Price.where(security: @security).order(:date)
assert_equal 4, db_prices.count
assert_equal [ 140, 145, 150, 150 ], db_prices.map(&:price)
end
test "no provider calls when all prices exist" do
Security::Price.delete_all
(3.days.ago.to_date..Date.current).each_with_index do |date, idx|
Security::Price.create!(security: @security, date:, price: 100 + idx, currency: "USD")
end
@provider.expects(:fetch_security_prices).never
Security::Price::Importer.new(
security: @security,
security_provider: @provider,
start_date: 3.days.ago.to_date,
end_date: Date.current
).import_provider_prices
end
test "full upsert if clear_cache is true" do
Security::Price.delete_all
# Seed DB with stale prices
(2.days.ago.to_date..Date.current).each do |date|
Security::Price.create!(security: @security, date:, price: 100, currency: "USD")
end
provider_response = provider_success_response([
OpenStruct.new(security: @security, date: 2.days.ago.to_date, price: 150, currency: "USD"),
OpenStruct.new(security: @security, date: 1.day.ago.to_date, price: 155, currency: "USD"),
OpenStruct.new(security: @security, date: Date.current, price: 160, currency: "USD")
])
@provider.expects(:fetch_security_prices)
.with(symbol: @security.ticker, exchange_operating_mic: @security.exchange_operating_mic,
start_date: get_provider_fetch_start_date(2.days.ago.to_date), end_date: Date.current)
.returns(provider_response)
Security::Price::Importer.new(
security: @security,
security_provider: @provider,
start_date: 2.days.ago.to_date,
end_date: Date.current,
clear_cache: true
).import_provider_prices
db_prices = Security::Price.where(security: @security).order(:date)
assert_equal [ 150, 155, 160 ], db_prices.map(&:price)
end
test "clamps end_date to today when future date is provided" do
Security::Price.delete_all
future_date = Date.current + 3.days
provider_response = provider_success_response([
OpenStruct.new(security: @security, date: Date.current, price: 165, currency: "USD")
])
@provider.expects(:fetch_security_prices)
.with(symbol: @security.ticker, exchange_operating_mic: @security.exchange_operating_mic,
start_date: get_provider_fetch_start_date(Date.current), end_date: Date.current)
.returns(provider_response)
Security::Price::Importer.new(
security: @security,
security_provider: @provider,
start_date: Date.current,
end_date: future_date
).import_provider_prices
assert_equal 1, Security::Price.count
end
private
def get_provider_fetch_start_date(start_date)
start_date - 5.days
end
end