using FluentAssertions; using IBKRTrader.Modules.Accounting.Logic; using IBKRTrader.Modules.Accounting.Models; namespace IBKRTrader.Tests.Modules.Accounting; [Trait("cat", "unit")] public class AccountingClassifierTests { [Fact] public void ClassifyExecution_Buy_CostsGrossPlusFee() { var e = new RawExecution { AccountId = "U1", TradeId = "T1", Side = "BUY", GrossBase = 1000m, FeeBase = 1m, Quantity = 10, Currency = "USD" }; var entry = AccountingClassifier.ClassifyExecution(e, 5); entry.EventType.Should().Be(LedgerEventType.TradeBuy); entry.NetBase.Should().Be(-1001m); entry.IdempotencyKey.Should().Be("TRD|TradeBuy|T1"); entry.IngestBatchId.Should().Be(5); } [Fact] public void ClassifyExecution_Sell_BringsGrossMinusFee() { var e = new RawExecution { AccountId = "U1", TradeId = "T2", Side = "SELL", GrossBase = 1300m, FeeBase = 1m }; var entry = AccountingClassifier.ClassifyExecution(e, 1); entry.EventType.Should().Be(LedgerEventType.TradeSell); entry.NetBase.Should().Be(1299m); } [Theory] [InlineData("Dividends", LedgerEventType.Dividend)] [InlineData("Withholding Tax", LedgerEventType.TaxWithholding)] [InlineData("Broker Interest Received", LedgerEventType.Interest)] [InlineData("Deposit", LedgerEventType.Deposit)] [InlineData("Withdrawal", LedgerEventType.Withdrawal)] public void MapCashType_MapsKnownTypes(string ibkrType, LedgerEventType expected) { AccountingClassifier.MapCashType(ibkrType).Should().Be(expected); } [Fact] public void ClassifyCashTransaction_KeepsReportedSign() { var div = new RawCashTransaction { AccountId = "U1", TransactionId = "C1", Type = "Dividends", AmountBase = 50m }; var tax = new RawCashTransaction { AccountId = "U1", TransactionId = "C2", Type = "Withholding Tax", AmountBase = -7.5m }; AccountingClassifier.ClassifyCashTransaction(div, 1).NetBase.Should().Be(50m); var t = AccountingClassifier.ClassifyCashTransaction(tax, 1); t.EventType.Should().Be(LedgerEventType.TaxWithholding); t.NetBase.Should().Be(-7.5m); t.GrossBase.Should().Be(7.5m); t.IdempotencyKey.Should().Be("CASH|TaxWithholding|C2"); } }