using AutoMapper;
using DocumentOperator.Application.CheckPdfAttachments.Queries;
using DocumentOperator.Application.Common.DTOs;
using DocumentOperator.Application.Common.Interfaces;
using FluentAssertions;
using Moq;
namespace DocumentOperator.Tests.Unit.Application.CheckPdfAttachments;
///
/// Unit tests for CheckPdfAttachmentsQueryHandler.
/// Tests handler logic with mocked dependencies (IPdfProcessor, IMapper).
///
public class CheckPdfAttachmentsQueryHandlerTests
{
private readonly Mock _mockPdfProcessor;
private readonly Mock _mockMapper;
private readonly CheckPdfAttachmentsQueryHandler _sut;
public CheckPdfAttachmentsQueryHandlerTests()
{
_mockPdfProcessor = new Mock();
_mockMapper = new Mock();
_sut = new CheckPdfAttachmentsQueryHandler(_mockPdfProcessor.Object, _mockMapper.Object);
}
[Fact]
public async Task Handle_WithPdfBytes_CallsProcessorAndMapper()
{
// Arrange
byte[] pdfBytes = "fake-pdf-content"u8.ToArray();
var query = new CheckPdfAttachmentsQuery { PdfBytes = pdfBytes };
var domainResult = new AttachmentInfo(
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,
Attachments =
[
new() { FileName = "invoice.xml", MimeType = "text/xml", Size = 1024 },
new() { FileName = "metadata.json", MimeType = "application/json", Size = 512 }
]
};
_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.Should().NotBeNull();
result.Should().BeEquivalentTo(expectedDto);
_mockPdfProcessor.Verify(p => p.CheckAttachmentsAsync(It.IsAny()), Times.Once);
_mockMapper.Verify(m => m.Map(domainResult), Times.Once);
}
[Fact]
public async Task Handle_WithBase64Pdf_DecodesAndCallsProcessor()
{
// Arrange
byte[] pdfBytes = "fake-pdf-content"u8.ToArray();
string base64Pdf = Convert.ToBase64String(pdfBytes);
var query = new CheckPdfAttachmentsQuery { Base64Pdf = base64Pdf };
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.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 { PdfBytes = 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();
}
}