R1: Umbau auf Multi-Projekt-Struktur (Vorbild PolytraderSharp) Kurskorrektur: Vorbild ist PolytraderSharp (C#), nicht die veraltete Python-Version. Reiner Strukturumbau, Verhalten unveraendert. - src/IBKRTrader.Core (classlib): Core-Code + UI-Contract (ModuleFormBase, WindowManager) - src/IBKRTrader.Modules.CongressTrading (classlib, referenziert nur Core) - Root: IBKRTrader.App (WinExe) referenziert Core + Modul - tests/IBKRTrader.Tests: Referenzen auf Core + Modul - Neue .slnx; ungenutztes HtmlAgilityPack entfernt - docs/ARCHITECTURE.md: korrigierter Ziel-Stand + R-Phasenplan - Build + 38/38 Tests gruen; App startet Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> @
58 lines
1.8 KiB
C#
58 lines
1.8 KiB
C#
using FluentAssertions;
|
|
using IBKRTrader.Core.Logging;
|
|
using IBKRTrader.Modules.CongressTrading.Scraper;
|
|
|
|
namespace IBKRTrader.Tests.Modules;
|
|
|
|
[Trait("cat", "unit")]
|
|
public class CapitolTradesScraperTests
|
|
{
|
|
private static string LoadFixture()
|
|
{
|
|
var path = Path.Combine(AppContext.BaseDirectory, "Fixtures", "ct_raw.html");
|
|
File.Exists(path).Should().BeTrue($"Fixture fehlt: {path}");
|
|
return File.ReadAllText(path);
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseTradesFromHtml_ExtractsTradesFromRscStream()
|
|
{
|
|
var scraper = new CapitolTradesScraper(new LoggingService());
|
|
|
|
var (trades, memberIds) = scraper.ParseTradesFromHtml(LoadFixture());
|
|
|
|
trades.Should().NotBeEmpty("die Fixture enthält einen RSC-Datenstrom mit Trades");
|
|
memberIds.Should().NotBeEmpty();
|
|
|
|
var first = trades[0];
|
|
first.TradeId.Should().NotBeNullOrWhiteSpace();
|
|
first.TradeType.Should().NotBeNullOrWhiteSpace();
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseTradesFromHtml_MapsMemberSnapshotConsistently()
|
|
{
|
|
var scraper = new CapitolTradesScraper(new LoggingService());
|
|
|
|
var (trades, memberIds) = scraper.ParseTradesFromHtml(LoadFixture());
|
|
|
|
// Jeder Member-Snapshot muss eine BioId haben, die auch im MemberBioIds-Set liegt.
|
|
foreach (var trade in trades.Where(t => t.MemberSnapshot is not null))
|
|
{
|
|
trade.MemberSnapshot!.BioId.Should().NotBeNullOrWhiteSpace();
|
|
memberIds.Should().Contain(trade.MemberBioId);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseTradesFromHtml_EmptyHtml_ReturnsNoTrades()
|
|
{
|
|
var scraper = new CapitolTradesScraper(new LoggingService());
|
|
|
|
var (trades, memberIds) = scraper.ParseTradesFromHtml("<html><body>nichts</body></html>");
|
|
|
|
trades.Should().BeEmpty();
|
|
memberIds.Should().BeEmpty();
|
|
}
|
|
}
|