- StoryServiceTests.cs: 536 lines, comprehensive tests for StoryService - StoryGenerationServiceTests.cs: 469 lines, tests for AI story generation - StoryUnlockServiceTests.cs: 292 lines, tests for story unlock logic - StoryRepositoryTests.cs: 120 lines, tests for EF Core repository - StoryProgressRepositoryTests.cs: 74 lines, tests for progress repository - AppDbContext.cs: Made DbSet properties virtual for Moq compatibility - Fixed return types in StoryRepository and StoryProgressRepository - Updated docs/features/story-integration.md for Phase 3 completion - All 324 unit tests pass Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
536 lines
19 KiB
C#
536 lines
19 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using GermanApp.Application.DTOs;
|
|
using GermanApp.Application.Services;
|
|
using GermanApp.Domain.Entities;
|
|
using GermanApp.Domain.Interfaces;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
using Moq;
|
|
|
|
namespace GermanApp.Tests.Unit.Application.Services;
|
|
|
|
[TestClass]
|
|
public class StoryServiceTests
|
|
{
|
|
private Mock<IStoryRepository> _mockStoryRepository;
|
|
private Mock<IStoryProgressRepository> _mockProgressRepository;
|
|
private Mock<ILogger<StoryService>> _mockLogger;
|
|
private StoryService _service;
|
|
|
|
[TestInitialize]
|
|
public void Setup()
|
|
{
|
|
_mockStoryRepository = new Mock<IStoryRepository>();
|
|
_mockProgressRepository = new Mock<IStoryProgressRepository>();
|
|
_mockLogger = new Mock<ILogger<StoryService>>();
|
|
_service = new StoryService(
|
|
_mockStoryRepository.Object,
|
|
_mockProgressRepository.Object,
|
|
_mockLogger.Object);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetByIdAsync_WithExistingId_ReturnsSegment()
|
|
{
|
|
// Arrange
|
|
var segment = StorySegment.Create(1, 1, "Test content", 1, "Test Title", "Test Theme");
|
|
typeof(StorySegment).GetProperty("Id")?.SetValue(segment, 1);
|
|
|
|
_mockStoryRepository.Setup(s => s.GetByIdAsync(1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(segment);
|
|
|
|
// Act
|
|
var result = await _service.GetByIdAsync(1);
|
|
|
|
// Assert
|
|
Assert.IsNotNull(result);
|
|
Assert.AreEqual(1, result.Id);
|
|
Assert.AreEqual("Test content", result.Content);
|
|
Assert.AreEqual("Test Title", result.Title);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetByIdAsync_WithNonExistingId_ReturnsNull()
|
|
{
|
|
// Arrange
|
|
_mockStoryRepository.Setup(s => s.GetByIdAsync(999, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync((StorySegment?)null);
|
|
|
|
// Act
|
|
var result = await _service.GetByIdAsync(999);
|
|
|
|
// Assert
|
|
Assert.IsNull(result);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetByLevelAsync_WithExistingLevel_ReturnsSegments()
|
|
{
|
|
// Arrange
|
|
var segment1 = StorySegment.Create(1, 1, "Content 1", 1, "Title 1", "Theme");
|
|
typeof(StorySegment).GetProperty("Id")?.SetValue(segment1, 1);
|
|
var segment2 = StorySegment.Create(1, 2, "Content 2", 2, "Title 2", "Theme");
|
|
typeof(StorySegment).GetProperty("Id")?.SetValue(segment2, 2);
|
|
|
|
_mockStoryRepository.Setup(s => s.GetByLevelAsync(1, false, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(new List<StorySegment> { segment1, segment2 });
|
|
|
|
// Act
|
|
var result = await _service.GetByLevelAsync(1);
|
|
|
|
// Assert
|
|
Assert.IsNotNull(result);
|
|
Assert.AreEqual(2, result.Count);
|
|
Assert.AreEqual("Content 1", result[0].Content);
|
|
Assert.AreEqual("Content 2", result[1].Content);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetByLevelAsync_WithNoSegments_ReturnsEmptyList()
|
|
{
|
|
// Arrange
|
|
_mockStoryRepository.Setup(s => s.GetByLevelAsync(1, false, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(new List<StorySegment>());
|
|
|
|
// Act
|
|
var result = await _service.GetByLevelAsync(1);
|
|
|
|
// Assert
|
|
Assert.IsNotNull(result);
|
|
Assert.AreEqual(0, result.Count);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetByLessonAsync_WithExistingLesson_ReturnsSegments()
|
|
{
|
|
// Arrange
|
|
var segment = StorySegment.Create(1, 1, "Test content", 1, "Test Title", "Theme");
|
|
typeof(StorySegment).GetProperty("Id")?.SetValue(segment, 1);
|
|
|
|
_mockStoryRepository.Setup(s => s.GetByLessonAsync(1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(new List<StorySegment> { segment });
|
|
|
|
// Act
|
|
var result = await _service.GetByLessonAsync(1);
|
|
|
|
// Assert
|
|
Assert.IsNotNull(result);
|
|
Assert.AreEqual(1, result.Count);
|
|
Assert.AreEqual("Test content", result[0].Content);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task CreateAsync_WithValidData_CreatesSegment()
|
|
{
|
|
// Arrange
|
|
var dto = new CreateStorySegmentDto(1, 1, "New content", 1, "New Title", "New Theme");
|
|
var createdSegment = StorySegment.Create(1, 1, "New content", 1, "New Title", "New Theme");
|
|
typeof(StorySegment).GetProperty("Id")?.SetValue(createdSegment, 10);
|
|
|
|
_mockStoryRepository.Setup(s => s.GetByOrderRangeAsync(1, 1, 1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(new List<StorySegment>()); // No existing segment
|
|
_mockStoryRepository.Setup(s => s.AddAsync(It.IsAny<StorySegment>(), It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(createdSegment);
|
|
|
|
// Act
|
|
var result = await _service.CreateAsync(dto);
|
|
|
|
// Assert
|
|
Assert.IsNotNull(result);
|
|
Assert.AreEqual(10, result.Id);
|
|
Assert.AreEqual("New content", result.Content);
|
|
_mockStoryRepository.Verify(s => s.AddAsync(It.IsAny<StorySegment>(), It.IsAny<CancellationToken>()), Times.Once);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task CreateAsync_WithDuplicateOrder_ThrowsException()
|
|
{
|
|
// Arrange
|
|
var dto = new CreateStorySegmentDto(1, 1, "New content", 1, "New Title", "New Theme");
|
|
var existingSegment = StorySegment.Create(1, 1, "Existing", 1, "Existing", "Theme");
|
|
typeof(StorySegment).GetProperty("Id")?.SetValue(existingSegment, 1);
|
|
|
|
_mockStoryRepository.Setup(s => s.GetByOrderRangeAsync(1, 1, 1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(new List<StorySegment> { existingSegment });
|
|
|
|
// Act & Assert
|
|
try
|
|
{
|
|
await _service.CreateAsync(dto);
|
|
Assert.Fail("Expected InvalidOperationException was not thrown");
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
Assert.IsTrue(ex.Message.Contains("already exists"));
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task UpdateAsync_WithExistingId_UpdatesSegment()
|
|
{
|
|
// Arrange
|
|
var existingSegment = StorySegment.Create(1, 1, "Old content", 1, "Old Title", "Theme");
|
|
typeof(StorySegment).GetProperty("Id")?.SetValue(existingSegment, 1);
|
|
var dto = new UpdateStorySegmentDto(Content: "New content", Title: "New Title");
|
|
|
|
_mockStoryRepository.Setup(s => s.GetByIdAsync(1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(existingSegment);
|
|
_mockStoryRepository.Setup(s => s.UpdateAsync(It.IsAny<StorySegment>(), It.IsAny<CancellationToken>()))
|
|
.Returns(Task.CompletedTask);
|
|
|
|
// Act
|
|
var result = await _service.UpdateAsync(1, dto);
|
|
|
|
// Assert
|
|
Assert.IsNotNull(result);
|
|
Assert.AreEqual("New content", result.Content);
|
|
Assert.AreEqual("New Title", result.Title);
|
|
_mockStoryRepository.Verify(s => s.UpdateAsync(It.IsAny<StorySegment>(), It.IsAny<CancellationToken>()), Times.Once);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task UpdateAsync_WithNonExistingId_ReturnsNull()
|
|
{
|
|
// Arrange
|
|
var dto = new UpdateStorySegmentDto(Content: "New content");
|
|
|
|
_mockStoryRepository.Setup(s => s.GetByIdAsync(999, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync((StorySegment?)null);
|
|
|
|
// Act
|
|
var result = await _service.UpdateAsync(999, dto);
|
|
|
|
// Assert
|
|
Assert.IsNull(result);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task DeleteAsync_WithExistingId_DeletesSegment()
|
|
{
|
|
// Arrange
|
|
_mockStoryRepository.Setup(s => s.ExistsAsync(1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(true);
|
|
_mockStoryRepository.Setup(s => s.DeleteAsync(1, It.IsAny<CancellationToken>()))
|
|
.Returns(Task.CompletedTask);
|
|
|
|
// Act
|
|
var result = await _service.DeleteAsync(1);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result);
|
|
_mockStoryRepository.Verify(s => s.DeleteAsync(1, It.IsAny<CancellationToken>()), Times.Once);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task DeleteAsync_WithNonExistingId_ReturnsFalse()
|
|
{
|
|
// Arrange
|
|
_mockStoryRepository.Setup(s => s.ExistsAsync(999, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(false);
|
|
|
|
// Act
|
|
var result = await _service.DeleteAsync(999);
|
|
|
|
// Assert
|
|
Assert.IsFalse(result);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetNextSegmentToUnlockAsync_WithValidLesson_ReturnsSegment()
|
|
{
|
|
// Arrange
|
|
var segment = StorySegment.Create(1, 2, "Next content", 2, "Next Title", "Theme");
|
|
typeof(StorySegment).GetProperty("Id")?.SetValue(segment, 2);
|
|
|
|
_mockStoryRepository.Setup(s => s.GetNextSegmentToUnlockAsync(1, 1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(segment);
|
|
|
|
// Act
|
|
var result = await _service.GetNextSegmentToUnlockAsync(1, 1);
|
|
|
|
// Assert
|
|
Assert.IsNotNull(result);
|
|
Assert.AreEqual(2, result.Id);
|
|
Assert.AreEqual("Next content", result.Content);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetNextSegmentToUnlockAsync_WithNoSegment_ReturnsNull()
|
|
{
|
|
// Arrange
|
|
_mockStoryRepository.Setup(s => s.GetNextSegmentToUnlockAsync(1, 10, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync((StorySegment?)null);
|
|
|
|
// Act
|
|
var result = await _service.GetNextSegmentToUnlockAsync(1, 10);
|
|
|
|
// Assert
|
|
Assert.IsNull(result);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task UpdateAudioUrlAsync_WithExistingSegment_UpdatesUrl()
|
|
{
|
|
// Arrange
|
|
var segment = StorySegment.Create(1, 1, "Content", 1, "Title", "Theme");
|
|
typeof(StorySegment).GetProperty("Id")?.SetValue(segment, 1);
|
|
|
|
_mockStoryRepository.Setup(s => s.GetByIdAsync(1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(segment);
|
|
_mockStoryRepository.Setup(s => s.UpdateAsync(It.IsAny<StorySegment>(), It.IsAny<CancellationToken>()))
|
|
.Returns(Task.CompletedTask);
|
|
|
|
// Act
|
|
var result = await _service.UpdateAudioUrlAsync(1, "/audio/test.wav");
|
|
|
|
// Assert
|
|
Assert.IsNotNull(result);
|
|
Assert.AreEqual("/audio/test.wav", result.AudioUrl);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task UpdateAudioUrlAsync_WithNonExistingSegment_ReturnsNull()
|
|
{
|
|
// Arrange
|
|
_mockStoryRepository.Setup(s => s.GetByIdAsync(999, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync((StorySegment?)null);
|
|
|
|
// Act
|
|
var result = await _service.UpdateAudioUrlAsync(999, "/audio/test.wav");
|
|
|
|
// Assert
|
|
Assert.IsNull(result);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task MarkSegmentAsCompletedAsync_WithExistingProgress_MarksAsCompleted()
|
|
{
|
|
// Arrange
|
|
var progress = StoryProgress.Create(1, 1, 1);
|
|
typeof(StoryProgress).GetProperty("Id")?.SetValue(progress, 1);
|
|
|
|
_mockProgressRepository.Setup(p => p.GetByUserAndSegmentAsync(1, 1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(progress);
|
|
_mockProgressRepository.Setup(p => p.UpdateAsync(It.IsAny<StoryProgress>(), It.IsAny<CancellationToken>()))
|
|
.Returns(Task.CompletedTask);
|
|
|
|
// Act
|
|
var result = await _service.MarkSegmentAsCompletedAsync(1, 1);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result);
|
|
Assert.IsTrue(progress.IsCompleted);
|
|
Assert.IsNotNull(progress.CompletedAt);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task MarkSegmentAsCompletedAsync_WithNonExistingProgress_ReturnsFalse()
|
|
{
|
|
// Arrange
|
|
_mockProgressRepository.Setup(p => p.GetByUserAndSegmentAsync(1, 999, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync((StoryProgress?)null);
|
|
|
|
// Act
|
|
var result = await _service.MarkSegmentAsCompletedAsync(1, 999);
|
|
|
|
// Assert
|
|
Assert.IsFalse(result);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task MarkSegmentAsCompletedAsync_WithAlreadyCompleted_ReturnsFalse()
|
|
{
|
|
// Arrange
|
|
var progress = StoryProgress.Create(1, 1, 1);
|
|
typeof(StoryProgress).GetProperty("Id")?.SetValue(progress, 1);
|
|
progress.MarkAsCompleted();
|
|
|
|
_mockProgressRepository.Setup(p => p.GetByUserAndSegmentAsync(1, 1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(progress);
|
|
|
|
// Act
|
|
var result = await _service.MarkSegmentAsCompletedAsync(1, 1);
|
|
|
|
// Assert
|
|
Assert.IsFalse(result);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task UnlockNextSegmentAsync_WithValidLesson_UnlocksSegment()
|
|
{
|
|
// Arrange
|
|
var segment = StorySegment.Create(1, 2, "Next content", 2, "Next Title", "Theme");
|
|
typeof(StorySegment).GetProperty("Id")?.SetValue(segment, 2);
|
|
|
|
_mockStoryRepository.Setup(s => s.GetNextSegmentToUnlockAsync(1, 1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(segment);
|
|
_mockProgressRepository.Setup(p => p.IsSegmentUnlockedAsync(1, 2, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(false);
|
|
_mockProgressRepository.Setup(p => p.AddAsync(It.IsAny<StoryProgress>(), It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync((StoryProgress p, CancellationToken ct) => p);
|
|
|
|
// Act
|
|
var result = await _service.UnlockNextSegmentAsync(1, 1, 1);
|
|
|
|
// Assert
|
|
Assert.IsNotNull(result);
|
|
Assert.AreEqual(2, result.Id);
|
|
_mockProgressRepository.Verify(p => p.AddAsync(It.IsAny<StoryProgress>(), It.IsAny<CancellationToken>()), Times.Once);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task UnlockNextSegmentAsync_WithAlreadyUnlocked_ReturnsSegmentWithoutAdding()
|
|
{
|
|
// Arrange
|
|
var segment = StorySegment.Create(1, 2, "Next content", 2, "Next Title", "Theme");
|
|
typeof(StorySegment).GetProperty("Id")?.SetValue(segment, 2);
|
|
|
|
_mockStoryRepository.Setup(s => s.GetNextSegmentToUnlockAsync(1, 1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(segment);
|
|
_mockProgressRepository.Setup(p => p.IsSegmentUnlockedAsync(1, 2, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(true);
|
|
|
|
// Act
|
|
var result = await _service.UnlockNextSegmentAsync(1, 1, 1);
|
|
|
|
// Assert
|
|
Assert.IsNotNull(result);
|
|
Assert.AreEqual(2, result.Id);
|
|
_mockProgressRepository.Verify(p => p.AddAsync(It.IsAny<StoryProgress>(), It.IsAny<CancellationToken>()), Times.Never);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task UnlockNextSegmentAsync_WithNoSegment_ReturnsNull()
|
|
{
|
|
// Arrange
|
|
_mockStoryRepository.Setup(s => s.GetNextSegmentToUnlockAsync(1, 10, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync((StorySegment?)null);
|
|
|
|
// Act
|
|
var result = await _service.UnlockNextSegmentAsync(1, 1, 10);
|
|
|
|
// Assert
|
|
Assert.IsNull(result);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetUserProgressAsync_WithSegments_ReturnsProgress()
|
|
{
|
|
// Arrange
|
|
var segment1 = StorySegment.Create(1, 1, "Content 1", 1, "Title 1", "Theme");
|
|
typeof(StorySegment).GetProperty("Id")?.SetValue(segment1, 1);
|
|
var segment2 = StorySegment.Create(1, 2, "Content 2", 2, "Title 2", "Theme");
|
|
typeof(StorySegment).GetProperty("Id")?.SetValue(segment2, 2);
|
|
|
|
var progress1 = StoryProgress.Create(1, 1, 1);
|
|
typeof(StoryProgress).GetProperty("Id")?.SetValue(progress1, 1);
|
|
progress1.MarkAsCompleted();
|
|
|
|
_mockStoryRepository.Setup(s => s.GetByLevelAsync(1, false, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(new List<StorySegment> { segment1, segment2 });
|
|
_mockProgressRepository.Setup(p => p.GetByUserAndLevelAsync(1, 1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(new List<StoryProgress> { progress1 });
|
|
_mockProgressRepository.Setup(p => p.IsSegmentUnlockedAsync(1, 1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(true);
|
|
_mockProgressRepository.Setup(p => p.IsSegmentUnlockedAsync(1, 2, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(false);
|
|
_mockProgressRepository.Setup(p => p.IsSegmentCompletedAsync(1, 1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(true);
|
|
_mockProgressRepository.Setup(p => p.IsSegmentCompletedAsync(1, 2, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(false);
|
|
_mockProgressRepository.Setup(p => p.GetHighestUnlockedOrderAsync(1, 1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(1);
|
|
|
|
// Act
|
|
var result = await _service.GetUserProgressAsync(1, 1);
|
|
|
|
// Assert
|
|
Assert.IsNotNull(result);
|
|
Assert.AreEqual(1, result.LevelId);
|
|
Assert.AreEqual(2, result.TotalSegments);
|
|
Assert.AreEqual(1, result.UnlockedSegments);
|
|
Assert.AreEqual(2, result.Segments.Count);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetSegmentsNeedingAudioAsync_WithSegmentsNeedingAudio_ReturnsSegments()
|
|
{
|
|
// Arrange
|
|
var segment1 = StorySegment.Create(1, 1, "Content 1", 1, "Title 1", "Theme");
|
|
typeof(StorySegment).GetProperty("Id")?.SetValue(segment1, 1);
|
|
var segment2 = StorySegment.Create(1, 2, "Content 2", 2, "Title 2", "Theme");
|
|
typeof(StorySegment).GetProperty("Id")?.SetValue(segment2, 2);
|
|
segment2.UpdateAudioUrl("/audio/existing.wav");
|
|
|
|
_mockStoryRepository.Setup(s => s.GetSegmentsNeedingAudioAsync(It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(new List<StorySegment> { segment1 });
|
|
|
|
// Act
|
|
var result = await _service.GetSegmentsNeedingAudioAsync();
|
|
|
|
// Assert
|
|
Assert.IsNotNull(result);
|
|
Assert.AreEqual(1, result.Count);
|
|
Assert.IsNull(result[0].AudioUrl);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task IsSegmentUnlockedAsync_WithUnlockedSegment_ReturnsTrue()
|
|
{
|
|
// Arrange
|
|
_mockProgressRepository.Setup(p => p.IsSegmentUnlockedAsync(1, 1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(true);
|
|
|
|
// Act
|
|
var result = await _service.IsSegmentUnlockedAsync(1, 1);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task IsSegmentUnlockedAsync_WithLockedSegment_ReturnsFalse()
|
|
{
|
|
// Arrange
|
|
_mockProgressRepository.Setup(p => p.IsSegmentUnlockedAsync(1, 999, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(false);
|
|
|
|
// Act
|
|
var result = await _service.IsSegmentUnlockedAsync(1, 999);
|
|
|
|
// Assert
|
|
Assert.IsFalse(result);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task IsSegmentCompletedAsync_WithCompletedSegment_ReturnsTrue()
|
|
{
|
|
// Arrange
|
|
_mockProgressRepository.Setup(p => p.IsSegmentCompletedAsync(1, 1, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(true);
|
|
|
|
// Act
|
|
var result = await _service.IsSegmentCompletedAsync(1, 1);
|
|
|
|
// Assert
|
|
Assert.IsTrue(result);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task IsSegmentCompletedAsync_WithIncompleteSegment_ReturnsFalse()
|
|
{
|
|
// Arrange
|
|
_mockProgressRepository.Setup(p => p.IsSegmentCompletedAsync(1, 999, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(false);
|
|
|
|
// Act
|
|
var result = await _service.IsSegmentCompletedAsync(1, 999);
|
|
|
|
// Assert
|
|
Assert.IsFalse(result);
|
|
}
|
|
}
|