Refactor: Rename DocumentOperator to DocumentService
Updated project and solution files to rename and restructure `DocumentOperator` to `DocumentService`. Modified project references in `DocumentService.API.csproj`, `DocumentService.Application.csproj`, and `DocumentService.Infrastructure.csproj` to reflect the new naming convention. Updated `DocumentService.sln` to remove old project references, add new ones, and adjust configuration and nested project mappings accordingly. This change aligns the project structure with the new naming convention.
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user