Spaces:
Sleeping
Sleeping
File size: 4,177 Bytes
b84ea83 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | """
Unit Tests — PDFService
Tests:
- Returns None for a visit that doesn't exist
- Returns bytes for a valid visit
- Output starts with PDF magic bytes (%PDF)
- PDF size is reasonable (>1KB)
- Works correctly with no checklists / no photos
- Works with checklists and photos present
"""
import pytest
from sqlalchemy.ext.asyncio import AsyncSession
from models.visit_model import Visit
from models.checklist_model import Checklist
from models.photo_model import Photo
from services.pdf_service import PDFService
PDF_MAGIC = b"%PDF"
@pytest.mark.asyncio
class TestPDFService:
async def test_returns_none_for_missing_visit(
self, async_session: AsyncSession
):
import uuid
svc = PDFService()
result = await svc.generate_visit_report(async_session, uuid.uuid4())
assert result is None
async def test_returns_bytes_for_valid_visit(
self, async_session: AsyncSession, sample_visit: Visit
):
svc = PDFService()
result = await svc.generate_visit_report(async_session, sample_visit.id)
assert result is not None
assert isinstance(result, bytes)
async def test_output_is_valid_pdf(
self, async_session: AsyncSession, sample_visit: Visit
):
"""PDF must start with the %PDF magic header."""
svc = PDFService()
result = await svc.generate_visit_report(async_session, sample_visit.id)
assert result is not None
assert result[:4] == PDF_MAGIC
async def test_pdf_has_reasonable_size(
self, async_session: AsyncSession, sample_visit: Visit
):
"""PDF should be at least 1KB (basic structure is there)."""
svc = PDFService()
result = await svc.generate_visit_report(async_session, sample_visit.id)
assert result is not None
assert len(result) > 1024 # > 1 KB
async def test_pdf_with_no_checklists_no_photos(
self, async_session: AsyncSession, sample_visit: Visit
):
"""Visit with no related data should still produce a valid PDF."""
svc = PDFService()
result = await svc.generate_visit_report(async_session, sample_visit.id)
assert result is not None
assert result[:4] == PDF_MAGIC
async def test_pdf_with_checklists(
self,
async_session: AsyncSession,
sample_visit: Visit,
sample_checklist: Checklist,
):
"""Checklist data should be included — PDF size increases."""
svc = PDFService()
result = await svc.generate_visit_report(async_session, sample_visit.id)
assert result is not None
assert len(result) > 1024
async def test_pdf_with_photos(
self,
async_session: AsyncSession,
sample_visit: Visit,
sample_photo: Photo,
):
"""Photo metadata table should be included — PDF still valid."""
svc = PDFService()
result = await svc.generate_visit_report(async_session, sample_visit.id)
assert result is not None
assert result[:4] == PDF_MAGIC
async def test_pdf_with_all_data(
self,
async_session: AsyncSession,
sample_visit: Visit,
):
"""Full visit with multiple checklists and photos."""
# Add 3 checklists
for i, checked in enumerate([True, False, True]):
async_session.add(Checklist(
visit_id=sample_visit.id,
item_name=f"Step {i+1}",
is_checked=checked,
notes=f"Note for step {i+1}" if checked else None,
))
# Add 2 photos
for j in range(2):
async_session.add(Photo(
visit_id=sample_visit.id,
file_path=f"/uploads/photo_{j}.jpg",
file_name=f"photo_{j}.jpg",
file_size=51200,
mime_type="image/jpeg",
))
await async_session.flush()
svc = PDFService()
result = await svc.generate_visit_report(async_session, sample_visit.id)
assert result is not None
assert result[:4] == PDF_MAGIC
assert len(result) > 2048 # Richer content = larger PDF
|