test: rewrite existing Application handler tests (no mapper mock, full assertions)
ValidatePdfHandlerTests: - Remove IMapper mock (handler no longer uses mapper) - Add: EncryptedPdf_ReturnsIsEncryptedTrue - Add: PdfWithAttachments_ReturnsAttachmentData - Add: ProcessorThrowsGenericException_PropagatesException ValidatePdfAQueryHandlerTests: - Remove IMapper mock - Strengthen assertions (Errors count, Warnings content) - Add: ProcessorThrowsGenericException_PropagatesException CheckPdfAttachmentsQueryHandlerTests: - Remove duplicate Handle_WithBase64Pdf test (identical to WithPdfBytes) - Add: ProcessorThrowsBadRequest_PropagatesException - Add: ProcessorThrowsGenericException_PropagatesException - Strengthen: assert individual attachment fields (FileName, MimeType, Size)
This commit is contained in:
@@ -2,16 +2,13 @@ using AutoMapper;
|
|||||||
using DocumentService.Application.CheckPdfAttachments.Queries;
|
using DocumentService.Application.CheckPdfAttachments.Queries;
|
||||||
using DocumentService.Application.Common.DTOs;
|
using DocumentService.Application.Common.DTOs;
|
||||||
using DocumentService.Application.Common.Interfaces;
|
using DocumentService.Application.Common.Interfaces;
|
||||||
|
using DocumentService.Domain.Common.Exceptions;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
namespace DocumentService.Tests.Unit.Application.CheckPdfAttachments;
|
namespace DocumentService.Tests.Unit.Application.CheckPdfAttachments;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unit tests for CheckPdfAttachmentsQueryHandler.
|
|
||||||
/// Tests handler logic with mocked dependencies (IPdfProcessor, IMapper).
|
|
||||||
/// </summary>
|
|
||||||
public class CheckPdfAttachmentsQueryHandlerTests
|
public class CheckPdfAttachmentsQueryHandlerTests
|
||||||
{
|
{
|
||||||
private readonly Mock<IPdfProcessor> _mockPdfProcessor;
|
private readonly Mock<IPdfProcessor> _mockPdfProcessor;
|
||||||
@@ -26,26 +23,16 @@ public class CheckPdfAttachmentsQueryHandlerTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Handle_WithPdfBytes_CallsProcessorAndMapper()
|
public async Task Handle_PdfWithAttachments_ReturnsAttachmentDetails()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
byte[] pdfBytes = "fake-pdf-content"u8.ToArray();
|
var query = new CheckPdfAttachmentsQuery { PdfStream = new MemoryStream("fake-pdf"u8.ToArray()) };
|
||||||
var query = new CheckPdfAttachmentsQuery { PdfStream = new MemoryStream(pdfBytes) };
|
|
||||||
|
|
||||||
var domainResult = new AttachmentInfo(
|
var domainResult = new AttachmentInfo(
|
||||||
hasAttachments: true,
|
hasAttachments: true, attachmentCount: 2,
|
||||||
attachmentCount: 2,
|
attachments: [new("invoice.xml", "text/xml", 1024), new("metadata.json", "application/json", 512)]);
|
||||||
attachments:
|
|
||||||
[
|
|
||||||
new("invoice.xml", "text/xml", 1024),
|
|
||||||
new("metadata.json", "application/json", 512)
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
var expectedDto = new AttachmentCheckResult
|
var expectedDto = new AttachmentCheckResult
|
||||||
{
|
{
|
||||||
HasAttachments = true,
|
HasAttachments = true, AttachmentCount = 2,
|
||||||
AttachmentCount = 2,
|
|
||||||
Attachments =
|
Attachments =
|
||||||
[
|
[
|
||||||
new() { FileName = "invoice.xml", MimeType = "text/xml", Size = 1024 },
|
new() { FileName = "invoice.xml", MimeType = "text/xml", Size = 1024 },
|
||||||
@@ -61,20 +48,22 @@ public class CheckPdfAttachmentsQueryHandlerTests
|
|||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().NotBeNull();
|
result.Should().NotBeNull();
|
||||||
result.Should().BeEquivalentTo(expectedDto);
|
result.HasAttachments.Should().BeTrue();
|
||||||
|
result.AttachmentCount.Should().Be(2);
|
||||||
|
result.Attachments.Should().HaveCount(2);
|
||||||
|
result.Attachments[0].FileName.Should().Be("invoice.xml");
|
||||||
|
result.Attachments[0].MimeType.Should().Be("text/xml");
|
||||||
|
result.Attachments[0].Size.Should().Be(1024);
|
||||||
_mockPdfProcessor.Verify(p => p.CheckAttachmentsAsync(It.IsAny<Stream>()), Times.Once);
|
_mockPdfProcessor.Verify(p => p.CheckAttachmentsAsync(It.IsAny<Stream>()), Times.Once);
|
||||||
_mockMapper.Verify(m => m.Map<AttachmentCheckResult>(domainResult), Times.Once);
|
_mockMapper.Verify(m => m.Map<AttachmentCheckResult>(domainResult), Times.Once);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Handle_WithBase64Pdf_DecodesAndCallsProcessor()
|
public async Task Handle_PdfWithNoAttachments_ReturnsEmptyResult()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
byte[] pdfBytes = "fake-pdf-content"u8.ToArray();
|
var query = new CheckPdfAttachmentsQuery { PdfStream = new MemoryStream("fake-pdf"u8.ToArray()) };
|
||||||
var query = new CheckPdfAttachmentsQuery { PdfStream = new MemoryStream(pdfBytes) };
|
var domainResult = AttachmentInfo.Empty;
|
||||||
|
|
||||||
var domainResult = new AttachmentInfo(false, 0, []);
|
|
||||||
var expectedDto = new AttachmentCheckResult { HasAttachments = false, AttachmentCount = 0, Attachments = [] };
|
var expectedDto = new AttachmentCheckResult { HasAttachments = false, AttachmentCount = 0, Attachments = [] };
|
||||||
|
|
||||||
_mockPdfProcessor.Setup(p => p.CheckAttachmentsAsync(It.IsAny<Stream>())).ReturnsAsync(domainResult);
|
_mockPdfProcessor.Setup(p => p.CheckAttachmentsAsync(It.IsAny<Stream>())).ReturnsAsync(domainResult);
|
||||||
@@ -83,40 +72,37 @@ public class CheckPdfAttachmentsQueryHandlerTests
|
|||||||
// Act
|
// Act
|
||||||
var result = await _sut.Handle(query, CancellationToken.None);
|
var result = await _sut.Handle(query, CancellationToken.None);
|
||||||
|
|
||||||
// Assert
|
|
||||||
result.Should().NotBeNull();
|
|
||||||
result.HasAttachments.Should().BeFalse();
|
|
||||||
result.AttachmentCount.Should().Be(0);
|
|
||||||
|
|
||||||
_mockPdfProcessor.Verify(p => p.CheckAttachmentsAsync(It.IsAny<Stream>()), Times.Once);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task Handle_WithEmptyAttachments_ReturnsEmptyList()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
byte[] pdfBytes = "fake-pdf-content"u8.ToArray();
|
|
||||||
var query = new CheckPdfAttachmentsQuery { PdfStream = new MemoryStream(pdfBytes) };
|
|
||||||
|
|
||||||
var domainResult = new AttachmentInfo(false, 0, []);
|
|
||||||
var expectedDto = new AttachmentCheckResult
|
|
||||||
{
|
|
||||||
HasAttachments = false,
|
|
||||||
AttachmentCount = 0,
|
|
||||||
Attachments = []
|
|
||||||
};
|
|
||||||
|
|
||||||
_mockPdfProcessor.Setup(p => p.CheckAttachmentsAsync(It.IsAny<Stream>())).ReturnsAsync(domainResult);
|
|
||||||
_mockMapper.Setup(m => m.Map<AttachmentCheckResult>(domainResult)).Returns(expectedDto);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = await _sut.Handle(query, CancellationToken.None);
|
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.HasAttachments.Should().BeFalse();
|
result.HasAttachments.Should().BeFalse();
|
||||||
result.AttachmentCount.Should().Be(0);
|
result.AttachmentCount.Should().Be(0);
|
||||||
result.Attachments.Should().BeEmpty();
|
result.Attachments.Should().BeEmpty();
|
||||||
|
_mockPdfProcessor.Verify(p => p.CheckAttachmentsAsync(It.IsAny<Stream>()), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Handle_ProcessorThrowsBadRequest_PropagatesException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var query = new CheckPdfAttachmentsQuery { PdfStream = new MemoryStream("fake-pdf"u8.ToArray()) };
|
||||||
|
_mockPdfProcessor.Setup(p => p.CheckAttachmentsAsync(It.IsAny<Stream>()))
|
||||||
|
.ThrowsAsync(new BadRequestException("PDF stream cannot be empty"));
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
var ex = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
|
() => _sut.Handle(query, CancellationToken.None));
|
||||||
|
ex.Message.Should().Be("PDF stream cannot be empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Handle_ProcessorThrowsGenericException_PropagatesException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var query = new CheckPdfAttachmentsQuery { PdfStream = new MemoryStream("fake-pdf"u8.ToArray()) };
|
||||||
|
_mockPdfProcessor.Setup(p => p.CheckAttachmentsAsync(It.IsAny<Stream>()))
|
||||||
|
.ThrowsAsync(new InvalidOperationException("Unexpected error"));
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
await Assert.ThrowsAsync<InvalidOperationException>(
|
||||||
|
() => _sut.Handle(query, CancellationToken.None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using AutoMapper;
|
|
||||||
using DocumentService.Application.Common.DTOs;
|
using DocumentService.Application.Common.DTOs;
|
||||||
using DocumentService.Application.Common.Interfaces;
|
using DocumentService.Application.Common.Interfaces;
|
||||||
using DocumentService.Application.ValidatePdf.Queries;
|
using DocumentService.Application.ValidatePdf.Queries;
|
||||||
@@ -12,47 +11,22 @@ namespace DocumentService.Tests.Unit.Application.Features.ValidatePdf;
|
|||||||
public class ValidatePdfHandlerTests
|
public class ValidatePdfHandlerTests
|
||||||
{
|
{
|
||||||
private readonly Mock<IPdfProcessor> _mockPdfProcessor;
|
private readonly Mock<IPdfProcessor> _mockPdfProcessor;
|
||||||
private readonly Mock<IMapper> _mockMapper;
|
|
||||||
private readonly ValidatePdfQueryHandler _handler;
|
private readonly ValidatePdfQueryHandler _handler;
|
||||||
|
|
||||||
public ValidatePdfHandlerTests()
|
public ValidatePdfHandlerTests()
|
||||||
{
|
{
|
||||||
_mockPdfProcessor = new Mock<IPdfProcessor>();
|
_mockPdfProcessor = new Mock<IPdfProcessor>();
|
||||||
_mockMapper = new Mock<IMapper>();
|
_handler = new ValidatePdfQueryHandler(_mockPdfProcessor.Object);
|
||||||
_handler = new ValidatePdfQueryHandler(_mockPdfProcessor.Object, _mockMapper.Object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Handle_ValidPdf_ReturnsPdfMetadata()
|
public async Task Handle_ValidPdf_ReturnsResult()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var pdfBytes = "%PDF"u8.ToArray(); // "%PDF"
|
var query = new ValidatePdfQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) };
|
||||||
var query = new ValidatePdfQuery { PdfStream = new MemoryStream(pdfBytes) };
|
var expected = new PdfValidationResult(5, 1024, 1024 / 1024.0 / 1024.0, "1.4", false, 0, false);
|
||||||
|
|
||||||
var domainMetadata = new PdfMetadata(
|
_mockPdfProcessor.Setup(x => x.ValidateAsync(It.IsAny<Stream>())).ReturnsAsync(expected);
|
||||||
pageCount: 5,
|
|
||||||
fileSizeBytes: 1024,
|
|
||||||
pdfVersion: "1.4",
|
|
||||||
hasAttachments: false,
|
|
||||||
attachmentCount: 0
|
|
||||||
);
|
|
||||||
|
|
||||||
var expectedDto = new PdfValidationResult(
|
|
||||||
PageCount: 5,
|
|
||||||
FileSizeBytes: 1024,
|
|
||||||
FileSizeMB: 0.00,
|
|
||||||
PdfVersion: "1.4",
|
|
||||||
HasAttachments: false,
|
|
||||||
AttachmentCount: 0
|
|
||||||
);
|
|
||||||
|
|
||||||
_mockPdfProcessor
|
|
||||||
.Setup(x => x.ValidateAsync(It.IsAny<Stream>()))
|
|
||||||
.ReturnsAsync(domainMetadata);
|
|
||||||
|
|
||||||
_mockMapper
|
|
||||||
.Setup(x => x.Map<PdfValidationResult>(domainMetadata))
|
|
||||||
.Returns(expectedDto);
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await _handler.Handle(query, CancellationToken.None);
|
var result = await _handler.Handle(query, CancellationToken.None);
|
||||||
@@ -64,28 +38,71 @@ public class ValidatePdfHandlerTests
|
|||||||
result.PdfVersion.Should().Be("1.4");
|
result.PdfVersion.Should().Be("1.4");
|
||||||
result.HasAttachments.Should().BeFalse();
|
result.HasAttachments.Should().BeFalse();
|
||||||
result.AttachmentCount.Should().Be(0);
|
result.AttachmentCount.Should().Be(0);
|
||||||
|
result.IsEncrypted.Should().BeFalse();
|
||||||
_mockPdfProcessor.Verify(x => x.ValidateAsync(It.IsAny<Stream>()), Times.Once);
|
_mockPdfProcessor.Verify(x => x.ValidateAsync(It.IsAny<Stream>()), Times.Once);
|
||||||
_mockMapper.Verify(x => x.Map<PdfValidationResult>(domainMetadata), Times.Once);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Handle_PdfProcessorThrowsException_PropagatesException()
|
public async Task Handle_EncryptedPdf_ReturnsIsEncryptedTrue()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var pdfBytes = "%PDF"u8.ToArray(); // "%PDF"
|
var query = new ValidatePdfQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) };
|
||||||
var query = new ValidatePdfQuery { PdfStream = new MemoryStream(pdfBytes) };
|
var expected = new PdfValidationResult(1, 512, 512 / 1024.0 / 1024.0, "1.7", false, 0, true);
|
||||||
|
|
||||||
_mockPdfProcessor
|
_mockPdfProcessor.Setup(x => x.ValidateAsync(It.IsAny<Stream>())).ReturnsAsync(expected);
|
||||||
.Setup(x => x.ValidateAsync(It.IsAny<Stream>()))
|
|
||||||
|
// 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<Stream>()), 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<Stream>())).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<Stream>()), 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<Stream>()))
|
||||||
.ThrowsAsync(new BadRequestException("Invalid PDF format"));
|
.ThrowsAsync(new BadRequestException("Invalid PDF format"));
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
var ex = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => _handler.Handle(query, CancellationToken.None)
|
() => _handler.Handle(query, CancellationToken.None));
|
||||||
);
|
ex.Message.Should().Be("Invalid PDF format");
|
||||||
|
|
||||||
exception.Message.Should().Be("Invalid PDF format");
|
|
||||||
_mockPdfProcessor.Verify(x => x.ValidateAsync(It.IsAny<Stream>()), Times.Once);
|
_mockPdfProcessor.Verify(x => x.ValidateAsync(It.IsAny<Stream>()), 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<Stream>()))
|
||||||
|
.ThrowsAsync(new InvalidOperationException("Unexpected error"));
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
await Assert.ThrowsAsync<InvalidOperationException>(
|
||||||
|
() => _handler.Handle(query, CancellationToken.None));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
using AutoMapper;
|
|
||||||
using DocumentService.Application.Common.DTOs;
|
using DocumentService.Application.Common.DTOs;
|
||||||
using DocumentService.Application.Common.Interfaces;
|
using DocumentService.Application.Common.Interfaces;
|
||||||
using DocumentService.Application.ValidatePdfA.Queries;
|
using DocumentService.Application.ValidatePdfA.Queries;
|
||||||
using DocumentService.Domain.Common.Exceptions;
|
using DocumentService.Domain.Common.Exceptions;
|
||||||
|
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
@@ -13,61 +11,32 @@ namespace DocumentService.Tests.Unit.Application.Features.ValidatePdfA;
|
|||||||
public class ValidatePdfAQueryHandlerTests
|
public class ValidatePdfAQueryHandlerTests
|
||||||
{
|
{
|
||||||
private readonly Mock<IPdfProcessor> _mockPdfProcessor;
|
private readonly Mock<IPdfProcessor> _mockPdfProcessor;
|
||||||
private readonly Mock<IMapper> _mockMapper;
|
|
||||||
private readonly ValidatePdfAQueryHandler _handler;
|
private readonly ValidatePdfAQueryHandler _handler;
|
||||||
|
|
||||||
public ValidatePdfAQueryHandlerTests()
|
public ValidatePdfAQueryHandlerTests()
|
||||||
{
|
{
|
||||||
_mockPdfProcessor = new Mock<IPdfProcessor>();
|
_mockPdfProcessor = new Mock<IPdfProcessor>();
|
||||||
_mockMapper = new Mock<IMapper>();
|
_handler = new ValidatePdfAQueryHandler(_mockPdfProcessor.Object);
|
||||||
_handler = new ValidatePdfAQueryHandler(_mockPdfProcessor.Object, _mockMapper.Object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Handle_ValidPdfA_ReturnsPdfAMetadata()
|
public async Task Handle_ValidCompliantPdfA_ReturnsCompliantResult()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var pdfBytes = "%PDF"u8.ToArray(); // "%PDF"
|
var query = new ValidatePdfAQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) };
|
||||||
var query = new ValidatePdfAQuery { PdfStream = new MemoryStream(pdfBytes) };
|
var expected = new PdfAValidationResult
|
||||||
|
|
||||||
var domainMetadata = new PdfAMetadata(
|
|
||||||
isValid: true,
|
|
||||||
pdfVersion: "1.7",
|
|
||||||
pageCount: 3,
|
|
||||||
fileSizeBytes: 2048,
|
|
||||||
encrypted: false,
|
|
||||||
pdfaVersion: "PDF/A-3b",
|
|
||||||
pdfaCompliant: true,
|
|
||||||
errors: [],
|
|
||||||
warnings: []
|
|
||||||
);
|
|
||||||
|
|
||||||
var expectedDto = new PdfAValidationResult
|
|
||||||
{
|
{
|
||||||
IsValid = true,
|
IsValid = true, PdfVersion = "1.7", PageCount = 3, FileSize = 2048,
|
||||||
PdfVersion = "1.7",
|
Encrypted = false, PdfAVersion = "PDF/A-3b", PdfACompliant = true,
|
||||||
PageCount = 3,
|
Errors = [], Warnings = []
|
||||||
FileSize = 2048,
|
|
||||||
Encrypted = false,
|
|
||||||
PdfAVersion = "PDF/A-3b",
|
|
||||||
PdfACompliant = true,
|
|
||||||
Errors = new List<string>(),
|
|
||||||
Warnings = new List<string>()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_mockPdfProcessor
|
_mockPdfProcessor.Setup(x => x.ValidatePdfAAsync(It.IsAny<Stream>())).ReturnsAsync(expected);
|
||||||
.Setup(x => x.ValidatePdfAAsync(It.IsAny<Stream>()))
|
|
||||||
.ReturnsAsync(domainMetadata);
|
|
||||||
|
|
||||||
_mockMapper
|
|
||||||
.Setup(x => x.Map<PdfAValidationResult>(domainMetadata))
|
|
||||||
.Returns(expectedDto);
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await _handler.Handle(query, CancellationToken.None);
|
var result = await _handler.Handle(query, CancellationToken.None);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().NotBeNull();
|
|
||||||
result.IsValid.Should().BeTrue();
|
result.IsValid.Should().BeTrue();
|
||||||
result.PageCount.Should().Be(3);
|
result.PageCount.Should().Be(3);
|
||||||
result.PdfVersion.Should().Be("1.7");
|
result.PdfVersion.Should().Be("1.7");
|
||||||
@@ -76,139 +45,85 @@ public class ValidatePdfAQueryHandlerTests
|
|||||||
result.Encrypted.Should().BeFalse();
|
result.Encrypted.Should().BeFalse();
|
||||||
result.Errors.Should().BeEmpty();
|
result.Errors.Should().BeEmpty();
|
||||||
result.Warnings.Should().BeEmpty();
|
result.Warnings.Should().BeEmpty();
|
||||||
|
|
||||||
_mockPdfProcessor.Verify(x => x.ValidatePdfAAsync(It.IsAny<Stream>()), Times.Once);
|
_mockPdfProcessor.Verify(x => x.ValidatePdfAAsync(It.IsAny<Stream>()), Times.Once);
|
||||||
_mockMapper.Verify(x => x.Map<PdfAValidationResult>(domainMetadata), Times.Once);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Handle_NonCompliantPdfA_ReturnsErrorsAndWarnings()
|
public async Task Handle_NonCompliantPdfA_ReturnsErrorsAndWarnings()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var pdfBytes = new byte[] { 0x25, 0x50, 0x44, 0x46 }; // "%PDF"
|
var query = new ValidatePdfAQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) };
|
||||||
var query = new ValidatePdfAQuery { PdfStream = new MemoryStream(pdfBytes) };
|
var expected = new PdfAValidationResult
|
||||||
|
|
||||||
var errors = new List<string> { "Missing XMP metadata", "Invalid color space" };
|
|
||||||
var warnings = new List<string> { "Embedded font not subset" };
|
|
||||||
|
|
||||||
var domainMetadata = new PdfAMetadata(
|
|
||||||
isValid: false,
|
|
||||||
pdfVersion: "1.4",
|
|
||||||
pageCount: 2,
|
|
||||||
fileSizeBytes: 1024,
|
|
||||||
encrypted: false,
|
|
||||||
pdfaVersion: null,
|
|
||||||
pdfaCompliant: false,
|
|
||||||
errors: errors,
|
|
||||||
warnings: warnings
|
|
||||||
);
|
|
||||||
|
|
||||||
var expectedDto = new PdfAValidationResult
|
|
||||||
{
|
{
|
||||||
IsValid = false,
|
IsValid = false, PdfVersion = "1.4", PageCount = 2, FileSize = 1024,
|
||||||
PdfVersion = "1.4",
|
Encrypted = false, PdfAVersion = null, PdfACompliant = false,
|
||||||
PageCount = 2,
|
Errors = ["Missing XMP metadata", "Invalid color space"],
|
||||||
FileSize = 1024,
|
Warnings = ["Embedded font not subset"]
|
||||||
Encrypted = false,
|
|
||||||
PdfAVersion = null,
|
|
||||||
PdfACompliant = false,
|
|
||||||
Errors = errors,
|
|
||||||
Warnings = warnings
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_mockPdfProcessor
|
_mockPdfProcessor.Setup(x => x.ValidatePdfAAsync(It.IsAny<Stream>())).ReturnsAsync(expected);
|
||||||
.Setup(x => x.ValidatePdfAAsync(It.IsAny<Stream>()))
|
|
||||||
.ReturnsAsync(domainMetadata);
|
|
||||||
|
|
||||||
_mockMapper
|
|
||||||
.Setup(x => x.Map<PdfAValidationResult>(domainMetadata))
|
|
||||||
.Returns(expectedDto);
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await _handler.Handle(query, CancellationToken.None);
|
var result = await _handler.Handle(query, CancellationToken.None);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().NotBeNull();
|
|
||||||
result.IsValid.Should().BeFalse();
|
result.IsValid.Should().BeFalse();
|
||||||
result.PdfACompliant.Should().BeFalse();
|
result.PdfACompliant.Should().BeFalse();
|
||||||
result.PdfAVersion.Should().BeNull();
|
result.PdfAVersion.Should().BeNull();
|
||||||
result.Errors.Should().HaveCount(2);
|
result.Errors.Should().HaveCount(2).And.Contain("Missing XMP metadata").And.Contain("Invalid color space");
|
||||||
result.Errors.Should().Contain("Missing XMP metadata");
|
result.Warnings.Should().HaveCount(1).And.Contain("Embedded font not subset");
|
||||||
result.Warnings.Should().HaveCount(1);
|
|
||||||
|
|
||||||
_mockPdfProcessor.Verify(x => x.ValidatePdfAAsync(It.IsAny<Stream>()), Times.Once);
|
_mockPdfProcessor.Verify(x => x.ValidatePdfAAsync(It.IsAny<Stream>()), Times.Once);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Handle_EncryptedPdf_ReturnsEncryptedFlag()
|
public async Task Handle_EncryptedPdf_ReturnsEncryptedFlagAndErrors()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var pdfBytes = new byte[] { 0x25, 0x50, 0x44, 0x46 }; // "%PDF"
|
var query = new ValidatePdfAQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) };
|
||||||
var query = new ValidatePdfAQuery { PdfStream = new MemoryStream(pdfBytes) };
|
var expected = new PdfAValidationResult
|
||||||
|
|
||||||
var domainMetadata = new PdfAMetadata(
|
|
||||||
isValid: true,
|
|
||||||
pdfVersion: "1.7",
|
|
||||||
pageCount: 1,
|
|
||||||
fileSizeBytes: 512,
|
|
||||||
encrypted: true,
|
|
||||||
pdfaVersion: null,
|
|
||||||
pdfaCompliant: false,
|
|
||||||
errors: new List<string> { "Encrypted PDFs cannot be PDF/A compliant" },
|
|
||||||
warnings: new List<string>()
|
|
||||||
);
|
|
||||||
|
|
||||||
var expectedDto = new PdfAValidationResult
|
|
||||||
{
|
{
|
||||||
IsValid = true,
|
IsValid = false, PdfVersion = "1.7", PageCount = 1, FileSize = 512,
|
||||||
PdfVersion = "1.7",
|
Encrypted = true, PdfAVersion = null, PdfACompliant = false,
|
||||||
PageCount = 1,
|
Errors = ["PDF/A documents cannot be encrypted"],
|
||||||
FileSize = 512,
|
Warnings = []
|
||||||
Encrypted = true,
|
|
||||||
PdfAVersion = null,
|
|
||||||
PdfACompliant = false,
|
|
||||||
Errors = new List<string> { "Encrypted PDFs cannot be PDF/A compliant" },
|
|
||||||
Warnings = new List<string>()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_mockPdfProcessor
|
_mockPdfProcessor.Setup(x => x.ValidatePdfAAsync(It.IsAny<Stream>())).ReturnsAsync(expected);
|
||||||
.Setup(x => x.ValidatePdfAAsync(It.IsAny<Stream>()))
|
|
||||||
.ReturnsAsync(domainMetadata);
|
|
||||||
|
|
||||||
_mockMapper
|
|
||||||
.Setup(x => x.Map<PdfAValidationResult>(domainMetadata))
|
|
||||||
.Returns(expectedDto);
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await _handler.Handle(query, CancellationToken.None);
|
var result = await _handler.Handle(query, CancellationToken.None);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().NotBeNull();
|
|
||||||
result.Encrypted.Should().BeTrue();
|
result.Encrypted.Should().BeTrue();
|
||||||
|
result.IsValid.Should().BeFalse();
|
||||||
result.PdfACompliant.Should().BeFalse();
|
result.PdfACompliant.Should().BeFalse();
|
||||||
result.Errors.Should().Contain("Encrypted PDFs cannot be PDF/A compliant");
|
result.Errors.Should().Contain("PDF/A documents cannot be encrypted");
|
||||||
|
|
||||||
_mockPdfProcessor.Verify(x => x.ValidatePdfAAsync(It.IsAny<Stream>()), Times.Once);
|
_mockPdfProcessor.Verify(x => x.ValidatePdfAAsync(It.IsAny<Stream>()), Times.Once);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Handle_PdfProcessorThrowsException_PropagatesException()
|
public async Task Handle_ProcessorThrowsBadRequest_PropagatesException()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var pdfBytes = new byte[] { 0x25, 0x50, 0x44, 0x46 }; // "%PDF"
|
var query = new ValidatePdfAQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) };
|
||||||
var query = new ValidatePdfAQuery { PdfStream = new MemoryStream(pdfBytes) };
|
_mockPdfProcessor.Setup(x => x.ValidatePdfAAsync(It.IsAny<Stream>()))
|
||||||
|
|
||||||
_mockPdfProcessor
|
|
||||||
.Setup(x => x.ValidatePdfAAsync(It.IsAny<Stream>()))
|
|
||||||
.ThrowsAsync(new BadRequestException("Invalid PDF format"));
|
.ThrowsAsync(new BadRequestException("Invalid PDF format"));
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
var ex = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
() => _handler.Handle(query, CancellationToken.None)
|
() => _handler.Handle(query, CancellationToken.None));
|
||||||
);
|
ex.Message.Should().Be("Invalid PDF format");
|
||||||
|
}
|
||||||
|
|
||||||
exception.Message.Should().Be("Invalid PDF format");
|
[Fact]
|
||||||
_mockPdfProcessor.Verify(x => x.ValidatePdfAAsync(It.IsAny<Stream>()), Times.Once);
|
public async Task Handle_ProcessorThrowsGenericException_PropagatesException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var query = new ValidatePdfAQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) };
|
||||||
|
_mockPdfProcessor.Setup(x => x.ValidatePdfAAsync(It.IsAny<Stream>()))
|
||||||
|
.ThrowsAsync(new Exception("Unexpected processing error"));
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
await Assert.ThrowsAsync<Exception>(() => _handler.Handle(query, CancellationToken.None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user