61114ea31b
Creates the 9-project .NET 8 solution (5 src + 4 test) with Marathon.Domain fully implemented: value objects (SportCode, EventId, OddsRate, OddsValue, BetScope hierarchy), enums (Side, BetType, OddsSource, AnomalyKind), and entities (Sport, Country, League, Event, Bet, OddsSnapshot, EventResult, Anomaly) with all invariants enforced in constructors. 96 domain tests pass (FluentAssertions + xUnit). Directory.Build.props and Directory.Packages.props centralise build settings and NuGet versions. Both Marathon.sln and Marathon.slnx are committed; dotnet build Marathon.sln succeeds with 0 warnings/errors.
60 lines
2.0 KiB
C#
60 lines
2.0 KiB
C#
using FluentAssertions;
|
|
using Marathon.Domain.Entities;
|
|
using Marathon.Domain.Enums;
|
|
using Marathon.Domain.ValueObjects;
|
|
|
|
namespace Marathon.Domain.Tests.Entities;
|
|
|
|
public sealed class OddsSnapshotTests
|
|
{
|
|
private static readonly EventId SampleEventId = new("26456117");
|
|
private static readonly DateTimeOffset SampleCapturedAt = DateTimeOffset.UtcNow;
|
|
private static readonly IReadOnlyList<Bet> OneBet =
|
|
[
|
|
new Bet(MatchScope.Instance, BetType.Win, Side.Side1, null, new OddsRate(1.85m)),
|
|
];
|
|
|
|
[Fact]
|
|
public void Constructor_CreatesInstance_WhenBetsIsNonEmpty()
|
|
{
|
|
var snapshot = new OddsSnapshot(SampleEventId, SampleCapturedAt, OddsSource.PreMatch, OneBet);
|
|
snapshot.EventId.Should().Be(SampleEventId);
|
|
snapshot.Bets.Should().HaveCount(1);
|
|
}
|
|
|
|
[Fact]
|
|
public void Constructor_ThrowsArgumentException_WhenBetsIsEmpty()
|
|
{
|
|
var act = () => new OddsSnapshot(SampleEventId, SampleCapturedAt, OddsSource.PreMatch, []);
|
|
act.Should().Throw<ArgumentException>()
|
|
.WithParameterName("bets");
|
|
}
|
|
|
|
[Fact]
|
|
public void Constructor_ThrowsArgumentNullException_WhenEventIdIsNull()
|
|
{
|
|
var act = () => new OddsSnapshot(null!, SampleCapturedAt, OddsSource.PreMatch, OneBet);
|
|
act.Should().Throw<ArgumentNullException>()
|
|
.WithParameterName("eventId");
|
|
}
|
|
|
|
[Fact]
|
|
public void Constructor_ThrowsArgumentNullException_WhenBetsIsNull()
|
|
{
|
|
var act = () => new OddsSnapshot(SampleEventId, SampleCapturedAt, OddsSource.PreMatch, null!);
|
|
act.Should().Throw<ArgumentNullException>()
|
|
.WithParameterName("bets");
|
|
}
|
|
|
|
[Fact]
|
|
public void OddsSnapshot_IsImmutable_NoSettablePublicProperties()
|
|
{
|
|
var snapshotType = typeof(OddsSnapshot);
|
|
var settableProperties = snapshotType.GetProperties()
|
|
.Where(p => p.CanWrite && p.GetSetMethod(nonPublic: false) is not null)
|
|
.ToList();
|
|
|
|
settableProperties.Should().BeEmpty("OddsSnapshot must be immutable.");
|
|
}
|
|
}
|