using DocumentService.Application.Common.DTOs; using DocumentService.Application.Common.Interfaces; using DocumentService.Application.ValidatePdf.Queries; using DocumentService.Domain.Common.Exceptions; using FluentAssertions; using Moq; using Xunit; namespace DocumentService.Tests.Unit.Application.Features.ValidatePdf; public class ValidatePdfHandlerTests { private readonly Mock _mockPdfProcessor; private readonly ValidatePdfQueryHandler _handler; public ValidatePdfHandlerTests() { _mockPdfProcessor = new Mock(); _handler = new ValidatePdfQueryHandler(_mockPdfProcessor.Object); } [Fact] public async Task Handle_ValidPdf_ReturnsResult() { // Arrange var query = new ValidatePdfQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) }; var expected = new PdfValidationResult(5, 1024, 1024 / 1024.0 / 1024.0, "1.4", false, 0, false); _mockPdfProcessor.Setup(x => x.ValidateAsync(It.IsAny())).ReturnsAsync(expected); // Act var result = await _handler.Handle(query, CancellationToken.None); // Assert result.Should().NotBeNull(); result.PageCount.Should().Be(5); result.FileSizeBytes.Should().Be(1024); result.PdfVersion.Should().Be("1.4"); result.HasAttachments.Should().BeFalse(); result.AttachmentCount.Should().Be(0); result.IsEncrypted.Should().BeFalse(); _mockPdfProcessor.Verify(x => x.ValidateAsync(It.IsAny()), Times.Once); } [Fact] public async Task Handle_EncryptedPdf_ReturnsIsEncryptedTrue() { // Arrange var query = new ValidatePdfQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) }; var expected = new PdfValidationResult(1, 512, 512 / 1024.0 / 1024.0, "1.7", false, 0, true); _mockPdfProcessor.Setup(x => x.ValidateAsync(It.IsAny())).ReturnsAsync(expected); // Act var result = await _handler.Handle(query, CancellationToken.None); // Assert result.IsEncrypted.Should().BeTrue(); result.PageCount.Should().Be(1); _mockPdfProcessor.Verify(x => x.ValidateAsync(It.IsAny()), Times.Once); } [Fact] public async Task Handle_PdfWithAttachments_ReturnsAttachmentData() { // Arrange var query = new ValidatePdfQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) }; var expected = new PdfValidationResult(2, 4096, 4096 / 1024.0 / 1024.0, "1.6", true, 3, false); _mockPdfProcessor.Setup(x => x.ValidateAsync(It.IsAny())).ReturnsAsync(expected); // Act var result = await _handler.Handle(query, CancellationToken.None); // Assert result.HasAttachments.Should().BeTrue(); result.AttachmentCount.Should().Be(3); _mockPdfProcessor.Verify(x => x.ValidateAsync(It.IsAny()), Times.Once); } [Fact] public async Task Handle_ProcessorThrowsBadRequest_PropagatesException() { // Arrange var query = new ValidatePdfQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) }; _mockPdfProcessor.Setup(x => x.ValidateAsync(It.IsAny())) .ThrowsAsync(new BadRequestException("Invalid PDF format")); // Act & Assert var ex = await Assert.ThrowsAsync( () => _handler.Handle(query, CancellationToken.None)); ex.Message.Should().Be("Invalid PDF format"); _mockPdfProcessor.Verify(x => x.ValidateAsync(It.IsAny()), Times.Once); } [Fact] public async Task Handle_ProcessorThrowsGenericException_PropagatesException() { // Arrange var query = new ValidatePdfQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) }; _mockPdfProcessor.Setup(x => x.ValidateAsync(It.IsAny())) .ThrowsAsync(new InvalidOperationException("Unexpected error")); // Act & Assert await Assert.ThrowsAsync( () => _handler.Handle(query, CancellationToken.None)); } }