Add tests for DevExpressPdfProcessor and roadmap updates
Updated ROADMAP.md to reflect progress on the TDD process for DevExpressPdfProcessor, including the creation of unit tests (6 tests in the Red Phase). Updated progress to 4/7 mini-steps completed and outlined the next step (Green Phase). Added `DevExpressPdfProcessorTests.cs` with unit tests to validate PDF files and extract metadata. Tests cover valid PDFs, null/empty inputs, corrupted PDFs, and file size calculations. Used `FluentAssertions` for assertions. Cleaned up `DocumentOperator.Tests.csproj` by removing an unused folder reference. No functional changes to the project structure.
This commit is contained in:
@@ -1321,11 +1321,12 @@ public async Task POST_ValidatePdf_InvalidPdf_Returns400() { }
|
||||
- ? Step 3.2.1 - ProcessDocument Ordner gelöscht (Application Layer cleanup)
|
||||
- ? Step 3.2.2 - Test-Ordnerstruktur erstellt (Unit/Infrastructure/Services/PdfProcessing)
|
||||
- ? Step 3.2.3 - Test-PDF Datei hinzugefügt (valid.pdf als Embedded Resource)
|
||||
- ? Step 3.2.4 - DevExpressPdfProcessorTests.cs erstellt (TDD Red Phase - 6 Tests)
|
||||
|
||||
### ?? In Progress
|
||||
- **Phase 3, Step 3.2:** DevExpressPdfProcessor (TDD)
|
||||
- **NEXT:** Step 3.2.4 - DevExpressPdfProcessorTests.cs erstellen (TDD Red Phase)
|
||||
- **Progress:** 3/7 Mini-Steps abgeschlossen
|
||||
- **NEXT:** Step 3.2.5 - DevExpressPdfProcessor.cs implementieren (TDD Green Phase)
|
||||
- **Progress:** 4/7 Mini-Steps abgeschlossen
|
||||
|
||||
### ? Pending
|
||||
- **Phase 3:** Infrastructure Layer
|
||||
@@ -1484,6 +1485,7 @@ public async Task POST_ValidatePdf_InvalidPdf_Returns400() { }
|
||||
| 17.01.2025 | Application | ? Step 3.2.1 - ProcessDocument Ordner gelöscht (Cleanup) |
|
||||
| 17.01.2025 | Tests | ? Step 3.2.2 - Test-Ordnerstruktur erstellt, UnitTest1.cs gelöscht |
|
||||
| 17.01.2025 | Tests | ? Step 3.2.3 - Test-PDF (valid.pdf) als Embedded Resource hinzugefügt |
|
||||
| 17.01.2025 | Tests | ? Step 3.2.4 - DevExpressPdfProcessorTests.cs erstellt (TDD Red - 6 Tests) |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
@@ -39,8 +39,4 @@
|
||||
<ProjectReference Include="..\DocumentOperator.Infrastructure\DocumentOperator.Infrastructure.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Unit\Infrastructure\Services\PdfProcessing\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
using System.Reflection;
|
||||
using DocumentOperator.Application.Common.Interfaces;
|
||||
using DocumentOperator.Domain.Common.Exceptions;
|
||||
using DocumentOperator.Domain.Models.ValueObjects;
|
||||
using DocumentOperator.Infrastructure.Services.PdfProcessing;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace DocumentOperator.Tests.Unit.Infrastructure.Services.PdfProcessing;
|
||||
|
||||
/// <summary>
|
||||
/// Unit tests for DevExpressPdfProcessor.
|
||||
/// Tests PDF validation and metadata extraction.
|
||||
/// </summary>
|
||||
public class DevExpressPdfProcessorTests
|
||||
{
|
||||
private readonly IPdfProcessor _sut; // SUT = System Under Test
|
||||
|
||||
public DevExpressPdfProcessorTests()
|
||||
{
|
||||
// Arrange: Create instance (wird später implementiert)
|
||||
_sut = new DevExpressPdfProcessor();
|
||||
}
|
||||
|
||||
#region Helper Methods
|
||||
|
||||
/// <summary>
|
||||
/// Loads a test PDF from embedded resources.
|
||||
/// </summary>
|
||||
/// <param name="filename">Name of the PDF file (e.g., "valid.pdf")</param>
|
||||
/// <returns>PDF content as byte array</returns>
|
||||
private static byte[] LoadTestPdf(string filename)
|
||||
{
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
var resourceName = $"DocumentOperator.Tests.TestData.Pdfs.{filename}";
|
||||
|
||||
using var stream = assembly.GetManifestResourceStream(resourceName);
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
throw new FileNotFoundException(
|
||||
$"Embedded resource '{resourceName}' not found. " +
|
||||
$"Available resources: {string.Join(", ", assembly.GetManifestResourceNames())}");
|
||||
}
|
||||
|
||||
using var memoryStream = new MemoryStream();
|
||||
stream.CopyTo(memoryStream);
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ValidateAsync Tests
|
||||
|
||||
[Fact]
|
||||
public async Task ValidateAsync_ValidPdf_ReturnsPdfMetadata()
|
||||
{
|
||||
// Arrange
|
||||
byte[] pdfBytes = LoadTestPdf("valid.pdf");
|
||||
|
||||
// Act
|
||||
var metadata = await _sut.ValidateAsync(pdfBytes);
|
||||
|
||||
// Assert
|
||||
metadata.Should().NotBeNull("a valid PDF should return metadata");
|
||||
metadata.PageCount.Should().BeGreaterThan(0, "PDF must have at least one page");
|
||||
metadata.FileSizeBytes.Should().Be(pdfBytes.Length, "file size should match input");
|
||||
metadata.PdfVersion.Should().NotBeNullOrEmpty("PDF version should be detected");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ValidateAsync_ValidPdf_ReturnsCorrectPageCount()
|
||||
{
|
||||
// Arrange
|
||||
byte[] pdfBytes = LoadTestPdf("valid.pdf");
|
||||
|
||||
// Act
|
||||
var metadata = await _sut.ValidateAsync(pdfBytes);
|
||||
|
||||
// Assert
|
||||
// Deine valid.pdf hat wahrscheinlich 1-5 Seiten - passe an!
|
||||
metadata.PageCount.Should().BeInRange(1, 100, "test PDF should have reasonable page count");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ValidateAsync_NullBytes_ThrowsPdfProcessingException()
|
||||
{
|
||||
// Arrange
|
||||
byte[]? pdfBytes = null;
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _sut.ValidateAsync(pdfBytes!);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<PdfProcessingException>()
|
||||
.WithMessage("*null*", "null input should be rejected");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ValidateAsync_EmptyBytes_ThrowsPdfProcessingException()
|
||||
{
|
||||
// Arrange
|
||||
byte[] pdfBytes = Array.Empty<byte>();
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _sut.ValidateAsync(pdfBytes);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<PdfProcessingException>()
|
||||
.WithMessage("*empty*", "empty input should be rejected");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ValidateAsync_CorruptedPdf_ThrowsPdfProcessingException()
|
||||
{
|
||||
// Arrange
|
||||
byte[] pdfBytes = "This is not a valid PDF content"u8.ToArray();
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _sut.ValidateAsync(pdfBytes);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<PdfProcessingException>()
|
||||
.WithMessage("*invalid*", "corrupted PDF should throw exception");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Metadata Tests
|
||||
|
||||
[Fact]
|
||||
public async Task ValidateAsync_ValidPdf_FileSizeMBCalculatedCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
byte[] pdfBytes = LoadTestPdf("valid.pdf");
|
||||
|
||||
// Act
|
||||
var metadata = await _sut.ValidateAsync(pdfBytes);
|
||||
|
||||
// Assert
|
||||
double expectedSizeMB = pdfBytes.Length / 1024.0 / 1024.0;
|
||||
metadata.FileSizeMB.Should().BeApproximately(expectedSizeMB, 0.01,
|
||||
"FileSizeMB should be calculated correctly from bytes");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user