# frozen_string_literal: true require "test_helper" class BinanceAccount::HoldingsProcessorTest < ActiveSupport::TestCase setup do @family = families(:dylan_family) @family.update!(currency: "EUR") @item = BinanceItem.create!( family: @family, name: "Binance", api_key: "k", api_secret: "s" ) @ba = @item.binance_accounts.create!( name: "Binance", account_type: "combined", currency: "USD", current_balance: 1000, raw_payload: { "assets" => [ { "symbol" => "BTC", "total" => "0.5", "source" => "spot" } ] } ) @account = Account.create!( family: @family, name: "Binance", balance: 0, currency: "EUR", accountable: Crypto.create!(subtype: "exchange") ) AccountProvider.create!(account: @account, provider: @ba) end test "converts holding amount to family currency when exact rate exists" do ExchangeRate.create!(from_currency: "USD", to_currency: "EUR", date: Date.current, rate: 0.92) Security.find_or_create_by!(ticker: "CRYPTO:BTC") do |s| s.name = "BTC" s.exchange_operating_mic = "XBNC" end BinanceAccount::HoldingsProcessor.any_instance .stubs(:fetch_price).with("BTC").returns(60_000.0) import_adapter = mock import_adapter.expects(:import_holding).with( has_entries(currency: "EUR", amount: 27_600.0) ) Account::ProviderImportAdapter.stubs(:new).returns(import_adapter) BinanceAccount::HoldingsProcessor.new(@ba).process end test "uses raw USD amount when no rate is available" do ExchangeRate.stubs(:find_or_fetch_rate).returns(nil) Security.find_or_create_by!(ticker: "CRYPTO:BTC") do |s| s.name = "BTC" s.exchange_operating_mic = "XBNC" end BinanceAccount::HoldingsProcessor.any_instance .stubs(:fetch_price).with("BTC").returns(60_000.0) import_adapter = mock import_adapter.expects(:import_holding).with( has_entries(currency: "EUR", amount: 30_000.0) ) Account::ProviderImportAdapter.stubs(:new).returns(import_adapter) BinanceAccount::HoldingsProcessor.new(@ba).process end end