Files
2026-03-01 15:14:42 -04:00

215 lines
7.6 KiB
C#

using Moq;
using SportsDivision.Application.Services;
using SportsDivision.Domain.Entities;
using SportsDivision.Domain.Enums;
using SportsDivision.Domain.Interfaces;
namespace SportsDivision.Application.Tests;
public class HeatAdvancementTests
{
private readonly Mock<IUnitOfWork> _mockUow;
private readonly HeatManagementService _service;
public HeatAdvancementTests()
{
_mockUow = new Mock<IUnitOfWork>();
_service = new HeatManagementService(_mockUow.Object, null!);
}
private Round CreateRoundWithHeats(int topN, int fastestLosers, List<Heat> heats)
{
return new Round
{
RoundId = 1,
TournamentEventLevelId = 1,
RoundOrder = 1,
AdvanceTopN = topN,
AdvanceFastestLosers = fastestLosers,
Heats = heats
};
}
private Heat CreateHeat(int heatId, int heatNumber, List<HeatLane> lanes)
{
var heat = new Heat
{
HeatId = heatId,
HeatNumber = heatNumber,
Status = HeatStatus.Completed,
HeatLanes = lanes
};
foreach (var lane in lanes)
lane.Heat = heat;
return heat;
}
private HeatLane CreateLane(int laneId, int regId, decimal? time, bool isDNS = false, bool isDNF = false, bool isDQ = false)
{
return new HeatLane
{
HeatLaneId = laneId,
EventRegistrationId = regId,
LaneNumber = laneId,
Time = time,
IsDNS = isDNS,
IsDNF = isDNF,
IsDQ = isDQ,
IsAdvanced = false
};
}
[Fact]
public async Task CalculateAdvancement_TopNFromEachHeat()
{
var heat1 = CreateHeat(1, 1, new List<HeatLane>
{
CreateLane(1, 101, 10.5m),
CreateLane(2, 102, 10.8m),
CreateLane(3, 103, 11.2m),
CreateLane(4, 104, 11.5m)
});
var heat2 = CreateHeat(2, 2, new List<HeatLane>
{
CreateLane(5, 201, 10.6m),
CreateLane(6, 202, 10.9m),
CreateLane(7, 203, 11.3m),
CreateLane(8, 204, 11.6m)
});
var round = CreateRoundWithHeats(topN: 2, fastestLosers: 0, new List<Heat> { heat1, heat2 });
_mockUow.Setup(u => u.Rounds.GetWithHeatsAsync(1)).ReturnsAsync(round);
_mockUow.Setup(u => u.HeatLanes.Update(It.IsAny<HeatLane>()));
_mockUow.Setup(u => u.SaveChangesAsync()).ReturnsAsync(1);
await _service.CalculateAdvancementAsync(1);
// Top 2 from heat 1: lanes 1 (10.5) and 2 (10.8)
Assert.True(heat1.HeatLanes.ElementAt(0).IsAdvanced);
Assert.True(heat1.HeatLanes.ElementAt(1).IsAdvanced);
Assert.False(heat1.HeatLanes.ElementAt(2).IsAdvanced);
Assert.False(heat1.HeatLanes.ElementAt(3).IsAdvanced);
// Top 2 from heat 2: lanes 5 (10.6) and 6 (10.9)
Assert.True(heat2.HeatLanes.ElementAt(0).IsAdvanced);
Assert.True(heat2.HeatLanes.ElementAt(1).IsAdvanced);
Assert.False(heat2.HeatLanes.ElementAt(2).IsAdvanced);
Assert.False(heat2.HeatLanes.ElementAt(3).IsAdvanced);
}
[Fact]
public async Task CalculateAdvancement_TopNPlusFastestLosers()
{
var heat1 = CreateHeat(1, 1, new List<HeatLane>
{
CreateLane(1, 101, 10.5m),
CreateLane(2, 102, 10.8m),
CreateLane(3, 103, 11.0m), // 3rd in heat 1 → fastest loser candidate
CreateLane(4, 104, 11.5m)
});
var heat2 = CreateHeat(2, 2, new List<HeatLane>
{
CreateLane(5, 201, 10.6m),
CreateLane(6, 202, 10.9m),
CreateLane(7, 203, 11.1m), // 3rd in heat 2 → fastest loser candidate
CreateLane(8, 204, 11.8m)
});
var round = CreateRoundWithHeats(topN: 2, fastestLosers: 2, new List<Heat> { heat1, heat2 });
_mockUow.Setup(u => u.Rounds.GetWithHeatsAsync(1)).ReturnsAsync(round);
_mockUow.Setup(u => u.HeatLanes.Update(It.IsAny<HeatLane>()));
_mockUow.Setup(u => u.SaveChangesAsync()).ReturnsAsync(1);
await _service.CalculateAdvancementAsync(1);
// Top 2 from each heat advance as TopN
Assert.Equal(AdvanceReason.TopN, heat1.HeatLanes.ElementAt(0).AdvanceReason);
Assert.Equal(AdvanceReason.TopN, heat1.HeatLanes.ElementAt(1).AdvanceReason);
Assert.Equal(AdvanceReason.TopN, heat2.HeatLanes.ElementAt(0).AdvanceReason);
Assert.Equal(AdvanceReason.TopN, heat2.HeatLanes.ElementAt(1).AdvanceReason);
// Fastest 2 losers: lane 3 (11.0) and lane 7 (11.1)
Assert.True(heat1.HeatLanes.ElementAt(2).IsAdvanced);
Assert.Equal(AdvanceReason.FastestLoser, heat1.HeatLanes.ElementAt(2).AdvanceReason);
Assert.True(heat2.HeatLanes.ElementAt(2).IsAdvanced);
Assert.Equal(AdvanceReason.FastestLoser, heat2.HeatLanes.ElementAt(2).AdvanceReason);
// Last in each heat should NOT advance
Assert.False(heat1.HeatLanes.ElementAt(3).IsAdvanced);
Assert.False(heat2.HeatLanes.ElementAt(3).IsAdvanced);
}
[Fact]
public async Task CalculateAdvancement_DNSExcluded()
{
var heat1 = CreateHeat(1, 1, new List<HeatLane>
{
CreateLane(1, 101, 10.5m),
CreateLane(2, 102, null, isDNS: true), // DNS
CreateLane(3, 103, 11.0m),
});
var round = CreateRoundWithHeats(topN: 2, fastestLosers: 0, new List<Heat> { heat1 });
_mockUow.Setup(u => u.Rounds.GetWithHeatsAsync(1)).ReturnsAsync(round);
_mockUow.Setup(u => u.HeatLanes.Update(It.IsAny<HeatLane>()));
_mockUow.Setup(u => u.SaveChangesAsync()).ReturnsAsync(1);
await _service.CalculateAdvancementAsync(1);
Assert.True(heat1.HeatLanes.ElementAt(0).IsAdvanced);
Assert.False(heat1.HeatLanes.ElementAt(1).IsAdvanced); // DNS not advanced
Assert.True(heat1.HeatLanes.ElementAt(2).IsAdvanced);
}
[Fact]
public async Task CalculateAdvancement_DNFExcluded()
{
var heat1 = CreateHeat(1, 1, new List<HeatLane>
{
CreateLane(1, 101, 10.5m),
CreateLane(2, 102, 10.8m, isDNF: true), // DNF
CreateLane(3, 103, 11.0m),
});
var round = CreateRoundWithHeats(topN: 2, fastestLosers: 0, new List<Heat> { heat1 });
_mockUow.Setup(u => u.Rounds.GetWithHeatsAsync(1)).ReturnsAsync(round);
_mockUow.Setup(u => u.HeatLanes.Update(It.IsAny<HeatLane>()));
_mockUow.Setup(u => u.SaveChangesAsync()).ReturnsAsync(1);
await _service.CalculateAdvancementAsync(1);
Assert.True(heat1.HeatLanes.ElementAt(0).IsAdvanced);
Assert.False(heat1.HeatLanes.ElementAt(1).IsAdvanced); // DNF not advanced
Assert.True(heat1.HeatLanes.ElementAt(2).IsAdvanced);
}
[Fact]
public async Task CalculateAdvancement_DQExcluded()
{
var heat1 = CreateHeat(1, 1, new List<HeatLane>
{
CreateLane(1, 101, 10.5m),
CreateLane(2, 102, 10.2m, isDQ: true), // DQ - fastest time but disqualified
CreateLane(3, 103, 11.0m),
});
var round = CreateRoundWithHeats(topN: 2, fastestLosers: 0, new List<Heat> { heat1 });
_mockUow.Setup(u => u.Rounds.GetWithHeatsAsync(1)).ReturnsAsync(round);
_mockUow.Setup(u => u.HeatLanes.Update(It.IsAny<HeatLane>()));
_mockUow.Setup(u => u.SaveChangesAsync()).ReturnsAsync(1);
await _service.CalculateAdvancementAsync(1);
Assert.True(heat1.HeatLanes.ElementAt(0).IsAdvanced);
Assert.False(heat1.HeatLanes.ElementAt(1).IsAdvanced); // DQ not advanced
Assert.True(heat1.HeatLanes.ElementAt(2).IsAdvanced);
}
}