using FluentAssertions; using IBKRTrader.Modules.Accounting.Logic; using IBKRTrader.Modules.Accounting.Models; namespace IBKRTrader.Tests.Modules.Accounting; [Trait("cat", "unit")] public class CsvExporterTests { [Fact] public void Ledger_HasHeader_AndInvariantFormatting() { var entries = new[] { new LedgerEntry { AccountId = "U1", EventType = LedgerEventType.TradeSell, Side = "SELL", Symbol = "AAPL", Currency = "USD", Quantity = 10m, PriceNative = 130.5m, GrossBase = 1305m, FeeBase = 1m, NetBase = 1304m, TransactionId = "T1", Source = "ibkr-flex", Timestamp = new DateTime(2026, 1, 2, 15, 4, 5, DateTimeKind.Utc) } }; var csv = CsvExporter.Ledger(entries); csv.Should().StartWith("Timestamp,AccountId,EventType,Side,Symbol"); csv.Should().Contain("2026-01-02 15:04:05"); csv.Should().Contain("130.5"); // Punkt-Dezimal, kulturinvariant csv.Should().Contain("TradeSell"); } [Fact] public void Quote_EscapesCommasAndQuotes() { var entries = new[] { new LedgerEntry { AccountId = "U1", Symbol = "A,B\"C", EventType = LedgerEventType.Other, TransactionId = "X" } }; var csv = CsvExporter.Ledger(entries); csv.Should().Contain("\"A,B\"\"C\""); } [Fact] public void Statement_ListsKeyMetrics() { var s = new PeriodStatement("U1", DateTime.UtcNow.AddDays(-30), DateTime.UtcNow, OpeningBalance: 100m, ClosingBalance: 150m, Deposits: 50m, Withdrawals: 0m, TradeVolume: 200m, Dividends: 5m, Interest: 0m, Fees: 2m, TaxWithheld: 1m, NetTradingResult: 0m, TradeCount: 3, EntryCount: 6); var csv = CsvExporter.Statement(s, "USD"); csv.Should().Contain("Kennzahl,USD"); csv.Should().Contain("Anfangssaldo,100"); csv.Should().Contain("Endsaldo,150"); } }