This commit implements a complete rebranding of the project: - Updated all namespaces from `DocumentOperator` to `DocumentService`. - Renamed file paths, embedded resources, and test data references. - Updated configuration keys, logging paths, and Redis instance names. - Revised documentation to reflect the new project name. - Modified project and solution files to align with the new structure. - Updated class names, DTOs, commands, queries, and handlers. - Adjusted middleware, controllers, and API endpoints. - Updated Swagger metadata and API titles to `DocumentService API`. - Refactored test namespaces, resource paths, and embedded resources. - Updated build and deployment configurations for the new name. - Replaced all references to `DocumentOperator` in comments and literals. These changes ensure consistency across the codebase and documentation.
388 lines
8.5 KiB
Markdown
388 lines
8.5 KiB
Markdown
# 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
|
|
|
|
1. **Start the API:**
|
|
```powershell
|
|
dotnet run --project DocumentService.API
|
|
```
|
|
Default URL: `https://localhost:5001` (check console output for actual port)
|
|
|
|
2. **Open Swagger UI:**
|
|
Navigate to `https://localhost:<port>/swagger`
|
|
|
|
3. **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
|
|
|
|
---
|
|
|
|
## 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:**
|
|
1. Open Swagger UI → `/api/pdf/validation/validate`
|
|
2. Click "Try it out"
|
|
3. Select **multipart/form-data** from dropdown
|
|
4. Click "Choose File" and select `fake-pdf/one-page.pdf`
|
|
5. Click "Execute"
|
|
|
|
**Expected Result:**
|
|
- **Status Code:** 200 OK
|
|
- **Response Body:**
|
|
```json
|
|
{
|
|
"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:**
|
|
1. Convert a PDF to Base64:
|
|
```powershell
|
|
$bytes = [System.IO.File]::ReadAllBytes("fake-pdf/one-page.pdf")
|
|
$base64 = [Convert]::ToBase64String($bytes)
|
|
Write-Output $base64
|
|
```
|
|
2. Open Swagger UI → `/api/pdf/validation/validate`
|
|
3. Click "Try it out"
|
|
4. Select **application/json** from dropdown
|
|
5. Paste into Request Body:
|
|
```json
|
|
{
|
|
"base64Pdf": "<paste-your-base64-here>"
|
|
}
|
|
```
|
|
6. 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:**
|
|
1. Open Swagger UI → `/api/pdf/validation/validate`
|
|
2. Select **application/json**
|
|
3. Paste into Request Body:
|
|
```json
|
|
{
|
|
"base64Pdf": "invalid-base64!!!"
|
|
}
|
|
```
|
|
4. 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:**
|
|
1. Create an empty file (`empty.pdf`)
|
|
2. 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:**
|
|
1. Upload `fake-pdf/multi-page.pdf` (49 KB)
|
|
|
|
**Expected Result:**
|
|
- **Status Code:** 200 OK
|
|
- **Response:**
|
|
```json
|
|
{
|
|
"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:**
|
|
1. Upload `fake-pdf/with-image.pdf` (256 KB)
|
|
|
|
**Expected Result:**
|
|
- **Status Code:** 200 OK
|
|
- **Response:**
|
|
```json
|
|
{
|
|
"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:**
|
|
1. Open Swagger UI → `/api/pdf/validation/validate-pdfa`
|
|
2. Select **multipart/form-data**
|
|
3. Upload a PDF/A-compliant PDF (if available)
|
|
4. Click "Execute"
|
|
|
|
**Expected Result (if PDF/A compliant):**
|
|
- **Status Code:** 200 OK
|
|
- **Response:**
|
|
```json
|
|
{
|
|
"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:**
|
|
1. Upload `fake-pdf/one-page.pdf` (regular PDF, NOT PDF/A)
|
|
|
|
**Expected Result:**
|
|
- **Status Code:** 200 OK
|
|
- **Response:**
|
|
```json
|
|
{
|
|
"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:**
|
|
1. Create or obtain a password-protected PDF
|
|
2. Upload via multipart/form-data
|
|
|
|
**Expected Result:**
|
|
- **Status Code:** 200 OK
|
|
- **Response:**
|
|
```json
|
|
{
|
|
"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:**
|
|
1. Select **application/json**
|
|
2. Paste:
|
|
```json
|
|
{
|
|
"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:**
|
|
1. Select **application/json**
|
|
2. Paste:
|
|
```json
|
|
{
|
|
"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:**
|
|
1. Open Swagger UI → `/api/swissqrcode/extract`
|
|
2. Select **multipart/form-data**
|
|
3. Upload a PDF containing Swiss QR Code on the **last page**
|
|
4. 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:**
|
|
1. 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:**
|
|
1. Any multipart endpoint
|
|
2. Don't select a file, click "Execute"
|
|
|
|
**Expected Result:**
|
|
- **Status Code:** 400 Bad Request
|
|
|
|
---
|
|
|
|
### Test Case E2: Both PdfBytes AND Base64Pdf Provided
|
|
**Steps:**
|
|
1. Attempt to send JSON with both fields populated
|
|
```json
|
|
{
|
|
"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:**
|
|
1. Create a text file with `.pdf` extension containing "FAKE PDF CONTENT"
|
|
2. 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) AND `application/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:**
|
|
```powershell
|
|
$bytes = [System.IO.File]::ReadAllBytes("path\to\file.pdf")
|
|
$base64 = [Convert]::ToBase64String($bytes)
|
|
$base64 | Set-Clipboard # Copies to clipboard
|
|
```
|
|
|
|
**Create empty PDF for testing:**
|
|
```powershell
|
|
New-Item -Path "empty.pdf" -ItemType File -Force
|
|
```
|
|
|
|
**Check if file is valid PDF:**
|
|
```powershell
|
|
$header = Get-Content -Path "file.pdf" -TotalCount 1 -Encoding Byte
|
|
# Should start with: 0x25 0x50 0x44 0x46 (%PDF)
|
|
```
|