New test files (4 tests each — 2 success + 2 failure): - MergePdfsCommandHandlerTests: TwoStreams, WithPageRanges, BadRequest, GenericException - AddAnnotationHandlerTests: TextMarkup, FreeText, BadRequest (page OOB), GenericException - AddStampHandlerTests: TextStamp, PredefinedStamp, BadRequest (opacity), GenericException - ExtractPdfAttachmentsHandlerTests: ReturnsZip, NotFoundException, BadRequest, GenericException - ConvertPdfAHandlerTests (ConvertTo + ConvertFrom): ConvertTo: ValidLevel, NotImplemented, BadRequest ConvertFrom: ValidPdfA, BadRequest, GenericException
81 lines
3.1 KiB
C#
81 lines
3.1 KiB
C#
using DocumentService.Application.Common.Interfaces;
|
|
using DocumentService.Application.ExtractPdfAttachments;
|
|
using DocumentService.Domain.Common.Exceptions;
|
|
using FluentAssertions;
|
|
using Moq;
|
|
using Xunit;
|
|
|
|
namespace DocumentService.Tests.Unit.Application.Features.ExtractAttachments;
|
|
|
|
public class ExtractPdfAttachmentsHandlerTests
|
|
{
|
|
private readonly Mock<IPdfProcessor> _mockProcessor;
|
|
private readonly ExtractPdfAttachmentsCommandHandler _handler;
|
|
private static readonly byte[] FakePdfBytes = "%PDF"u8.ToArray();
|
|
|
|
public ExtractPdfAttachmentsHandlerTests()
|
|
{
|
|
_mockProcessor = new Mock<IPdfProcessor>();
|
|
_handler = new ExtractPdfAttachmentsCommandHandler(_mockProcessor.Object);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_PdfWithAttachments_ReturnsZipBytes()
|
|
{
|
|
// Arrange
|
|
var command = new ExtractPdfAttachmentsCommand { PdfStream = new MemoryStream(FakePdfBytes) };
|
|
// ZIP magic bytes PK
|
|
var expected = new byte[] { 0x50, 0x4B, 0x03, 0x04, 0x00, 0x00 };
|
|
_mockProcessor.Setup(x => x.ExtractAttachmentsAsync(It.IsAny<Stream>())).ReturnsAsync(expected);
|
|
|
|
// Act
|
|
var result = await _handler.Handle(command, CancellationToken.None);
|
|
|
|
// Assert
|
|
result.Should().NotBeEmpty();
|
|
result[0].Should().Be(0x50, "ZIP starts with 'P'");
|
|
result[1].Should().Be(0x4B, "ZIP continues with 'K'");
|
|
_mockProcessor.Verify(x => x.ExtractAttachmentsAsync(It.IsAny<Stream>()), Times.Once);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_PdfWithNoAttachments_ThrowsNotFoundException()
|
|
{
|
|
// Arrange
|
|
var command = new ExtractPdfAttachmentsCommand { PdfStream = new MemoryStream(FakePdfBytes) };
|
|
_mockProcessor.Setup(x => x.ExtractAttachmentsAsync(It.IsAny<Stream>()))
|
|
.ThrowsAsync(new NotFoundException("PDF does not contain any attachments"));
|
|
|
|
// Act & Assert
|
|
var ex = await Assert.ThrowsAsync<NotFoundException>(
|
|
() => _handler.Handle(command, CancellationToken.None));
|
|
ex.Message.Should().Contain("attachments");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_EmptyStream_ThrowsBadRequestException()
|
|
{
|
|
// Arrange
|
|
var command = new ExtractPdfAttachmentsCommand { PdfStream = new MemoryStream(FakePdfBytes) };
|
|
_mockProcessor.Setup(x => x.ExtractAttachmentsAsync(It.IsAny<Stream>()))
|
|
.ThrowsAsync(new BadRequestException("PDF stream cannot be empty"));
|
|
|
|
// Act & Assert
|
|
var ex = await Assert.ThrowsAsync<BadRequestException>(
|
|
() => _handler.Handle(command, CancellationToken.None));
|
|
ex.Message.Should().Contain("empty");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_ProcessorThrowsGenericException_PropagatesException()
|
|
{
|
|
// Arrange
|
|
var command = new ExtractPdfAttachmentsCommand { PdfStream = new MemoryStream(FakePdfBytes) };
|
|
_mockProcessor.Setup(x => x.ExtractAttachmentsAsync(It.IsAny<Stream>()))
|
|
.ThrowsAsync(new Exception("Unexpected error"));
|
|
|
|
// Act & Assert
|
|
await Assert.ThrowsAsync<Exception>(() => _handler.Handle(command, CancellationToken.None));
|
|
}
|
|
}
|