From 10f255a9a9399064a9bed64dd4b6efa0fc03eaf9 Mon Sep 17 00:00:00 2001 From: Zach Gollwitzer Date: Sat, 17 May 2025 16:37:16 -0400 Subject: [PATCH] Clarify backend data pipeline naming concepts (importers, processors, materializers, calculators, and syncers) (#2255) * Rename MarketDataSyncer to MarketDataImporter * Materializers * Importers * More reference replacements --- ..._data_job.rb => import_market_data_job.rb} | 4 +- app/models/account/market_data_importer.rb | 82 +++++++++++++++++++ app/models/account/market_data_syncer.rb | 82 ------------------- app/models/account/syncer.rb | 12 +-- .../balance/{syncer.rb => materializer.rb} | 10 +-- .../exchange_rate/{syncer.rb => importer.rb} | 4 +- app/models/exchange_rate/provided.rb | 8 +- .../holding/{syncer.rb => materializer.rb} | 6 +- ...data_syncer.rb => market_data_importer.rb} | 24 +++--- .../security/price/{syncer.rb => importer.rb} | 4 +- app/models/security/provided.rb | 12 +-- config/schedule.yml | 6 +- ...r_test.rb => market_data_importer_test.rb} | 8 +- .../{syncer_test.rb => materializer_test.rb} | 8 +- .../{syncer_test.rb => importer_test.rb} | 22 ++--- .../{syncer_test.rb => materializer_test.rb} | 6 +- ...r_test.rb => market_data_importer_test.rb} | 8 +- .../{syncer_test.rb => importer_test.rb} | 22 ++--- 18 files changed, 165 insertions(+), 163 deletions(-) rename app/jobs/{sync_market_data_job.rb => import_market_data_job.rb} (86%) create mode 100644 app/models/account/market_data_importer.rb delete mode 100644 app/models/account/market_data_syncer.rb rename app/models/balance/{syncer.rb => materializer.rb} (89%) rename app/models/exchange_rate/{syncer.rb => importer.rb} (98%) rename app/models/holding/{syncer.rb => materializer.rb} (87%) rename app/models/{market_data_syncer.rb => market_data_importer.rb} (84%) rename app/models/security/price/{syncer.rb => importer.rb} (98%) rename test/models/account/{market_data_syncer_test.rb => market_data_importer_test.rb} (92%) rename test/models/balance/{syncer_test.rb => materializer_test.rb} (82%) rename test/models/exchange_rate/{syncer_test.rb => importer_test.rb} (92%) rename test/models/holding/{syncer_test.rb => materializer_test.rb} (78%) rename test/models/{market_data_syncer_test.rb => market_data_importer_test.rb} (91%) rename test/models/security/price/{syncer_test.rb => importer_test.rb} (92%) diff --git a/app/jobs/sync_market_data_job.rb b/app/jobs/import_market_data_job.rb similarity index 86% rename from app/jobs/sync_market_data_job.rb rename to app/jobs/import_market_data_job.rb index db34a41a..294d5836 100644 --- a/app/jobs/sync_market_data_job.rb +++ b/app/jobs/import_market_data_job.rb @@ -7,7 +7,7 @@ # Each individual account sync will still fetch any missing market data that isn't yet synced, but by running # this job daily, we significantly reduce overlapping account syncs that both need the same market data (e.g. common security like `AAPL`) # -class SyncMarketDataJob < ApplicationJob +class ImportMarketDataJob < ApplicationJob queue_as :scheduled def perform(opts) @@ -15,6 +15,6 @@ class SyncMarketDataJob < ApplicationJob mode = opts.fetch(:mode, :full) clear_cache = opts.fetch(:clear_cache, false) - MarketDataSyncer.new(mode: mode, clear_cache: clear_cache).sync + MarketDataImporter.new(mode: mode, clear_cache: clear_cache).import_all end end diff --git a/app/models/account/market_data_importer.rb b/app/models/account/market_data_importer.rb new file mode 100644 index 00000000..af538314 --- /dev/null +++ b/app/models/account/market_data_importer.rb @@ -0,0 +1,82 @@ +class Account::MarketDataImporter + attr_reader :account + + def initialize(account) + @account = account + end + + def import_all + import_exchange_rates + import_security_prices + end + + def import_exchange_rates + return unless needs_exchange_rates? + return unless ExchangeRate.provider + + pair_dates = {} + + # 1. ENTRY-BASED PAIRS – currencies that differ from the account currency + account.entries + .where.not(currency: account.currency) + .group(:currency) + .minimum(:date) + .each do |source_currency, date| + key = [ source_currency, account.currency ] + pair_dates[key] = [ pair_dates[key], date ].compact.min + end + + # 2. ACCOUNT-BASED PAIR – convert the account currency to the family currency (if different) + if foreign_account? + key = [ account.currency, account.family.currency ] + pair_dates[key] = [ pair_dates[key], account.start_date ].compact.min + end + + pair_dates.each do |(source, target), start_date| + ExchangeRate.import_provider_rates( + from: source, + to: target, + start_date: start_date, + end_date: Date.current + ) + end + end + + def import_security_prices + return unless Security.provider + + account_securities = account.trades.map(&:security).uniq + + return if account_securities.empty? + + account_securities.each do |security| + security.import_provider_prices( + start_date: first_required_price_date(security), + end_date: Date.current + ) + + security.import_provider_details + end + end + + private + # Calculates the first date we require a price for the given security scoped to this account + def first_required_price_date(security) + account.trades.with_entry + .where(security: security) + .where(entries: { account_id: account.id }) + .minimum("entries.date") + end + + def needs_exchange_rates? + has_multi_currency_entries? || foreign_account? + end + + def has_multi_currency_entries? + account.entries.where.not(currency: account.currency).exists? + end + + def foreign_account? + account.currency != account.family.currency + end +end diff --git a/app/models/account/market_data_syncer.rb b/app/models/account/market_data_syncer.rb deleted file mode 100644 index b223d229..00000000 --- a/app/models/account/market_data_syncer.rb +++ /dev/null @@ -1,82 +0,0 @@ -class Account::MarketDataSyncer - attr_reader :account - - def initialize(account) - @account = account - end - - def sync_market_data - sync_exchange_rates - sync_security_prices - end - - private - def sync_exchange_rates - return unless needs_exchange_rates? - return unless ExchangeRate.provider - - pair_dates = {} - - # 1. ENTRY-BASED PAIRS – currencies that differ from the account currency - account.entries - .where.not(currency: account.currency) - .group(:currency) - .minimum(:date) - .each do |source_currency, date| - key = [ source_currency, account.currency ] - pair_dates[key] = [ pair_dates[key], date ].compact.min - end - - # 2. ACCOUNT-BASED PAIR – convert the account currency to the family currency (if different) - if foreign_account? - key = [ account.currency, account.family.currency ] - pair_dates[key] = [ pair_dates[key], account.start_date ].compact.min - end - - pair_dates.each do |(source, target), start_date| - ExchangeRate.sync_provider_rates( - from: source, - to: target, - start_date: start_date, - end_date: Date.current - ) - end - end - - def sync_security_prices - return unless Security.provider - - account_securities = account.trades.map(&:security).uniq - - return if account_securities.empty? - - account_securities.each do |security| - security.sync_provider_prices( - start_date: first_required_price_date(security), - end_date: Date.current - ) - - security.sync_provider_details - end - end - - # Calculates the first date we require a price for the given security scoped to this account - def first_required_price_date(security) - account.trades.with_entry - .where(security: security) - .where(entries: { account_id: account.id }) - .minimum("entries.date") - end - - def needs_exchange_rates? - has_multi_currency_entries? || foreign_account? - end - - def has_multi_currency_entries? - account.entries.where.not(currency: account.currency).exists? - end - - def foreign_account? - account.currency != account.family.currency - end -end diff --git a/app/models/account/syncer.rb b/app/models/account/syncer.rb index de63f5e8..ab198a95 100644 --- a/app/models/account/syncer.rb +++ b/app/models/account/syncer.rb @@ -7,8 +7,8 @@ class Account::Syncer def perform_sync(sync) Rails.logger.info("Processing balances (#{account.linked? ? 'reverse' : 'forward'})") - sync_market_data - sync_balances + import_market_data + materialize_balances end def perform_post_sync @@ -16,9 +16,9 @@ class Account::Syncer end private - def sync_balances + def materialize_balances strategy = account.linked? ? :reverse : :forward - Balance::Syncer.new(account, strategy: strategy).sync_balances + Balance::Materializer.new(account, strategy: strategy).materialize_balances end # Syncs all the exchange rates + security prices this account needs to display historical chart data @@ -28,8 +28,8 @@ class Account::Syncer # # We rescue errors here because if this operation fails, we don't want to fail the entire sync since # we have reasonable fallbacks for missing market data. - def sync_market_data - Account::MarketDataSyncer.new(account).sync_market_data + def import_market_data + Account::MarketDataImporter.new(account).import_all rescue => e Rails.logger.error("Error syncing market data for account #{account.id}: #{e.message}") Sentry.capture_exception(e) diff --git a/app/models/balance/syncer.rb b/app/models/balance/materializer.rb similarity index 89% rename from app/models/balance/syncer.rb rename to app/models/balance/materializer.rb index 890bb5f9..75a98ffd 100644 --- a/app/models/balance/syncer.rb +++ b/app/models/balance/materializer.rb @@ -1,4 +1,4 @@ -class Balance::Syncer +class Balance::Materializer attr_reader :account, :strategy def initialize(account, strategy:) @@ -6,9 +6,9 @@ class Balance::Syncer @strategy = strategy end - def sync_balances + def materialize_balances Balance.transaction do - sync_holdings + materialize_holdings calculate_balances Rails.logger.info("Persisting #{@balances.size} balances") @@ -23,8 +23,8 @@ class Balance::Syncer end private - def sync_holdings - @holdings = Holding::Syncer.new(account, strategy: strategy).sync_holdings + def materialize_holdings + @holdings = Holding::Materializer.new(account, strategy: strategy).materialize_holdings end def update_account_info diff --git a/app/models/exchange_rate/syncer.rb b/app/models/exchange_rate/importer.rb similarity index 98% rename from app/models/exchange_rate/syncer.rb rename to app/models/exchange_rate/importer.rb index a1ee44b5..133106bc 100644 --- a/app/models/exchange_rate/syncer.rb +++ b/app/models/exchange_rate/importer.rb @@ -1,4 +1,4 @@ -class ExchangeRate::Syncer +class ExchangeRate::Importer MissingExchangeRateError = Class.new(StandardError) MissingStartRateError = Class.new(StandardError) @@ -12,7 +12,7 @@ class ExchangeRate::Syncer end # Constructs a daily series of rates for the given currency pair for date range - def sync_provider_rates + def import_provider_rates if !clear_cache && all_rates_exist? Rails.logger.info("No new rates to sync for #{from} to #{to} between #{start_date} and #{end_date}, skipping") return diff --git a/app/models/exchange_rate/provided.rb b/app/models/exchange_rate/provided.rb index 5a1b4c60..defee421 100644 --- a/app/models/exchange_rate/provided.rb +++ b/app/models/exchange_rate/provided.rb @@ -28,20 +28,20 @@ module ExchangeRate::Provided end # @return [Integer] The number of exchange rates synced - def sync_provider_rates(from:, to:, start_date:, end_date:, clear_cache: false) + def import_provider_rates(from:, to:, start_date:, end_date:, clear_cache: false) unless provider.present? - Rails.logger.warn("No provider configured for ExchangeRate.sync_provider_rates") + Rails.logger.warn("No provider configured for ExchangeRate.import_provider_rates") return 0 end - ExchangeRate::Syncer.new( + ExchangeRate::Importer.new( exchange_rate_provider: provider, from: from, to: to, start_date: start_date, end_date: end_date, clear_cache: clear_cache - ).sync_provider_rates + ).import_provider_rates end end end diff --git a/app/models/holding/syncer.rb b/app/models/holding/materializer.rb similarity index 87% rename from app/models/holding/syncer.rb rename to app/models/holding/materializer.rb index 345f2a3f..e4931128 100644 --- a/app/models/holding/syncer.rb +++ b/app/models/holding/materializer.rb @@ -1,10 +1,12 @@ -class Holding::Syncer +# "Materializes" holdings (similar to a DB materialized view, but done at the app level) +# into a series of records we can easily query and join with other data. +class Holding::Materializer def initialize(account, strategy:) @account = account @strategy = strategy end - def sync_holdings + def materialize_holdings calculate_holdings Rails.logger.info("Persisting #{@holdings.size} holdings") diff --git a/app/models/market_data_syncer.rb b/app/models/market_data_importer.rb similarity index 84% rename from app/models/market_data_syncer.rb rename to app/models/market_data_importer.rb index 5567ba31..9eaf5964 100644 --- a/app/models/market_data_syncer.rb +++ b/app/models/market_data_importer.rb @@ -1,4 +1,4 @@ -class MarketDataSyncer +class MarketDataImporter # By default, our graphs show 1M as the view, so by fetching 31 days, # we ensure we can always show an accurate default graph SNAPSHOT_DAYS = 31 @@ -10,32 +10,32 @@ class MarketDataSyncer @clear_cache = clear_cache end - def sync - sync_prices - sync_exchange_rates + def import_all + import_security_prices + import_exchange_rates end # Syncs historical security prices (and details) - def sync_prices + def import_security_prices unless Security.provider - Rails.logger.warn("No provider configured for MarketDataSyncer.sync_prices, skipping sync") + Rails.logger.warn("No provider configured for MarketDataImporter.import_security_prices, skipping sync") return end Security.where.not(exchange_operating_mic: nil).find_each do |security| - security.sync_provider_prices( + security.import_provider_prices( start_date: get_first_required_price_date(security), end_date: end_date, clear_cache: clear_cache ) - security.sync_provider_details(clear_cache: clear_cache) + security.import_provider_details(clear_cache: clear_cache) end end - def sync_exchange_rates + def import_exchange_rates unless ExchangeRate.provider - Rails.logger.warn("No provider configured for MarketDataSyncer.sync_exchange_rates, skipping sync") + Rails.logger.warn("No provider configured for MarketDataImporter.import_exchange_rates, skipping sync") return end @@ -43,7 +43,7 @@ class MarketDataSyncer # pair is a Hash with keys :source, :target, and :start_date start_date = snapshot? ? default_start_date : pair[:start_date] - ExchangeRate.sync_provider_rates( + ExchangeRate.import_provider_rates( from: pair[:source], to: pair[:target], start_date: start_date, @@ -124,7 +124,7 @@ class MarketDataSyncer valid_modes = [ :full, :snapshot ] unless valid_modes.include?(mode.to_sym) - raise InvalidModeError, "Invalid mode for MarketDataSyncer, can only be :full or :snapshot, but was #{mode}" + raise InvalidModeError, "Invalid mode for MarketDataImporter, can only be :full or :snapshot, but was #{mode}" end mode.to_sym diff --git a/app/models/security/price/syncer.rb b/app/models/security/price/importer.rb similarity index 98% rename from app/models/security/price/syncer.rb rename to app/models/security/price/importer.rb index 824998cd..4e6bee2f 100644 --- a/app/models/security/price/syncer.rb +++ b/app/models/security/price/importer.rb @@ -1,4 +1,4 @@ -class Security::Price::Syncer +class Security::Price::Importer MissingSecurityPriceError = Class.new(StandardError) MissingStartPriceError = Class.new(StandardError) @@ -12,7 +12,7 @@ class Security::Price::Syncer # Constructs a daily series of prices for a single security over the date range. # Returns the number of rows upserted. - def sync_provider_prices + def import_provider_prices if !clear_cache && all_prices_exist? Rails.logger.info("No new prices to sync for #{security.ticker} between #{start_date} and #{end_date}, skipping") return 0 diff --git a/app/models/security/provided.rb b/app/models/security/provided.rb index 2214ccfa..2fdcc607 100644 --- a/app/models/security/provided.rb +++ b/app/models/security/provided.rb @@ -49,9 +49,9 @@ module Security::Provided price end - def sync_provider_details(clear_cache: false) + def import_provider_details(clear_cache: false) unless provider.present? - Rails.logger.warn("No provider configured for Security.sync_provider_details") + Rails.logger.warn("No provider configured for Security.import_provider_details") return end @@ -76,19 +76,19 @@ module Security::Provided end end - def sync_provider_prices(start_date:, end_date:, clear_cache: false) + def import_provider_prices(start_date:, end_date:, clear_cache: false) unless provider.present? - Rails.logger.warn("No provider configured for Security.sync_provider_prices") + Rails.logger.warn("No provider configured for Security.import_provider_prices") return 0 end - Security::Price::Syncer.new( + Security::Price::Importer.new( security: self, security_provider: provider, start_date: start_date, end_date: end_date, clear_cache: clear_cache - ).sync_provider_prices + ).import_provider_prices end private diff --git a/config/schedule.yml b/config/schedule.yml index 8eb8ef0a..28078e4d 100644 --- a/config/schedule.yml +++ b/config/schedule.yml @@ -1,8 +1,8 @@ -sync_market_data: +import_market_data: cron: "0 22 * * 1-5" # 5:00 PM EST / 6:00 PM EDT (NY time) - class: "SyncMarketDataJob" + class: "ImportMarketDataJob" queue: "scheduled" - description: "Syncs market data daily at 5:00 PM EST (1 hour after market close)" + description: "Imports market data daily at 5:00 PM EST (1 hour after market close)" args: mode: "full" clear_cache: false diff --git a/test/models/account/market_data_syncer_test.rb b/test/models/account/market_data_importer_test.rb similarity index 92% rename from test/models/account/market_data_syncer_test.rb rename to test/models/account/market_data_importer_test.rb index 596798f5..74c42d36 100644 --- a/test/models/account/market_data_syncer_test.rb +++ b/test/models/account/market_data_importer_test.rb @@ -1,7 +1,7 @@ require "test_helper" require "ostruct" -class Account::MarketDataSyncerTest < ActiveSupport::TestCase +class Account::MarketDataImporterTest < ActiveSupport::TestCase include ProviderTestHelper PROVIDER_BUFFER = 5.days @@ -32,7 +32,7 @@ class Account::MarketDataSyncerTest < ActiveSupport::TestCase accountable: Depository.new ) - # Seed a rate for the first required day so that the syncer only needs the next day forward + # Seed a rate for the first required day so that the importer only needs the next day forward existing_date = account.start_date ExchangeRate.create!(from_currency: "CAD", to_currency: "USD", date: existing_date, rate: 2.0) @@ -49,7 +49,7 @@ class Account::MarketDataSyncerTest < ActiveSupport::TestCase ])) before = ExchangeRate.count - Account::MarketDataSyncer.new(account).sync_market_data + Account::MarketDataImporter.new(account).import_all after = ExchangeRate.count assert_operator after, :>, before, "Should insert at least one new exchange-rate row" @@ -100,7 +100,7 @@ class Account::MarketDataSyncerTest < ActiveSupport::TestCase # Ignore exchange-rate calls for this test @provider.stubs(:fetch_exchange_rates).returns(provider_success_response([])) - Account::MarketDataSyncer.new(account).sync_market_data + Account::MarketDataImporter.new(account).import_all assert_equal 1, Security::Price.where(security: security, date: trade_date).count end diff --git a/test/models/balance/syncer_test.rb b/test/models/balance/materializer_test.rb similarity index 82% rename from test/models/balance/syncer_test.rb rename to test/models/balance/materializer_test.rb index 648f6b3a..4a5ac439 100644 --- a/test/models/balance/syncer_test.rb +++ b/test/models/balance/materializer_test.rb @@ -1,6 +1,6 @@ require "test_helper" -class Balance::SyncerTest < ActiveSupport::TestCase +class Balance::MaterializerTest < ActiveSupport::TestCase include EntriesTestHelper setup do @@ -14,7 +14,7 @@ class Balance::SyncerTest < ActiveSupport::TestCase end test "syncs balances" do - Holding::Syncer.any_instance.expects(:sync_holdings).returns([]).once + Holding::Materializer.any_instance.expects(:materialize_holdings).returns([]).once @account.expects(:start_date).returns(2.days.ago.to_date) @@ -26,7 +26,7 @@ class Balance::SyncerTest < ActiveSupport::TestCase ) assert_difference "@account.balances.count", 2 do - Balance::Syncer.new(@account, strategy: :forward).sync_balances + Balance::Materializer.new(@account, strategy: :forward).materialize_balances end end @@ -45,7 +45,7 @@ class Balance::SyncerTest < ActiveSupport::TestCase ) assert_difference "@account.balances.count", 3 do - Balance::Syncer.new(@account, strategy: :forward).sync_balances + Balance::Materializer.new(@account, strategy: :forward).materialize_balances end end end diff --git a/test/models/exchange_rate/syncer_test.rb b/test/models/exchange_rate/importer_test.rb similarity index 92% rename from test/models/exchange_rate/syncer_test.rb rename to test/models/exchange_rate/importer_test.rb index 58818834..dab40fa8 100644 --- a/test/models/exchange_rate/syncer_test.rb +++ b/test/models/exchange_rate/importer_test.rb @@ -1,7 +1,7 @@ require "test_helper" require "ostruct" -class ExchangeRate::SyncerTest < ActiveSupport::TestCase +class ExchangeRate::ImporterTest < ActiveSupport::TestCase include ProviderTestHelper setup do @@ -21,13 +21,13 @@ class ExchangeRate::SyncerTest < ActiveSupport::TestCase .with(from: "USD", to: "EUR", start_date: get_provider_fetch_start_date(2.days.ago.to_date), end_date: Date.current) .returns(provider_response) - ExchangeRate::Syncer.new( + ExchangeRate::Importer.new( exchange_rate_provider: @provider, from: "USD", to: "EUR", start_date: 2.days.ago.to_date, end_date: Date.current - ).sync_provider_rates + ).import_provider_rates db_rates = ExchangeRate.where(from_currency: "USD", to_currency: "EUR", date: 2.days.ago.to_date..Date.current) .order(:date) @@ -53,13 +53,13 @@ class ExchangeRate::SyncerTest < ActiveSupport::TestCase .with(from: "USD", to: "EUR", start_date: get_provider_fetch_start_date(1.day.ago.to_date), end_date: Date.current) .returns(provider_response) - ExchangeRate::Syncer.new( + ExchangeRate::Importer.new( exchange_rate_provider: @provider, from: "USD", to: "EUR", start_date: 3.days.ago.to_date, end_date: Date.current - ).sync_provider_rates + ).import_provider_rates db_rates = ExchangeRate.order(:date) assert_equal 4, db_rates.count @@ -75,13 +75,13 @@ class ExchangeRate::SyncerTest < ActiveSupport::TestCase @provider.expects(:fetch_exchange_rates).never - ExchangeRate::Syncer.new( + ExchangeRate::Importer.new( exchange_rate_provider: @provider, from: "USD", to: "EUR", start_date: 3.days.ago.to_date, end_date: Date.current - ).sync_provider_rates + ).import_provider_rates end # A helpful "reset" option for when we need to refresh provider data @@ -103,14 +103,14 @@ class ExchangeRate::SyncerTest < ActiveSupport::TestCase .with(from: "USD", to: "EUR", start_date: get_provider_fetch_start_date(2.days.ago.to_date), end_date: Date.current) .returns(provider_response) - ExchangeRate::Syncer.new( + ExchangeRate::Importer.new( exchange_rate_provider: @provider, from: "USD", to: "EUR", start_date: 2.days.ago.to_date, end_date: Date.current, clear_cache: true - ).sync_provider_rates + ).import_provider_rates db_rates = ExchangeRate.where(from_currency: "USD", to_currency: "EUR").order(:date) assert_equal [ 1.3, 1.4, 1.5 ], db_rates.map(&:rate) @@ -129,13 +129,13 @@ class ExchangeRate::SyncerTest < ActiveSupport::TestCase .with(from: "USD", to: "EUR", start_date: get_provider_fetch_start_date(Date.current), end_date: Date.current) .returns(provider_response) - ExchangeRate::Syncer.new( + ExchangeRate::Importer.new( exchange_rate_provider: @provider, from: "USD", to: "EUR", start_date: Date.current, end_date: future_date - ).sync_provider_rates + ).import_provider_rates assert_equal 1, ExchangeRate.count end diff --git a/test/models/holding/syncer_test.rb b/test/models/holding/materializer_test.rb similarity index 78% rename from test/models/holding/syncer_test.rb rename to test/models/holding/materializer_test.rb index 19e191c8..41ae8ff6 100644 --- a/test/models/holding/syncer_test.rb +++ b/test/models/holding/materializer_test.rb @@ -1,6 +1,6 @@ require "test_helper" -class Holding::SyncerTest < ActiveSupport::TestCase +class Holding::MaterializerTest < ActiveSupport::TestCase include EntriesTestHelper setup do @@ -14,7 +14,7 @@ class Holding::SyncerTest < ActiveSupport::TestCase # Should have yesterday's and today's holdings assert_difference "@account.holdings.count", 2 do - Holding::Syncer.new(@account, strategy: :forward).sync_holdings + Holding::Materializer.new(@account, strategy: :forward).materialize_holdings end end @@ -23,7 +23,7 @@ class Holding::SyncerTest < ActiveSupport::TestCase Holding.create!(account: @account, security: @aapl, qty: 1, price: 100, amount: 100, currency: "USD", date: Date.current) assert_difference "Holding.count", -1 do - Holding::Syncer.new(@account, strategy: :forward).sync_holdings + Holding::Materializer.new(@account, strategy: :forward).materialize_holdings end end end diff --git a/test/models/market_data_syncer_test.rb b/test/models/market_data_importer_test.rb similarity index 91% rename from test/models/market_data_syncer_test.rb rename to test/models/market_data_importer_test.rb index 8a9db1f5..b39bf0ad 100644 --- a/test/models/market_data_syncer_test.rb +++ b/test/models/market_data_importer_test.rb @@ -1,10 +1,10 @@ require "test_helper" require "ostruct" -class MarketDataSyncerTest < ActiveSupport::TestCase +class MarketDataImporterTest < ActiveSupport::TestCase include ProviderTestHelper - SNAPSHOT_START_DATE = MarketDataSyncer::SNAPSHOT_DAYS.days.ago.to_date + SNAPSHOT_START_DATE = MarketDataImporter::SNAPSHOT_DAYS.days.ago.to_date PROVIDER_BUFFER = 5.days setup do @@ -47,7 +47,7 @@ class MarketDataSyncerTest < ActiveSupport::TestCase ])) before = ExchangeRate.count - MarketDataSyncer.new(mode: :snapshot).sync_exchange_rates + MarketDataImporter.new(mode: :snapshot).import_exchange_rates after = ExchangeRate.count assert_operator after, :>, before, "Should insert at least one new exchange-rate row" @@ -78,7 +78,7 @@ class MarketDataSyncerTest < ActiveSupport::TestCase # Ignore exchange rate calls for this test @provider.stubs(:fetch_exchange_rates).returns(provider_success_response([])) - MarketDataSyncer.new(mode: :snapshot).sync_prices + MarketDataImporter.new(mode: :snapshot).import_security_prices assert_equal 1, Security::Price.where(security: security, date: SNAPSHOT_START_DATE).count end diff --git a/test/models/security/price/syncer_test.rb b/test/models/security/price/importer_test.rb similarity index 92% rename from test/models/security/price/syncer_test.rb rename to test/models/security/price/importer_test.rb index 25a3f14c..665a91f6 100644 --- a/test/models/security/price/syncer_test.rb +++ b/test/models/security/price/importer_test.rb @@ -1,7 +1,7 @@ require "test_helper" require "ostruct" -class Security::Price::SyncerTest < ActiveSupport::TestCase +class Security::Price::ImporterTest < ActiveSupport::TestCase include ProviderTestHelper setup do @@ -23,12 +23,12 @@ class Security::Price::SyncerTest < ActiveSupport::TestCase start_date: get_provider_fetch_start_date(2.days.ago.to_date), end_date: Date.current) .returns(provider_response) - Security::Price::Syncer.new( + Security::Price::Importer.new( security: @security, security_provider: @provider, start_date: 2.days.ago.to_date, end_date: Date.current - ).sync_provider_prices + ).import_provider_prices db_prices = Security::Price.where(security: @security, date: 2.days.ago.to_date..Date.current).order(:date) @@ -52,12 +52,12 @@ class Security::Price::SyncerTest < ActiveSupport::TestCase start_date: get_provider_fetch_start_date(1.day.ago.to_date), end_date: Date.current) .returns(provider_response) - Security::Price::Syncer.new( + Security::Price::Importer.new( security: @security, security_provider: @provider, start_date: 3.days.ago.to_date, end_date: Date.current - ).sync_provider_prices + ).import_provider_prices db_prices = Security::Price.where(security: @security).order(:date) assert_equal 4, db_prices.count @@ -73,12 +73,12 @@ class Security::Price::SyncerTest < ActiveSupport::TestCase @provider.expects(:fetch_security_prices).never - Security::Price::Syncer.new( + Security::Price::Importer.new( security: @security, security_provider: @provider, start_date: 3.days.ago.to_date, end_date: Date.current - ).sync_provider_prices + ).import_provider_prices end test "full upsert if clear_cache is true" do @@ -100,13 +100,13 @@ class Security::Price::SyncerTest < ActiveSupport::TestCase start_date: get_provider_fetch_start_date(2.days.ago.to_date), end_date: Date.current) .returns(provider_response) - Security::Price::Syncer.new( + Security::Price::Importer.new( security: @security, security_provider: @provider, start_date: 2.days.ago.to_date, end_date: Date.current, clear_cache: true - ).sync_provider_prices + ).import_provider_prices db_prices = Security::Price.where(security: @security).order(:date) assert_equal [ 150, 155, 160 ], db_prices.map(&:price) @@ -126,12 +126,12 @@ class Security::Price::SyncerTest < ActiveSupport::TestCase start_date: get_provider_fetch_start_date(Date.current), end_date: Date.current) .returns(provider_response) - Security::Price::Syncer.new( + Security::Price::Importer.new( security: @security, security_provider: @provider, start_date: Date.current, end_date: future_date - ).sync_provider_prices + ).import_provider_prices assert_equal 1, Security::Price.count end