Files
RichardandClaude Opus 5 fd6d62618f Kultur-Bug behoben + Threema entfernt (INotificationSink)
- TraderMonitorService las API-Preise kulturabhaengig: unter de-DE wurde aus
  "0.53" der Wert 53 (Faktor-100-Fehler im Einstandspreis). Nutzt jetzt den
  bereits vorhandenen invarianten Helper ParseDecimal.
- Gleiche Fehlerklasse in PolymarketClobClient (6x) und MasterTraderAnalyticsJob
  vorsorglich auf InvariantCulture gestellt.
- Neuer Regressionstest ApiNumberParsingTests (10 Faelle unter erzwungener de-DE-Kultur).
- Threema komplett entfernt (Entscheidung Richard): ThreemaService, vendorte
  Bibliothek libs/Threema-MsgApi-Net-Core, ServerSettings-Block, DI-Verdrahtung.
- Ersetzt durch neutrale INotificationSink (No-Throw-Vertrag) + LogNotificationSink
  als Uebergang; RocketChat/Telegram folgen spaeter.
- Entfernt nebenbei libsodium 1.0.16, die einzige Registry-Nutzung im Build,
  den HttpListener-Webhook und System.Web.HttpUtility (alles Linux-Hindernisse).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 12:01:13 +02:00

65 lines
2.6 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Globalization;
using System.Text.Json;
using System.Threading;
using PolyTraderSharp.Services;
using Xunit;
namespace PolyTrader.Tests
{
/// <summary>
/// Regressionsschutz für den Kultur-Bug in der Aktivitäts-Auswertung: Polymarket liefert
/// <c>price</c>/<c>size</c> je nach Endpunkt als JSON-Zahl ODER als String ("0.53"). Wurde der
/// String kulturabhängig geparst, las de-DE den Punkt als Tausendertrennzeichen aus 0,53 wurde
/// 53 (Faktor-100-Fehler im Einstandspreis der Master-Trader-Auswertung).
///
/// Die Tests setzen die Thread-Kultur bewusst auf de-DE, damit sie auch auf einer invarianten
/// Umgebung (z.B. Linux-CI ohne LANG) fehlschlagen würden, sobald jemand die Invariant-Angabe
/// wieder entfernt.
/// </summary>
public class ApiNumberParsingTests
{
/// <summary>Führt die Prüfung unter erzwungener de-DE-Kultur aus und stellt sie danach wieder her.</summary>
private static void UnderGermanCulture(System.Action assertions)
{
var previous = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");
try { assertions(); }
finally { Thread.CurrentThread.CurrentCulture = previous; }
}
private static JsonElement Prop(string json) =>
JsonDocument.Parse(json).RootElement.GetProperty("v");
[Theory]
[InlineData("\"0.53\"", 0.53)] // der eigentliche Bug: wurde unter de-DE zu 53
[InlineData("\"0.045\"", 0.045)]
[InlineData("\"1234.5\"", 1234.5)] // ohne Invariant unter de-DE: 12345
[InlineData("\"0\"", 0)]
public void ParseDecimal_reads_string_values_invariantly(string jsonValue, double expected)
{
UnderGermanCulture(() =>
Assert.Equal((decimal)expected, TraderMonitorService.ParseDecimal(Prop($"{{\"v\":{jsonValue}}}"))));
}
[Theory]
[InlineData("0.53", 0.53)]
[InlineData("1234.5", 1234.5)]
public void ParseDecimal_reads_numeric_values(string jsonValue, double expected)
{
UnderGermanCulture(() =>
Assert.Equal((decimal)expected, TraderMonitorService.ParseDecimal(Prop($"{{\"v\":{jsonValue}}}"))));
}
[Theory]
[InlineData("null")]
[InlineData("\"\"")]
[InlineData("\"n/a\"")]
[InlineData("true")]
public void ParseDecimal_returns_zero_for_unusable_values(string jsonValue)
{
UnderGermanCulture(() =>
Assert.Equal(0m, TraderMonitorService.ParseDecimal(Prop($"{{\"v\":{jsonValue}}}"))));
}
}
}