using FluentAssertions; using IBKRTrader.Modules.Accounting.Logic; using IBKRTrader.Modules.Accounting.Models; namespace IBKRTrader.Tests.Modules.Accounting; [Trait("cat", "unit")] public class FxConverterTests { private static FxRate R(int day, decimal rate) => new() { Date = new DateTime(2026, 5, day), UsdToEur = rate, Source = "ECB" }; [Fact] public void UsesNearestRateOnOrBefore() { var conv = new FxConverter(new[] { R(1, 0.90m), R(10, 0.92m) }); conv.UsdToEurOn(new DateTime(2026, 5, 5)).Should().Be(0.90m); // zwischen 1. und 10. → 0.90 conv.UsdToEurOn(new DateTime(2026, 5, 10)).Should().Be(0.92m); // exakt conv.UsdToEurOn(new DateTime(2026, 5, 20)).Should().Be(0.92m); // nach letztem → letzter } [Fact] public void ReturnsNull_WhenNoRateBeforeDate() { var conv = new FxConverter(new[] { R(10, 0.92m) }); conv.UsdToEurOn(new DateTime(2026, 5, 1)).Should().BeNull(); conv.UsdToEur(100m, new DateTime(2026, 5, 1)).Should().BeNull(); } [Fact] public void ConvertsAndRounds() { var conv = new FxConverter(new[] { R(1, 0.9123m) }); conv.UsdToEur(100m, new DateTime(2026, 5, 2)).Should().Be(91.23m); } }