"""Tests for display mode switching functionality.""" from decimal import Decimal import pytest from app.domain.conversions import ( collateral_to_display_units, format_display_quantity, get_display_mode_label, get_display_mode_options, position_to_display_units, ) from app.models.position import create_position class TestDisplayModeOptions: """Test display mode option helpers.""" def test_get_display_mode_options(self): """Test display mode options dictionary.""" options = get_display_mode_options() assert "GLD" in options assert "XAU_OZ" in options assert "XAU_G" in options assert "GCF" in options assert options["GLD"] == "GLD Shares" assert options["XAU_OZ"] == "Gold Ounces (troy)" assert options["XAU_G"] == "Gold Grams" assert options["GCF"] == "GC=F Contracts" def test_get_display_mode_label(self): """Test display mode label lookup.""" assert get_display_mode_label("GLD") == "GLD Shares" assert get_display_mode_label("XAU_OZ") == "Gold (Troy Ounces)" assert get_display_mode_label("XAU_G") == "Gold (Grams)" assert get_display_mode_label("GCF") == "GC=F Contracts" assert get_display_mode_label("UNKNOWN") == "UNKNOWN" class TestFormatDisplayQuantity: """Test quantity formatting for display.""" def test_format_shares(self): """Test share formatting (no decimals).""" assert format_display_quantity(100.0, "shares") == "100" assert format_display_quantity(1234.56, "shares") == "1,235" assert format_display_quantity(1000000.0, "shares") == "1,000,000" def test_format_contracts(self): """Test contract formatting (no decimals).""" assert format_display_quantity(10.0, "contracts") == "10" assert format_display_quantity(1234.56, "contracts") == "1,235" def test_format_ounces(self): """Test ounce formatting (4 decimals).""" assert format_display_quantity(100.0, "oz") == "100.0000" assert format_display_quantity(9.1576, "oz") == "9.1576" assert format_display_quantity(0.123456, "oz") == "0.1235" def test_format_grams(self): """Test gram formatting (2 decimals).""" assert format_display_quantity(100.0, "g") == "100.00" assert format_display_quantity(284.83, "g") == "284.83" assert format_display_quantity(31103.5, "g") == "31,103.50" class TestPositionToDisplayUnits: """Test position conversion to display units.""" def test_gld_shares_in_gld_mode(self): """Test GLD shares displayed as-is in GLD mode.""" pos = create_position("GLD", Decimal("100"), "shares", Decimal("230")) qty, unit = position_to_display_units(pos, "GLD") assert qty == Decimal("100") assert unit == "shares" def test_gld_shares_in_xau_oz_mode(self): """Test GLD shares converted to ounces in XAU_OZ mode.""" pos = create_position("GLD", Decimal("100"), "shares", Decimal("230")) qty, unit = position_to_display_units(pos, "XAU_OZ") assert unit == "oz" # Should be ~9.16 oz for 100 shares (depends on date) assert Decimal("9") < qty < Decimal("10") def test_gld_shares_in_xau_g_mode(self): """Test GLD shares converted to grams in XAU_G mode.""" pos = create_position("GLD", Decimal("100"), "shares", Decimal("230")) qty, unit = position_to_display_units(pos, "XAU_G") assert unit == "g" # Should be ~285 g for 100 shares assert Decimal("280") < qty < Decimal("290") def test_gld_shares_in_gcf_mode(self): """Test GLD shares converted to contracts in GCF mode.""" pos = create_position("GLD", Decimal("1000"), "shares", Decimal("230")) qty, unit = position_to_display_units(pos, "GCF") assert unit == "contracts" # Should be ~0.92 contracts for 1000 shares assert Decimal("0.9") < qty < Decimal("1.0") def test_xau_oz_in_gld_mode(self): """Test XAU ounces converted to GLD shares in GLD mode.""" pos = create_position("XAU", Decimal("10"), "oz", Decimal("2150")) qty, unit = position_to_display_units(pos, "GLD") assert unit == "shares" # 10 oz should be ~109 shares assert Decimal("100") < qty < Decimal("120") def test_xau_oz_in_xau_g_mode(self): """Test XAU ounces converted to grams in XAU_G mode.""" pos = create_position("XAU", Decimal("10"), "oz", Decimal("2150")) qty, unit = position_to_display_units(pos, "XAU_G") assert unit == "g" # 10 oz = 311.035 g assert qty == Decimal("311.035") def test_gcf_contracts_in_xau_oz_mode(self): """Test GC=F contracts converted to ounces in XAU_OZ mode.""" pos = create_position("GC=F", Decimal("1"), "contracts", Decimal("215000")) qty, unit = position_to_display_units(pos, "XAU_OZ") assert unit == "oz" # 1 contract = 100 oz assert qty == Decimal("100") def test_gcf_contracts_in_gld_mode(self): """Test GC=F contracts converted to GLD shares in GLD mode.""" pos = create_position("GC=F", Decimal("1"), "contracts", Decimal("215000")) qty, unit = position_to_display_units(pos, "GLD") assert unit == "shares" # 100 oz should be ~1092 shares assert Decimal("1000") < qty < Decimal("1100") class TestCollateralToDisplayUnits: """Test collateral conversion to display units.""" def test_collateral_in_gld_mode(self): """Test collateral converted to GLD shares.""" qty, unit = collateral_to_display_units(1000.0, "GLD") assert unit == "shares" assert qty > 10000 # Should be ~10920 shares def test_collateral_in_xau_oz_mode(self): """Test collateral stays in ounces.""" qty, unit = collateral_to_display_units(1000.0, "XAU_OZ") assert unit == "oz" assert qty == 1000.0 def test_collateral_in_xau_g_mode(self): """Test collateral converted to grams.""" qty, unit = collateral_to_display_units(1000.0, "XAU_G") assert unit == "g" assert qty == pytest.approx(31103.5, rel=0.01) def test_collateral_in_gcf_mode(self): """Test collateral converted to contracts.""" qty, unit = collateral_to_display_units(1000.0, "GCF") assert unit == "contracts" assert qty == pytest.approx(10.0, rel=0.01) class TestPortfolioConfigDisplayMode: """Test PortfolioConfig display_mode field.""" def test_default_display_mode(self): """Test default display mode is GLD.""" from app.models.portfolio import PortfolioConfig config = PortfolioConfig() assert config.display_mode == "GLD" def test_custom_display_mode(self): """Test custom display mode.""" from app.models.portfolio import PortfolioConfig config = PortfolioConfig(display_mode="XAU_OZ") assert config.display_mode == "XAU_OZ" def test_display_mode_in_to_dict(self): """Test display_mode is included in to_dict.""" from app.models.portfolio import PortfolioConfig config = PortfolioConfig(display_mode="XAU_G") config_dict = config.to_dict() assert "display_mode" in config_dict assert config_dict["display_mode"] == "XAU_G" def test_display_mode_in_from_dict(self): """Test display_mode is restored from dict.""" from app.models.portfolio import PortfolioConfig config_dict = { "gold_value": 215000.0, "entry_price": 2150.0, "gold_ounces": 100.0, "display_mode": "GCF", } config = PortfolioConfig.from_dict(config_dict) assert config.display_mode == "GCF"