Consolidated DTOs under `DocumentService.Application.Common.DTOs.Requests` to centralize and align them with the application layer. Introduced `PdfBase64RequestBase` to encapsulate shared properties, reducing redundancy across request DTOs. Updated controllers, clients, and tests to use the new DTO structure. Removed redundant DTOs and cleaned up unused namespaces and comments. Improved documentation and ensured consistent naming conventions across the codebase.
DocumentService API - Manual Testing Guide
This guide contains manual test scenarios for validating the DocumentService API endpoints using Swagger UI or tools like Postman.
Prerequisites
-
Start the API:
dotnet run --project DocumentService.APIDefault URL:
https://localhost:5001(check console output for actual port) -
Open Swagger UI: Navigate to
https://localhost:<port>/swagger -
Test PDFs:
- Use PDFs from
fake-pdf/folder (form.pdf, multi-page.pdf, one-page.pdf, with-image.pdf) - Or use your own PDF files
- Use PDFs from
Feature 1: Basic PDF Validation
Endpoint: POST /api/pdf/validation/validate
Test Case 1.1: Valid PDF (Multipart Upload)
Objective: Verify basic PDF validation works with file upload
Steps:
- Open Swagger UI →
/api/pdf/validation/validate - Click "Try it out"
- Select multipart/form-data from dropdown
- Click "Choose File" and select
fake-pdf/one-page.pdf - Click "Execute"
Expected Result:
- Status Code: 200 OK
- Response Body:
{ "pageCount": 1, "fileSizeBytes": 7168, "fileSizeMB": 0.01, "pdfVersion": "1.4", "hasAttachments": false, "attachmentCount": 0 }
Test Case 1.2: Valid PDF (Base64 JSON)
Objective: Verify Base64 input works
Steps:
- Convert a PDF to Base64:
$bytes = [System.IO.File]::ReadAllBytes("fake-pdf/one-page.pdf") $base64 = [Convert]::ToBase64String($bytes) Write-Output $base64 - Open Swagger UI →
/api/pdf/validation/validate - Click "Try it out"
- Select application/json from dropdown
- Paste into Request Body:
{ "base64Pdf": "<paste-your-base64-here>" } - Click "Execute"
Expected Result:
- Status Code: 200 OK
- Same response as Test 1.1
Test Case 1.3: Invalid Base64 String
Objective: Verify validation rejects malformed Base64
Steps:
- Open Swagger UI →
/api/pdf/validation/validate - Select application/json
- Paste into Request Body:
{ "base64Pdf": "invalid-base64!!!" } - Click "Execute"
Expected Result:
- Status Code: 400 Bad Request
- Error Message: Contains "Base64"
Test Case 1.4: Empty File Upload
Objective: Verify empty files are rejected
Steps:
- Create an empty file (
empty.pdf) - Upload via multipart/form-data
Expected Result:
- Status Code: 400 Bad Request
- Error Message: Contains "cannot be empty"
Test Case 1.5: Large Multi-Page PDF
Objective: Verify handling of larger PDFs
Steps:
- Upload
fake-pdf/multi-page.pdf(49 KB)
Expected Result:
- Status Code: 200 OK
- Response:
{ "pageCount": 3, "fileSizeBytes": 49152, "fileSizeMB": 0.05, "pdfVersion": "1.7", "hasAttachments": false, "attachmentCount": 0 }
Test Case 1.6: PDF with Images
Objective: Verify image-heavy PDFs are processed
Steps:
- Upload
fake-pdf/with-image.pdf(256 KB)
Expected Result:
- Status Code: 200 OK
- Response:
{ "pageCount": 1, "fileSizeBytes": 262144, "fileSizeMB": 0.25, "pdfVersion": "1.6", "hasAttachments": false, "attachmentCount": 0 }
Feature 3: PDF/A Validation
Endpoint: POST /api/pdf/validation/validate-pdfa
Test Case 3.1: PDF/A Compliant Document (Multipart)
Objective: Verify PDF/A validation detects conformance
Steps:
- Open Swagger UI →
/api/pdf/validation/validate-pdfa - Select multipart/form-data
- Upload a PDF/A-compliant PDF (if available)
- Click "Execute"
Expected Result (if PDF/A compliant):
- Status Code: 200 OK
- Response:
{ "isValid": true, "pdfVersion": "1.7", "pageCount": 1, "fileSize": 12345, "encrypted": false, "pdfAVersion": "PDF/A-3b", "pdfACompliant": true, "errors": [], "warnings": [] }
Test Case 3.2: Non-PDF/A Document
Objective: Verify regular PDFs are detected as non-compliant
Steps:
- Upload
fake-pdf/one-page.pdf(regular PDF, NOT PDF/A)
Expected Result:
- Status Code: 200 OK
- Response:
{ "isValid": true, "pdfVersion": "1.4", "pageCount": 1, "fileSize": 7168, "encrypted": false, "pdfAVersion": null, "pdfACompliant": false, "errors": [], "warnings": ["Manual verification recommended: PDF/A compliance requires all fonts to be embedded"] }
Test Case 3.3: Encrypted PDF
Objective: Verify encrypted PDFs are flagged
Steps:
- Create or obtain a password-protected PDF
- Upload via multipart/form-data
Expected Result:
- Status Code: 200 OK
- Response:
{ "isValid": true, "pdfVersion": "1.7", "pageCount": 1, "fileSize": 12345, "encrypted": true, "pdfAVersion": null, "pdfACompliant": false, "errors": ["Encrypted PDFs cannot be PDF/A compliant"], "warnings": [] }
Test Case 3.4: Invalid Base64 (PDF/A Endpoint)
Objective: Verify validation works on PDF/A endpoint
Steps:
- Select application/json
- Paste:
{ "base64Pdf": "not-base64!!!" }
Expected Result:
- Status Code: 400 Bad Request
- Error Message: Contains "Base64"
Test Case 3.5: Empty Request
Objective: Verify both inputs missing is rejected
Steps:
- Select application/json
- Paste:
{ "pdfBytes": null, "base64Pdf": "" }
Expected Result:
- Status Code: 400 Bad Request
- Error Message: "Either PdfBytes or Base64Pdf must be provided, but not both"
Feature 2: Swiss QR Code Extraction
Endpoint: POST /api/swissqrcode/extract
Test Case 2.1: PDF with Swiss QR Code
Objective: Extract Swiss QR Bill from PDF
Steps:
- Open Swagger UI →
/api/swissqrcode/extract - Select multipart/form-data
- Upload a PDF containing Swiss QR Code on the last page
- Click "Execute"
Expected Result (if QR code present):
- Status Code: 200 OK
- Response: Contains Swiss QR Bill details (IBAN, amount, creditor, debtor, reference)
Test Case 2.2: PDF without QR Code
Objective: Verify graceful handling when no QR code exists
Steps:
- Upload
fake-pdf/one-page.pdf(no QR code)
Expected Result:
- Status Code: 404 Not Found
- Error Message: "Swiss QR Code not found in PDF"
Common Error Scenarios
Test Case E1: Missing File in Multipart Request
Steps:
- Any multipart endpoint
- Don't select a file, click "Execute"
Expected Result:
- Status Code: 400 Bad Request
Test Case E2: Both PdfBytes AND Base64Pdf Provided
Steps:
- Attempt to send JSON with both fields populated
{ "pdfBytes": [1,2,3], "base64Pdf": "dGVzdA==" }
Expected Result:
- Status Code: 400 Bad Request
- Error Message: "Either PdfBytes or Base64Pdf must be provided, but not both"
Test Case E3: Corrupted PDF File
Steps:
- Create a text file with
.pdfextension containing "FAKE PDF CONTENT" - Upload it
Expected Result:
- Status Code: 500 Internal Server Error
- Error Message: Contains "PDF processing error"
Test Coverage Summary
| Feature | Endpoint | Test Cases |
|---|---|---|
| Basic PDF Validation | POST /api/pdf/validation/validate |
6 |
| PDF/A Validation | POST /api/pdf/validation/validate-pdfa |
5 |
| Swiss QR Code | POST /api/swissqrcode/extract |
2 |
| Error Handling | All endpoints | 3 |
| TOTAL | 16 Manual Test Cases |
Notes
- All endpoints support BOTH
multipart/form-data(file upload) ANDapplication/json(Base64) - FluentValidation runs before handlers (400 errors indicate validation failures)
- DevExpress evaluation warnings (DX1000/DX1001) are expected and can be ignored
- Test PDFs in
fake-pdf/folder are small samples; use real-world PDFs for comprehensive testing
Quick PowerShell Helpers
Convert PDF to Base64:
$bytes = [System.IO.File]::ReadAllBytes("path\to\file.pdf")
$base64 = [Convert]::ToBase64String($bytes)
$base64 | Set-Clipboard # Copies to clipboard
Create empty PDF for testing:
New-Item -Path "empty.pdf" -ItemType File -Force
Check if file is valid PDF:
$header = Get-Content -Path "file.pdf" -TotalCount 1 -Encoding Byte
# Should start with: 0x25 0x50 0x44 0x46 (%PDF)