using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using FluentAssertions; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Moq; using NexusReader.Data.Persistence; using NexusReader.Domain.Entities; using NexusReader.Application.Queries.Reader; using NexusReader.Infrastructure.Services; using Xunit; namespace NexusReader.Application.Tests.Services; public class EpubReaderServiceTests : IDisposable { private readonly SqliteConnection _connection; private readonly DbContextOptions _contextOptions; private readonly Mock> _dbContextFactoryMock; private readonly Mock> _loggerMock; public EpubReaderServiceTests() { _connection = new SqliteConnection("DataSource=:memory:"); _connection.Open(); _contextOptions = new DbContextOptionsBuilder() .UseSqlite(_connection) .Options; // Seed initial database schema using var context = new AppDbContext(_contextOptions); context.Database.EnsureCreated(); _dbContextFactoryMock = new Mock>(); _dbContextFactoryMock.Setup(f => f.CreateDbContextAsync(It.IsAny())) .ReturnsAsync(() => new AppDbContext(_contextOptions)); _dbContextFactoryMock.Setup(f => f.CreateDbContext()) .Returns(() => new AppDbContext(_contextOptions)); _loggerMock = new Mock>(); } [Fact] public async Task GetEpubContentAsync_RewritesImageUrlsAndExtractsImages() { // Arrange var ebookId = Guid.NewGuid(); var userId = "test-user-id"; using (var context = new AppDbContext(_contextOptions)) { var user = new NexusUser { Id = userId, UserName = "testuser", Email = "test@nexus.com", TenantId = "tenant-123", SubscriptionPlanId = 1 }; context.Users.Add(user); var author = new Author { Id = 10, Name = "Giorgio Vasari" }; context.Authors.Add(author); var ebook = new Ebook { Id = ebookId, UserId = userId, Title = "Test Book", AuthorId = author.Id, FilePath = "assets/book.epub", AddedDate = DateTime.UtcNow, LastReadDate = DateTime.UtcNow, Progress = 0, LastChapter = "Introduction" }; context.Ebooks.Add(ebook); await context.SaveChangesAsync(); } var service = new EpubReaderService(_dbContextFactoryMock.Object, _loggerMock.Object); // Act var result = await service.GetEpubContentAsync(ebookId, 0, userId); // Assert result.IsSuccess.Should().BeTrue(); result.Value.Should().NotBeNull(); result.Value.Blocks.Should().NotBeEmpty(); // Check that any img tags extracted are preserved and rewritten var hasImages = false; foreach (var block in result.Value.Blocks) { if (block is TextSegmentBlock textBlock && textBlock.Content.Contains("