using System; using System.Linq; using System.Threading.Tasks; using PolyTraderSharp; using PolyTraderSharp.Services; using Xunit; namespace PolyTrader.Tests.WebUi { /// /// Trading beenden über das WebUI, ohne die Anwendung zu beenden (#563). /// public class StopTradingEndpointTests { [Fact] public async Task Beenden_setzt_beide_Modi_auf_Inaktiv_und_die_Pause_an() { await using var web = await WebUiTestHost.StartAsync(); web.State.LiveTradingMode = TradingMode.Active; web.State.DemoTradingMode = TradingMode.SellOnly; var (status, body) = await web.PostJsonAsync("/api/dashboard/stop-trading", new { confirmed = true }); Assert.Equal(200, status); Assert.Equal(TradingMode.Inactive, web.State.LiveTradingMode); Assert.Equal(TradingMode.Inactive, web.State.DemoTradingMode); Assert.True(web.State.GlobalTradingPaused); Assert.True(body.GetProperty("globalTradingPaused").GetBoolean()); } [Fact] public async Task Ohne_Bestaetigung_bleibt_alles_wie_es_ist() { await using var web = await WebUiTestHost.StartAsync(); web.State.LiveTradingMode = TradingMode.Active; var (withoutBody, _) = await web.PostJsonAsync("/api/dashboard/stop-trading"); var (notConfirmed, _) = await web.PostJsonAsync("/api/dashboard/stop-trading", new { confirmed = false }); Assert.Equal(400, withoutBody); Assert.Equal(400, notConfirmed); Assert.Equal(TradingMode.Active, web.State.LiveTradingMode); Assert.False(web.State.GlobalTradingPaused); } [Fact] public async Task Anwendung_und_WebUI_bleiben_danach_erreichbar() { await using var web = await WebUiTestHost.StartAsync(); await web.PostJsonAsync("/api/dashboard/stop-trading", new { confirmed = true }); var summary = await web.GetJsonAsync("/api/dashboard/summary"); Assert.True(summary.GetProperty("globalTradingPaused").GetBoolean()); Assert.Equal("Inactive", summary.GetProperty("liveTradingMode").GetString()); } [Fact] public async Task Beenden_wird_als_Warnung_protokolliert() { await using var web = await WebUiTestHost.StartAsync(); await web.PostJsonAsync("/api/dashboard/stop-trading", new { confirmed = true }); var entry = web.Logger.GetHistory(TimeSpan.FromMinutes(1)) .LastOrDefault(e => e.Message.Contains("Trading beendet", StringComparison.Ordinal)); Assert.NotNull(entry); Assert.Equal(LogLevel.Warning, entry!.Level); Assert.Contains("Orders an der Börse bleiben stehen", entry.Message); } [Fact] public async Task Wiederaufnahme_nur_ausdruecklich_ueber_die_Modus_Schalter() { await using var web = await WebUiTestHost.StartAsync(); await web.PostJsonAsync("/api/dashboard/stop-trading", new { confirmed = true }); // Die Pause aufzuheben genuegt nicht: Die Modi stehen weiter auf Inaktiv. await web.PostJsonAsync("/api/dashboard/trading-mode", new { modeType = "pause", targetMode = "" }); Assert.False(web.State.GlobalTradingPaused); Assert.Equal(TradingMode.Inactive, web.State.LiveTradingMode); Assert.Equal(TradingMode.Inactive, web.State.DemoTradingMode); var (status, _) = await web.PostJsonAsync("/api/dashboard/trading-mode", new { modeType = "demo", targetMode = "Active" }); Assert.Equal(200, status); Assert.Equal(TradingMode.Active, web.State.DemoTradingMode); } } }