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:
387
DocumentService.API/README.md
Normal file
387
DocumentService.API/README.md
Normal file
@@ -0,0 +1,387 @@
|
||||
# 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)
|
||||
```
|
||||
Reference in New Issue
Block a user