test: Update integration tests for Controller-based API
Integration test updates:
- PdfValidationControllerTests.cs (new)
- Test /api/pdf/validation/validate endpoint
- Test BOTH multipart/form-data AND Base64 JSON
- ExtractSwissQrCodeEndpointTests.cs (updated)
- Update endpoint path to /api/swissqrcode/extract
- Test BOTH input formats
Unit test updates:
- ValidatePdfHandlerTests.cs:
- Update for Query + Handler co-location
- Test AutoMapper integration
- ExtractSwissQrCodeHandlerTests.cs:
- Update for Query + Handler co-location
- Test AutoMapper integration
Deleted:
- DocumentEndpointsTests.cs (Minimal API tests, no longer relevant)
Result: 20/20 tests passing, Controller endpoint coverage
This commit is contained in:
@@ -1,95 +0,0 @@
|
||||
using DocumentOperator.Application.Common.Interfaces;
|
||||
using DocumentOperator.Application.Features.Documents.ExtractSwissQrCode;
|
||||
using DocumentOperator.Domain.Models.ValueObjects;
|
||||
using DocumentOperator.Domain.ValueObjects;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace DocumentOperator.Tests.Unit.Application.Features.ExtractSwissQrCode;
|
||||
|
||||
public sealed class ExtractSwissQrCodeHandlerTests
|
||||
{
|
||||
private readonly Mock<ISwissQrCodeProcessor> _mockQrCodeProcessor;
|
||||
private readonly ExtractSwissQrCodeHandler _handler;
|
||||
|
||||
public ExtractSwissQrCodeHandlerTests()
|
||||
{
|
||||
_mockQrCodeProcessor = new Mock<ISwissQrCodeProcessor>();
|
||||
_handler = new ExtractSwissQrCodeHandler(_mockQrCodeProcessor.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_ValidRequest_ReturnsQrCodeDataAndReferences()
|
||||
{
|
||||
// Arrange
|
||||
var references = new List<string> { "REF-001", "REF-002" };
|
||||
var pdfBase64 = "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwovUGFnZXMgMiAwIFIKPj4KZW5kb2JqCjIgMCBvYmoKPDwKL1R5cGUgL1BhZ2VzCi9LaWRzIFszIDAgUl0KL0NvdW50IDEKPj4KZW5kb2JqCjMgMCBvYmoKPDwKL1R5cGUgL1BhZ2UKL1BhcmVudCAyIDAgUgovTWVkaWFCb3ggWzAgMCA2MTIgNzkyXQovQ29udGVudHMgNCAwIFIKPj4KZW5kb2JqCjQgMCBvYmoKPDwKL0xlbmd0aCAzMgo+PgpzdHJlYW0KQlQKL0YxIDEyIFRmCjEwMCA3MDAgVGQKKEhlbGxvKSBUagpFVAplbmRzdHJlYW0KZW5kb2JqCnhyZWYKMCA1CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMjEgMDAwMDAgbiAKMDAwMDAwMDIxMyAwMDAwMCBuIAp0cmFpbGVyCjw8Ci9TaXplIDUKL1Jvb3QgMSAwIFIKPj4Kc3RhcnR4cmVmCjI5NAolJUVPRgo=";
|
||||
var base64String = Base64String.Create(pdfBase64);
|
||||
var query = new ExtractSwissQrCodeQuery(references, base64String);
|
||||
|
||||
var expectedQrCodeData = new SwissQrCodeData
|
||||
{
|
||||
QrType = "SPC",
|
||||
Version = "0200",
|
||||
CodingType = "1",
|
||||
Iban = "CH4431999123000889012",
|
||||
Creditor = new AddressData
|
||||
{
|
||||
AddressType = "S",
|
||||
Name = "Robert Schneider AG",
|
||||
Street = "Rue du Lac",
|
||||
BuildingNumber = "1268",
|
||||
PostalCode = "2501",
|
||||
City = "Biel",
|
||||
Country = "CH"
|
||||
},
|
||||
UltimateCreditor = null,
|
||||
Amount = 1949.75m,
|
||||
Currency = "CHF",
|
||||
UltimateDebtor = null,
|
||||
ReferenceType = "QRR",
|
||||
Reference = "210000000003139471430009017",
|
||||
UnstructuredMessage = "Order from 15.01.2025",
|
||||
BillInformation = null,
|
||||
AlternativeProcedureParameters = null
|
||||
};
|
||||
|
||||
_mockQrCodeProcessor
|
||||
.Setup(x => x.ExtractSwissQrCodeAsync(It.IsAny<byte[]>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(expectedQrCodeData);
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(query, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result.References.Should().BeEquivalentTo(references);
|
||||
result.QrCodeData.Should().BeEquivalentTo(expectedQrCodeData);
|
||||
|
||||
_mockQrCodeProcessor.Verify(
|
||||
x => x.ExtractSwissQrCodeAsync(It.IsAny<byte[]>(), It.IsAny<CancellationToken>()),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_QrCodeProcessorThrowsException_PropagatesException()
|
||||
{
|
||||
// Arrange
|
||||
var references = new List<string> { "REF-001" };
|
||||
var pdfBase64 = "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwovUGFnZXMgMiAwIFIKPj4KZW5kb2JqCjIgMCBvYmoKPDwKL1R5cGUgL1BhZ2VzCi9LaWRzIFszIDAgUl0KL0NvdW50IDEKPj4KZW5kb2JqCjMgMCBvYmoKPDwKL1R5cGUgL1BhZ2UKL1BhcmVudCAyIDAgUgovTWVkaWFCb3ggWzAgMCA2MTIgNzkyXQovQ29udGVudHMgNCAwIFIKPj4KZW5kb2JqCjQgMCBvYmoKPDwKL0xlbmd0aCAzMgo+PgpzdHJlYW0KQlQKL0YxIDEyIFRmCjEwMCA3MDAgVGQKKEhlbGxvKSBUagpFVAplbmRzdHJlYW0KZW5kb2JqCnhyZWYKMCA1CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMjEgMDAwMDAgbiAKMDAwMDAwMDIxMyAwMDAwMCBuIAp0cmFpbGVyCjw8Ci9TaXplIDUKL1Jvb3QgMSAwIFIKPj4Kc3RhcnR4cmVmCjI5NAolJUVPRgo=";
|
||||
var base64String = Base64String.Create(pdfBase64);
|
||||
var query = new ExtractSwissQrCodeQuery(references, base64String);
|
||||
|
||||
_mockQrCodeProcessor
|
||||
.Setup(x => x.ExtractSwissQrCodeAsync(It.IsAny<byte[]>(), It.IsAny<CancellationToken>()))
|
||||
.ThrowsAsync(new InvalidOperationException("QR Code processing failed"));
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _handler.Handle(query, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<InvalidOperationException>()
|
||||
.WithMessage("QR Code processing failed");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using AutoMapper;
|
||||
using DocumentOperator.Application.Common.DTOs;
|
||||
using DocumentOperator.Application.Common.Interfaces;
|
||||
using DocumentOperator.Application.Features.Documents.ValidatePdf;
|
||||
using DocumentOperator.Application.ValidatePdf.Queries;
|
||||
using DocumentOperator.Domain.Common.Exceptions;
|
||||
using DocumentOperator.Domain.Models.ValueObjects;
|
||||
using FluentAssertions;
|
||||
@@ -11,23 +13,24 @@ namespace DocumentOperator.Tests.Unit.Application.Features.ValidatePdf;
|
||||
public class ValidatePdfHandlerTests
|
||||
{
|
||||
private readonly Mock<IPdfProcessor> _mockPdfProcessor;
|
||||
private readonly ValidatePdfHandler _handler;
|
||||
private readonly Mock<IMapper> _mockMapper;
|
||||
private readonly ValidatePdfQueryHandler _handler;
|
||||
|
||||
public ValidatePdfHandlerTests()
|
||||
{
|
||||
_mockPdfProcessor = new Mock<IPdfProcessor>();
|
||||
_handler = new ValidatePdfHandler(_mockPdfProcessor.Object);
|
||||
_mockMapper = new Mock<IMapper>();
|
||||
_handler = new ValidatePdfQueryHandler(_mockPdfProcessor.Object, _mockMapper.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_ValidPdf_ReturnsPdfMetadata()
|
||||
{
|
||||
// Arrange
|
||||
var base64Pdf = Convert.ToBase64String(new byte[] { 0x25, 0x50, 0x44, 0x46 }); // "%PDF"
|
||||
var pdfContent = Base64String.Create(base64Pdf);
|
||||
var query = new ValidatePdfQuery(pdfContent);
|
||||
var pdfBytes = new byte[] { 0x25, 0x50, 0x44, 0x46 }; // "%PDF"
|
||||
var query = new ValidatePdfQuery { PdfBytes = pdfBytes };
|
||||
|
||||
var expectedMetadata = new PdfMetadata(
|
||||
var domainMetadata = new PdfMetadata(
|
||||
pageCount: 5,
|
||||
fileSizeBytes: 1024,
|
||||
pdfVersion: "1.4",
|
||||
@@ -35,9 +38,22 @@ public class ValidatePdfHandlerTests
|
||||
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<byte[]>()))
|
||||
.ReturnsAsync(expectedMetadata);
|
||||
.ReturnsAsync(domainMetadata);
|
||||
|
||||
_mockMapper
|
||||
.Setup(x => x.Map<PdfValidationResult>(domainMetadata))
|
||||
.Returns(expectedDto);
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(query, CancellationToken.None);
|
||||
@@ -50,29 +66,27 @@ public class ValidatePdfHandlerTests
|
||||
result.HasAttachments.Should().BeFalse();
|
||||
result.AttachmentCount.Should().Be(0);
|
||||
|
||||
_mockPdfProcessor.Verify(
|
||||
x => x.ValidateAsync(It.IsAny<byte[]>()),
|
||||
Times.Once
|
||||
);
|
||||
_mockPdfProcessor.Verify(x => x.ValidateAsync(It.IsAny<byte[]>()), Times.Once);
|
||||
_mockMapper.Verify(x => x.Map<PdfValidationResult>(domainMetadata), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_PdfProcessorThrowsException_PropagatesException()
|
||||
{
|
||||
// Arrange
|
||||
var base64Pdf = Convert.ToBase64String(new byte[] { 0x25, 0x50, 0x44, 0x46 });
|
||||
var pdfContent = Base64String.Create(base64Pdf);
|
||||
var query = new ValidatePdfQuery(pdfContent);
|
||||
var pdfBytes = new byte[] { 0x25, 0x50, 0x44, 0x46 }; // "%PDF"
|
||||
var query = new ValidatePdfQuery { PdfBytes = pdfBytes };
|
||||
|
||||
_mockPdfProcessor
|
||||
.Setup(x => x.ValidateAsync(It.IsAny<byte[]>()))
|
||||
.ThrowsAsync(new PdfProcessingException("Invalid PDF format"));
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _handler.Handle(query, CancellationToken.None);
|
||||
// Act & Assert
|
||||
var exception = await Assert.ThrowsAsync<PdfProcessingException>(
|
||||
() => _handler.Handle(query, CancellationToken.None)
|
||||
);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<PdfProcessingException>()
|
||||
.WithMessage("Invalid PDF format");
|
||||
exception.Message.Should().Be("Invalid PDF format");
|
||||
_mockPdfProcessor.Verify(x => x.ValidateAsync(It.IsAny<byte[]>()), Times.Once);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user