using System; using PolyTrader.Modules.ResolutionFarming.Logic; using PolyTrader.Modules.ResolutionFarming.Models; using Xunit; namespace PolyTrader.Tests { /// Sicherheitsnetz für den reinen Positions-Abschluss bei Auflösung (PnL, Fees, Redeem-Status). public class FarmingResolutionTests { private static RfPosition Pos(int feeBps = 0) => new() { AccountId = 1, TokenId = "a", MarketQuestion = "Q", Size = 100m, EntryPrice = 0.95m, AmountUsd = 95m, EntryFeeBps = feeBps, IsDemo = true, OpenedAt = DateTime.UtcNow.AddHours(-5) }; [Fact] public void Winner_maker_pays_out_one_per_share() { var t = FarmingResolution.BuildClosedTrade(Pos(), isWinner: true, DateTime.UtcNow); Assert.Equal(1.0m, t.ExitPrice); Assert.Equal(5m, t.RealizedPnl); // 100 - 95 - 0 Assert.Equal(0m, t.TotalFees); Assert.Equal("Pending", t.RedeemStatus); // Gewinner müssen redeemt werden } [Fact] public void Loser_loses_entry_cost() { var t = FarmingResolution.BuildClosedTrade(Pos(), isWinner: false, DateTime.UtcNow); Assert.Equal(0.0m, t.ExitPrice); Assert.Equal(-95m, t.RealizedPnl); Assert.Equal("None", t.RedeemStatus); } [Fact] public void Taker_entry_fee_reduces_winner_pnl() { var t = FarmingResolution.BuildClosedTrade(Pos(feeBps: 100), isWinner: true, DateTime.UtcNow); Assert.Equal(4.05m, t.RealizedPnl); // 100 - 95 - 0.95 Assert.Equal(0.95m, t.TotalFees); } } }