diff --git a/DocumentOperator.Tests/Unit/Application/CheckPdfAttachments/CheckPdfAttachmentsQueryHandlerTests.cs b/DocumentOperator.Tests/Unit/Application/CheckPdfAttachments/CheckPdfAttachmentsQueryHandlerTests.cs
index 62eb85c..3c1677c 100644
--- a/DocumentOperator.Tests/Unit/Application/CheckPdfAttachments/CheckPdfAttachmentsQueryHandlerTests.cs
+++ b/DocumentOperator.Tests/Unit/Application/CheckPdfAttachments/CheckPdfAttachmentsQueryHandlerTests.cs
@@ -2,16 +2,13 @@ using AutoMapper;
using DocumentService.Application.CheckPdfAttachments.Queries;
using DocumentService.Application.Common.DTOs;
using DocumentService.Application.Common.Interfaces;
-
+using DocumentService.Domain.Common.Exceptions;
using FluentAssertions;
using Moq;
+using Xunit;
namespace DocumentService.Tests.Unit.Application.CheckPdfAttachments;
-///
-/// Unit tests for CheckPdfAttachmentsQueryHandler.
-/// Tests handler logic with mocked dependencies (IPdfProcessor, IMapper).
-///
public class CheckPdfAttachmentsQueryHandlerTests
{
private readonly Mock _mockPdfProcessor;
@@ -26,26 +23,16 @@ public class CheckPdfAttachmentsQueryHandlerTests
}
[Fact]
- public async Task Handle_WithPdfBytes_CallsProcessorAndMapper()
+ public async Task Handle_PdfWithAttachments_ReturnsAttachmentDetails()
{
// Arrange
- byte[] pdfBytes = "fake-pdf-content"u8.ToArray();
- var query = new CheckPdfAttachmentsQuery { PdfStream = new MemoryStream(pdfBytes) };
-
+ var query = new CheckPdfAttachmentsQuery { PdfStream = new MemoryStream("fake-pdf"u8.ToArray()) };
var domainResult = new AttachmentInfo(
- hasAttachments: true,
- attachmentCount: 2,
- attachments:
- [
- new("invoice.xml", "text/xml", 1024),
- new("metadata.json", "application/json", 512)
- ]
- );
-
+ hasAttachments: true, attachmentCount: 2,
+ attachments: [new("invoice.xml", "text/xml", 1024), new("metadata.json", "application/json", 512)]);
var expectedDto = new AttachmentCheckResult
{
- HasAttachments = true,
- AttachmentCount = 2,
+ HasAttachments = true, AttachmentCount = 2,
Attachments =
[
new() { FileName = "invoice.xml", MimeType = "text/xml", Size = 1024 },
@@ -61,20 +48,22 @@ public class CheckPdfAttachmentsQueryHandlerTests
// Assert
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()), Times.Once);
_mockMapper.Verify(m => m.Map(domainResult), Times.Once);
}
[Fact]
- public async Task Handle_WithBase64Pdf_DecodesAndCallsProcessor()
+ public async Task Handle_PdfWithNoAttachments_ReturnsEmptyResult()
{
// Arrange
- byte[] pdfBytes = "fake-pdf-content"u8.ToArray();
- var query = new CheckPdfAttachmentsQuery { PdfStream = new MemoryStream(pdfBytes) };
-
- var domainResult = new AttachmentInfo(false, 0, []);
+ var query = new CheckPdfAttachmentsQuery { PdfStream = new MemoryStream("fake-pdf"u8.ToArray()) };
+ var domainResult = AttachmentInfo.Empty;
var expectedDto = new AttachmentCheckResult { HasAttachments = false, AttachmentCount = 0, Attachments = [] };
_mockPdfProcessor.Setup(p => p.CheckAttachmentsAsync(It.IsAny())).ReturnsAsync(domainResult);
@@ -83,40 +72,37 @@ public class CheckPdfAttachmentsQueryHandlerTests
// Act
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()), 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())).ReturnsAsync(domainResult);
- _mockMapper.Setup(m => m.Map(domainResult)).Returns(expectedDto);
-
- // Act
- var result = await _sut.Handle(query, CancellationToken.None);
-
// Assert
result.HasAttachments.Should().BeFalse();
result.AttachmentCount.Should().Be(0);
result.Attachments.Should().BeEmpty();
+ _mockPdfProcessor.Verify(p => p.CheckAttachmentsAsync(It.IsAny()), 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()))
+ .ThrowsAsync(new BadRequestException("PDF stream cannot be empty"));
+
+ // Act & Assert
+ var ex = await Assert.ThrowsAsync(
+ () => _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()))
+ .ThrowsAsync(new InvalidOperationException("Unexpected error"));
+
+ // Act & Assert
+ await Assert.ThrowsAsync(
+ () => _sut.Handle(query, CancellationToken.None));
}
}
-
-
diff --git a/DocumentOperator.Tests/Unit/Application/Features/ValidatePdf/ValidatePdfHandlerTests.cs b/DocumentOperator.Tests/Unit/Application/Features/ValidatePdf/ValidatePdfHandlerTests.cs
index f1b3699..51ec94b 100644
--- a/DocumentOperator.Tests/Unit/Application/Features/ValidatePdf/ValidatePdfHandlerTests.cs
+++ b/DocumentOperator.Tests/Unit/Application/Features/ValidatePdf/ValidatePdfHandlerTests.cs
@@ -1,4 +1,3 @@
-using AutoMapper;
using DocumentService.Application.Common.DTOs;
using DocumentService.Application.Common.Interfaces;
using DocumentService.Application.ValidatePdf.Queries;
@@ -12,47 +11,22 @@ namespace DocumentService.Tests.Unit.Application.Features.ValidatePdf;
public class ValidatePdfHandlerTests
{
private readonly Mock _mockPdfProcessor;
- private readonly Mock _mockMapper;
private readonly ValidatePdfQueryHandler _handler;
public ValidatePdfHandlerTests()
{
_mockPdfProcessor = new Mock();
- _mockMapper = new Mock();
- _handler = new ValidatePdfQueryHandler(_mockPdfProcessor.Object, _mockMapper.Object);
+ _handler = new ValidatePdfQueryHandler(_mockPdfProcessor.Object);
}
[Fact]
- public async Task Handle_ValidPdf_ReturnsPdfMetadata()
+ public async Task Handle_ValidPdf_ReturnsResult()
{
// Arrange
- var pdfBytes = "%PDF"u8.ToArray(); // "%PDF"
- var query = new ValidatePdfQuery { PdfStream = new MemoryStream(pdfBytes) };
+ 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);
- var domainMetadata = new PdfMetadata(
- 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()))
- .ReturnsAsync(domainMetadata);
-
- _mockMapper
- .Setup(x => x.Map(domainMetadata))
- .Returns(expectedDto);
+ _mockPdfProcessor.Setup(x => x.ValidateAsync(It.IsAny())).ReturnsAsync(expected);
// Act
var result = await _handler.Handle(query, CancellationToken.None);
@@ -64,28 +38,71 @@ public class ValidatePdfHandlerTests
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);
- _mockMapper.Verify(x => x.Map(domainMetadata), Times.Once);
}
[Fact]
- public async Task Handle_PdfProcessorThrowsException_PropagatesException()
+ public async Task Handle_EncryptedPdf_ReturnsIsEncryptedTrue()
{
// Arrange
- var pdfBytes = "%PDF"u8.ToArray(); // "%PDF"
- var query = new ValidatePdfQuery { PdfStream = new MemoryStream(pdfBytes) };
+ 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()))
+ _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 exception = await Assert.ThrowsAsync(
- () => _handler.Handle(query, CancellationToken.None)
- );
-
- exception.Message.Should().Be("Invalid PDF format");
+ 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));
+ }
}
diff --git a/DocumentOperator.Tests/Unit/Application/Features/ValidatePdfA/ValidatePdfAQueryHandlerTests.cs b/DocumentOperator.Tests/Unit/Application/Features/ValidatePdfA/ValidatePdfAQueryHandlerTests.cs
index 22d9c8a..2d5ae15 100644
--- a/DocumentOperator.Tests/Unit/Application/Features/ValidatePdfA/ValidatePdfAQueryHandlerTests.cs
+++ b/DocumentOperator.Tests/Unit/Application/Features/ValidatePdfA/ValidatePdfAQueryHandlerTests.cs
@@ -1,9 +1,7 @@
-using AutoMapper;
using DocumentService.Application.Common.DTOs;
using DocumentService.Application.Common.Interfaces;
using DocumentService.Application.ValidatePdfA.Queries;
using DocumentService.Domain.Common.Exceptions;
-
using FluentAssertions;
using Moq;
using Xunit;
@@ -13,61 +11,32 @@ namespace DocumentService.Tests.Unit.Application.Features.ValidatePdfA;
public class ValidatePdfAQueryHandlerTests
{
private readonly Mock _mockPdfProcessor;
- private readonly Mock _mockMapper;
private readonly ValidatePdfAQueryHandler _handler;
public ValidatePdfAQueryHandlerTests()
{
_mockPdfProcessor = new Mock();
- _mockMapper = new Mock();
- _handler = new ValidatePdfAQueryHandler(_mockPdfProcessor.Object, _mockMapper.Object);
+ _handler = new ValidatePdfAQueryHandler(_mockPdfProcessor.Object);
}
[Fact]
- public async Task Handle_ValidPdfA_ReturnsPdfAMetadata()
+ public async Task Handle_ValidCompliantPdfA_ReturnsCompliantResult()
{
// Arrange
- var pdfBytes = "%PDF"u8.ToArray(); // "%PDF"
- var query = new ValidatePdfAQuery { PdfStream = new MemoryStream(pdfBytes) };
-
- 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
+ var query = new ValidatePdfAQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) };
+ var expected = new PdfAValidationResult
{
- IsValid = true,
- PdfVersion = "1.7",
- PageCount = 3,
- FileSize = 2048,
- Encrypted = false,
- PdfAVersion = "PDF/A-3b",
- PdfACompliant = true,
- Errors = new List(),
- Warnings = new List()
+ IsValid = true, PdfVersion = "1.7", PageCount = 3, FileSize = 2048,
+ Encrypted = false, PdfAVersion = "PDF/A-3b", PdfACompliant = true,
+ Errors = [], Warnings = []
};
- _mockPdfProcessor
- .Setup(x => x.ValidatePdfAAsync(It.IsAny()))
- .ReturnsAsync(domainMetadata);
-
- _mockMapper
- .Setup(x => x.Map(domainMetadata))
- .Returns(expectedDto);
+ _mockPdfProcessor.Setup(x => x.ValidatePdfAAsync(It.IsAny())).ReturnsAsync(expected);
// Act
var result = await _handler.Handle(query, CancellationToken.None);
// Assert
- result.Should().NotBeNull();
result.IsValid.Should().BeTrue();
result.PageCount.Should().Be(3);
result.PdfVersion.Should().Be("1.7");
@@ -76,139 +45,85 @@ public class ValidatePdfAQueryHandlerTests
result.Encrypted.Should().BeFalse();
result.Errors.Should().BeEmpty();
result.Warnings.Should().BeEmpty();
-
_mockPdfProcessor.Verify(x => x.ValidatePdfAAsync(It.IsAny()), Times.Once);
- _mockMapper.Verify(x => x.Map(domainMetadata), Times.Once);
}
[Fact]
public async Task Handle_NonCompliantPdfA_ReturnsErrorsAndWarnings()
{
// Arrange
- var pdfBytes = new byte[] { 0x25, 0x50, 0x44, 0x46 }; // "%PDF"
- var query = new ValidatePdfAQuery { PdfStream = new MemoryStream(pdfBytes) };
-
- var errors = new List { "Missing XMP metadata", "Invalid color space" };
- var warnings = new List { "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
+ var query = new ValidatePdfAQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) };
+ var expected = new PdfAValidationResult
{
- IsValid = false,
- PdfVersion = "1.4",
- PageCount = 2,
- FileSize = 1024,
- Encrypted = false,
- PdfAVersion = null,
- PdfACompliant = false,
- Errors = errors,
- Warnings = warnings
+ IsValid = false, PdfVersion = "1.4", PageCount = 2, FileSize = 1024,
+ Encrypted = false, PdfAVersion = null, PdfACompliant = false,
+ Errors = ["Missing XMP metadata", "Invalid color space"],
+ Warnings = ["Embedded font not subset"]
};
- _mockPdfProcessor
- .Setup(x => x.ValidatePdfAAsync(It.IsAny()))
- .ReturnsAsync(domainMetadata);
-
- _mockMapper
- .Setup(x => x.Map(domainMetadata))
- .Returns(expectedDto);
+ _mockPdfProcessor.Setup(x => x.ValidatePdfAAsync(It.IsAny())).ReturnsAsync(expected);
// Act
var result = await _handler.Handle(query, CancellationToken.None);
// Assert
- result.Should().NotBeNull();
result.IsValid.Should().BeFalse();
result.PdfACompliant.Should().BeFalse();
result.PdfAVersion.Should().BeNull();
- result.Errors.Should().HaveCount(2);
- result.Errors.Should().Contain("Missing XMP metadata");
- result.Warnings.Should().HaveCount(1);
-
+ result.Errors.Should().HaveCount(2).And.Contain("Missing XMP metadata").And.Contain("Invalid color space");
+ result.Warnings.Should().HaveCount(1).And.Contain("Embedded font not subset");
_mockPdfProcessor.Verify(x => x.ValidatePdfAAsync(It.IsAny()), Times.Once);
}
[Fact]
- public async Task Handle_EncryptedPdf_ReturnsEncryptedFlag()
+ public async Task Handle_EncryptedPdf_ReturnsEncryptedFlagAndErrors()
{
// Arrange
- var pdfBytes = new byte[] { 0x25, 0x50, 0x44, 0x46 }; // "%PDF"
- var query = new ValidatePdfAQuery { PdfStream = new MemoryStream(pdfBytes) };
-
- var domainMetadata = new PdfAMetadata(
- isValid: true,
- pdfVersion: "1.7",
- pageCount: 1,
- fileSizeBytes: 512,
- encrypted: true,
- pdfaVersion: null,
- pdfaCompliant: false,
- errors: new List { "Encrypted PDFs cannot be PDF/A compliant" },
- warnings: new List()
- );
-
- var expectedDto = new PdfAValidationResult
+ var query = new ValidatePdfAQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) };
+ var expected = new PdfAValidationResult
{
- IsValid = true,
- PdfVersion = "1.7",
- PageCount = 1,
- FileSize = 512,
- Encrypted = true,
- PdfAVersion = null,
- PdfACompliant = false,
- Errors = new List { "Encrypted PDFs cannot be PDF/A compliant" },
- Warnings = new List()
+ IsValid = false, PdfVersion = "1.7", PageCount = 1, FileSize = 512,
+ Encrypted = true, PdfAVersion = null, PdfACompliant = false,
+ Errors = ["PDF/A documents cannot be encrypted"],
+ Warnings = []
};
- _mockPdfProcessor
- .Setup(x => x.ValidatePdfAAsync(It.IsAny()))
- .ReturnsAsync(domainMetadata);
-
- _mockMapper
- .Setup(x => x.Map(domainMetadata))
- .Returns(expectedDto);
+ _mockPdfProcessor.Setup(x => x.ValidatePdfAAsync(It.IsAny())).ReturnsAsync(expected);
// Act
var result = await _handler.Handle(query, CancellationToken.None);
// Assert
- result.Should().NotBeNull();
result.Encrypted.Should().BeTrue();
+ result.IsValid.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()), Times.Once);
}
[Fact]
- public async Task Handle_PdfProcessorThrowsException_PropagatesException()
+ public async Task Handle_ProcessorThrowsBadRequest_PropagatesException()
{
// Arrange
- var pdfBytes = new byte[] { 0x25, 0x50, 0x44, 0x46 }; // "%PDF"
- var query = new ValidatePdfAQuery { PdfStream = new MemoryStream(pdfBytes) };
-
- _mockPdfProcessor
- .Setup(x => x.ValidatePdfAAsync(It.IsAny()))
+ var query = new ValidatePdfAQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) };
+ _mockPdfProcessor.Setup(x => x.ValidatePdfAAsync(It.IsAny()))
.ThrowsAsync(new BadRequestException("Invalid PDF format"));
// Act & Assert
- var exception = await Assert.ThrowsAsync(
- () => _handler.Handle(query, CancellationToken.None)
- );
+ var ex = await Assert.ThrowsAsync(
+ () => _handler.Handle(query, CancellationToken.None));
+ ex.Message.Should().Be("Invalid PDF format");
+ }
- exception.Message.Should().Be("Invalid PDF format");
- _mockPdfProcessor.Verify(x => x.ValidatePdfAAsync(It.IsAny()), Times.Once);
+ [Fact]
+ public async Task Handle_ProcessorThrowsGenericException_PropagatesException()
+ {
+ // Arrange
+ var query = new ValidatePdfAQuery { PdfStream = new MemoryStream("%PDF"u8.ToArray()) };
+ _mockPdfProcessor.Setup(x => x.ValidatePdfAAsync(It.IsAny()))
+ .ThrowsAsync(new Exception("Unexpected processing error"));
+
+ // Act & Assert
+ await Assert.ThrowsAsync(() => _handler.Handle(query, CancellationToken.None));
}
}
-