using Moq; using SportsDivision.Application.Services; using SportsDivision.Domain.Entities; using SportsDivision.Domain.Enums; using SportsDivision.Domain.Interfaces; namespace SportsDivision.Application.Tests; public class HighJumpEliminationTests { private readonly Mock _mockUow; private readonly HighJumpService _service; public HighJumpEliminationTests() { _mockUow = new Mock(); _service = new HighJumpService(_mockUow.Object, null!); } private HighJumpHeight CreateHeight(int heightId, decimal height, int sortOrder, HighJumpAttempt? attempt = null) { var h = new HighJumpHeight { HighJumpHeightId = heightId, Height = height, SortOrder = sortOrder, TournamentEventLevelId = 1, Attempts = new List() }; if (attempt != null) { attempt.HighJumpHeightId = heightId; h.Attempts.Add(attempt); } return h; } private HighJumpAttempt CreateAttempt(int regId, HighJumpAttemptResult? a1, HighJumpAttemptResult? a2 = null, HighJumpAttemptResult? a3 = null) { return new HighJumpAttempt { EventRegistrationId = regId, Attempt1 = a1, Attempt2 = a2, Attempt3 = a3 }; } [Fact] public async Task IsEliminated_ThreeConsecutiveFailsAtOneHeight_ReturnsTrue() { var heights = new List { CreateHeight(1, 1.50m, 1, CreateAttempt(1, HighJumpAttemptResult.Clear)), CreateHeight(2, 1.55m, 2, CreateAttempt(1, HighJumpAttemptResult.Fail, HighJumpAttemptResult.Fail, HighJumpAttemptResult.Fail)) }; _mockUow.Setup(u => u.HighJumpHeights.GetByTournamentEventLevelAsync(1)) .ReturnsAsync(heights); _mockUow.Setup(u => u.HighJumpHeights.GetWithAttemptsAsync(1)).ReturnsAsync(heights[0]); _mockUow.Setup(u => u.HighJumpHeights.GetWithAttemptsAsync(2)).ReturnsAsync(heights[1]); var result = await _service.IsEliminatedAsync(1, 1); Assert.True(result); } [Fact] public async Task IsEliminated_ClearsAllHeights_ReturnsFalse() { var heights = new List { CreateHeight(1, 1.50m, 1, CreateAttempt(1, HighJumpAttemptResult.Clear)), CreateHeight(2, 1.55m, 2, CreateAttempt(1, HighJumpAttemptResult.Fail, HighJumpAttemptResult.Clear)), CreateHeight(3, 1.60m, 3, CreateAttempt(1, HighJumpAttemptResult.Clear)) }; _mockUow.Setup(u => u.HighJumpHeights.GetByTournamentEventLevelAsync(1)) .ReturnsAsync(heights); _mockUow.Setup(u => u.HighJumpHeights.GetWithAttemptsAsync(1)).ReturnsAsync(heights[0]); _mockUow.Setup(u => u.HighJumpHeights.GetWithAttemptsAsync(2)).ReturnsAsync(heights[1]); _mockUow.Setup(u => u.HighJumpHeights.GetWithAttemptsAsync(3)).ReturnsAsync(heights[2]); var result = await _service.IsEliminatedAsync(1, 1); Assert.False(result); } [Fact] public async Task IsEliminated_TwoFailsThenClear_ResetsCount_ReturnsFalse() { var heights = new List { CreateHeight(1, 1.50m, 1, CreateAttempt(1, HighJumpAttemptResult.Fail, HighJumpAttemptResult.Fail, HighJumpAttemptResult.Clear)), CreateHeight(2, 1.55m, 2, CreateAttempt(1, HighJumpAttemptResult.Fail, HighJumpAttemptResult.Clear)) }; _mockUow.Setup(u => u.HighJumpHeights.GetByTournamentEventLevelAsync(1)) .ReturnsAsync(heights); _mockUow.Setup(u => u.HighJumpHeights.GetWithAttemptsAsync(1)).ReturnsAsync(heights[0]); _mockUow.Setup(u => u.HighJumpHeights.GetWithAttemptsAsync(2)).ReturnsAsync(heights[1]); var result = await _service.IsEliminatedAsync(1, 1); Assert.False(result); } [Fact] public async Task IsEliminated_NoAttempts_ReturnsFalse() { var heights = new List { CreateHeight(1, 1.50m, 1) }; _mockUow.Setup(u => u.HighJumpHeights.GetByTournamentEventLevelAsync(1)) .ReturnsAsync(heights); _mockUow.Setup(u => u.HighJumpHeights.GetWithAttemptsAsync(1)).ReturnsAsync(heights[0]); var result = await _service.IsEliminatedAsync(1, 1); Assert.False(result); } [Fact] public async Task IsEliminated_PassedHeight_FailCountDoesNotReset() { // If an athlete passes a height, fails should continue accumulating var heights = new List { CreateHeight(1, 1.50m, 1, CreateAttempt(1, HighJumpAttemptResult.Fail, HighJumpAttemptResult.Fail, HighJumpAttemptResult.Pass)), // Height 2: passed (no attempt recorded in this test) CreateHeight(2, 1.55m, 2, CreateAttempt(1, HighJumpAttemptResult.Fail)) }; _mockUow.Setup(u => u.HighJumpHeights.GetByTournamentEventLevelAsync(1)) .ReturnsAsync(heights); _mockUow.Setup(u => u.HighJumpHeights.GetWithAttemptsAsync(1)).ReturnsAsync(heights[0]); _mockUow.Setup(u => u.HighJumpHeights.GetWithAttemptsAsync(2)).ReturnsAsync(heights[1]); var result = await _service.IsEliminatedAsync(1, 1); // 2 fails at height 1 (pass doesn't reset) + 1 fail at height 2 = 3 consecutive fails Assert.True(result); } }