using FluentAssertions; using Marathon.Domain.Entities; using Marathon.Domain.Enums; using Marathon.Domain.ValueObjects; namespace Marathon.Domain.Tests.Entities; public sealed class PaperBetTests { private static readonly DateTimeOffset Opened = new(2026, 5, 20, 18, 0, 0, TimeSpan.FromHours(3)); private static PaperBet OpenBet(Side pick = Side.Side1, decimal rate = 2.00m, decimal stake = 10m) => PaperBet.Open(Guid.NewGuid(), new EventId("26000001"), pick, rate, stake, Opened); [Fact] public void Open_CreatesPendingBet_WithIdentity() { var bet = OpenBet(); bet.Id.Should().NotBe(Guid.Empty); bet.Outcome.Should().Be(BetOutcome.Pending); bet.IsOpen.Should().BeTrue(); bet.SettledAt.Should().BeNull(); bet.Payout.Should().BeNull(); } [Theory] [InlineData(1.0)] [InlineData(0.5)] public void Constructor_Throws_When_RateNotAboveOne(double rate) { var act = () => OpenBet(rate: (decimal)rate); act.Should().Throw(); } [Theory] [InlineData(0)] [InlineData(-5)] public void Constructor_Throws_When_StakeNotPositive(double stake) { var act = () => OpenBet(stake: (decimal)stake); act.Should().Throw(); } [Fact] public void SettleAgainst_Win_PaysStakeTimesRate() { var bet = OpenBet(pick: Side.Side1, rate: 2.00m, stake: 10m); var settledAt = Opened.AddHours(2); var settled = bet.SettleAgainst(Side.Side1, settledAt); settled.Outcome.Should().Be(BetOutcome.Won); settled.Payout.Should().Be(20m); settled.SettledAt.Should().Be(settledAt); settled.IsOpen.Should().BeFalse(); } [Fact] public void SettleAgainst_Loss_PaysZero() { var settled = OpenBet(pick: Side.Side1).SettleAgainst(Side.Side2, Opened.AddHours(2)); settled.Outcome.Should().Be(BetOutcome.Lost); settled.Payout.Should().Be(0m); } [Fact] public void SettleAgainst_PreservesIdentityStakeAndRate() { var bet = OpenBet(rate: 2.00m, stake: 10m); var settled = bet.SettleAgainst(Side.Side1, Opened.AddHours(1)); settled.Id.Should().Be(bet.Id); settled.AnomalyId.Should().Be(bet.AnomalyId); settled.EventId.Should().Be(bet.EventId); settled.Stake.Should().Be(10m); settled.Rate.Should().Be(2.00m); } }