Files
TekH 0e88b349d7 Rebrand project: DocumentOperator to DocumentService
This commit implements a complete rebranding of the project:
- Updated all namespaces from `DocumentOperator` to `DocumentService`.
- Renamed file paths, embedded resources, and test data references.
- Updated configuration keys, logging paths, and Redis instance names.
- Revised documentation to reflect the new project name.
- Modified project and solution files to align with the new structure.
- Updated class names, DTOs, commands, queries, and handlers.
- Adjusted middleware, controllers, and API endpoints.
- Updated Swagger metadata and API titles to `DocumentService API`.
- Refactored test namespaces, resource paths, and embedded resources.
- Updated build and deployment configurations for the new name.
- Replaced all references to `DocumentOperator` in comments and literals.

These changes ensure consistency across the codebase and documentation.
2026-07-30 14:02:56 +02:00

215 lines
7.0 KiB
C#

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;
namespace DocumentService.Tests.Unit.Application.Features.ValidatePdfA;
public class ValidatePdfAQueryHandlerTests
{
private readonly Mock<IPdfProcessor> _mockPdfProcessor;
private readonly Mock<IMapper> _mockMapper;
private readonly ValidatePdfAQueryHandler _handler;
public ValidatePdfAQueryHandlerTests()
{
_mockPdfProcessor = new Mock<IPdfProcessor>();
_mockMapper = new Mock<IMapper>();
_handler = new ValidatePdfAQueryHandler(_mockPdfProcessor.Object, _mockMapper.Object);
}
[Fact]
public async Task Handle_ValidPdfA_ReturnsPdfAMetadata()
{
// 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
{
IsValid = true,
PdfVersion = "1.7",
PageCount = 3,
FileSize = 2048,
Encrypted = false,
PdfAVersion = "PDF/A-3b",
PdfACompliant = true,
Errors = new List<string>(),
Warnings = new List<string>()
};
_mockPdfProcessor
.Setup(x => x.ValidatePdfAAsync(It.IsAny<Stream>()))
.ReturnsAsync(domainMetadata);
_mockMapper
.Setup(x => x.Map<PdfAValidationResult>(domainMetadata))
.Returns(expectedDto);
// 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");
result.PdfAVersion.Should().Be("PDF/A-3b");
result.PdfACompliant.Should().BeTrue();
result.Encrypted.Should().BeFalse();
result.Errors.Should().BeEmpty();
result.Warnings.Should().BeEmpty();
_mockPdfProcessor.Verify(x => x.ValidatePdfAAsync(It.IsAny<Stream>()), Times.Once);
_mockMapper.Verify(x => x.Map<PdfAValidationResult>(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<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,
PdfVersion = "1.4",
PageCount = 2,
FileSize = 1024,
Encrypted = false,
PdfAVersion = null,
PdfACompliant = false,
Errors = errors,
Warnings = warnings
};
_mockPdfProcessor
.Setup(x => x.ValidatePdfAAsync(It.IsAny<Stream>()))
.ReturnsAsync(domainMetadata);
_mockMapper
.Setup(x => x.Map<PdfAValidationResult>(domainMetadata))
.Returns(expectedDto);
// 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);
_mockPdfProcessor.Verify(x => x.ValidatePdfAAsync(It.IsAny<Stream>()), Times.Once);
}
[Fact]
public async Task Handle_EncryptedPdf_ReturnsEncryptedFlag()
{
// 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<string> { "Encrypted PDFs cannot be PDF/A compliant" },
warnings: new List<string>()
);
var expectedDto = new PdfAValidationResult
{
IsValid = true,
PdfVersion = "1.7",
PageCount = 1,
FileSize = 512,
Encrypted = true,
PdfAVersion = null,
PdfACompliant = false,
Errors = new List<string> { "Encrypted PDFs cannot be PDF/A compliant" },
Warnings = new List<string>()
};
_mockPdfProcessor
.Setup(x => x.ValidatePdfAAsync(It.IsAny<Stream>()))
.ReturnsAsync(domainMetadata);
_mockMapper
.Setup(x => x.Map<PdfAValidationResult>(domainMetadata))
.Returns(expectedDto);
// Act
var result = await _handler.Handle(query, CancellationToken.None);
// Assert
result.Should().NotBeNull();
result.Encrypted.Should().BeTrue();
result.PdfACompliant.Should().BeFalse();
result.Errors.Should().Contain("Encrypted PDFs cannot be PDF/A compliant");
_mockPdfProcessor.Verify(x => x.ValidatePdfAAsync(It.IsAny<Stream>()), Times.Once);
}
[Fact]
public async Task Handle_PdfProcessorThrowsException_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<Stream>()))
.ThrowsAsync(new BadRequestException("Invalid PDF format"));
// Act & Assert
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => _handler.Handle(query, CancellationToken.None)
);
exception.Message.Should().Be("Invalid PDF format");
_mockPdfProcessor.Verify(x => x.ValidatePdfAAsync(It.IsAny<Stream>()), Times.Once);
}
}