using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using GermanApp.Domain.Entities; using GermanApp.Infrastructure.Data.DbContext; using GermanApp.Infrastructure.Data.Repositories; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; namespace GermanApp.Tests.Unit.Infrastructure.Data.Repositories; [TestClass] public class StoryRepositoryTests { private StorySegment CreateSegment(int id, int levelId, int? lessonId, int order) { var segment = StorySegment.Create(levelId, lessonId, "Content", order, "Title", "Theme"); typeof(StorySegment).GetProperty("Id")?.SetValue(segment, id); return segment; } [TestMethod] public async Task AddAsync_WithNewSegment_AddsToDbSet() { // Arrange var segment = CreateSegment(0, 1, 1, 1); var mockDbSet = new Mock>(); var options = new DbContextOptions(); var mockContext = new Mock(options); mockDbSet.Setup(d => d.AddAsync(segment, It.IsAny())) .Returns(ValueTask.FromResult((EntityEntry?)null)); mockContext.Setup(c => c.StorySegments).Returns(mockDbSet.Object); mockContext.Setup(c => c.SaveChangesAsync(It.IsAny())) .ReturnsAsync(1); var repository = new StoryRepository(mockContext.Object); // Act var result = await repository.AddAsync(segment); // Assert Assert.IsNotNull(result); mockDbSet.Verify(d => d.AddAsync(segment, It.IsAny()), Times.Once); mockContext.Verify(c => c.SaveChangesAsync(It.IsAny()), Times.Once); } [TestMethod] public async Task UpdateAsync_WithExistingSegment_UpdatesDbSet() { // Arrange var segment = CreateSegment(1, 1, 1, 1); var mockDbSet = new Mock>(); var options = new DbContextOptions(); var mockContext = new Mock(options); mockContext.Setup(c => c.StorySegments).Returns(mockDbSet.Object); mockContext.Setup(c => c.SaveChangesAsync(It.IsAny())) .ReturnsAsync(1); var repository = new StoryRepository(mockContext.Object); // Act await repository.UpdateAsync(segment); // Assert mockDbSet.Verify(d => d.Update(segment), Times.Once); mockContext.Verify(c => c.SaveChangesAsync(It.IsAny()), Times.Once); } [TestMethod] public async Task DeleteAsync_WithExistingId_RemovesFromDbSet() { // Arrange var segment = CreateSegment(1, 1, 1, 1); var mockDbSet = new Mock>(); var options = new DbContextOptions(); var mockContext = new Mock(options); mockDbSet.Setup(d => d.FindAsync(new object[] { 1 }, It.IsAny())) .ReturnsAsync(segment); mockContext.Setup(c => c.StorySegments).Returns(mockDbSet.Object); mockContext.Setup(c => c.SaveChangesAsync(It.IsAny())) .ReturnsAsync(1); var repository = new StoryRepository(mockContext.Object); // Act await repository.DeleteAsync(1); // Assert mockDbSet.Verify(d => d.Remove(segment), Times.Once); mockContext.Verify(c => c.SaveChangesAsync(It.IsAny()), Times.Once); } [TestMethod] public async Task DeleteAsync_WithNonExistingId_DoesNotThrow() { // Arrange var mockDbSet = new Mock>(); var options = new DbContextOptions(); var mockContext = new Mock(options); mockDbSet.Setup(d => d.FindAsync(new object[] { 999 }, It.IsAny())) .ReturnsAsync((StorySegment?)null); mockContext.Setup(c => c.StorySegments).Returns(mockDbSet.Object); mockContext.Setup(c => c.SaveChangesAsync(It.IsAny())) .ReturnsAsync(1); var repository = new StoryRepository(mockContext.Object); // Act & Assert (should not throw) await repository.DeleteAsync(999); mockDbSet.Verify(d => d.Remove(It.IsAny()), Times.Never); } }