Files
my_bookmate/backend/test_book_file.py
T

58 lines
2.4 KiB
Python

"""Run with: .venv/Scripts/python.exe -B -m unittest test_book_file"""
import tempfile
import unittest
from pathlib import Path
from types import SimpleNamespace
from unittest.mock import AsyncMock, patch
import httpx
from fastapi import FastAPI
from app.api.books import router
from app.core.database import get_db
class BookFileTests(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
self.temp = tempfile.TemporaryDirectory()
self.root = Path(self.temp.name)
self.file = self.root / "sample.epub"
self.content = b"PK\x03\x04original-epub-bytes"
self.file.write_bytes(self.content)
self.db = SimpleNamespace(get=AsyncMock(return_value=SimpleNamespace(file_path=str(self.file))))
app = FastAPI()
app.include_router(router, prefix="/api")
async def fake_db():
yield self.db
app.dependency_overrides[get_db] = fake_db
self.client = httpx.AsyncClient(transport=httpx.ASGITransport(app=app), base_url="http://test")
self.config = patch("app.api.books.settings", SimpleNamespace(upload_dir=str(self.root)))
self.config.start()
async def asyncTearDown(self):
await self.client.aclose()
self.config.stop()
self.temp.cleanup()
async def test_original_bytes_and_type(self):
response = await self.client.get("/api/books/book-id/file")
self.assertEqual(response.status_code, 200)
self.assertEqual(response.content, self.content)
self.assertEqual(response.headers["content-type"], "application/epub+zip")
async def test_unknown_book(self):
self.db.get.return_value = None
self.assertEqual((await self.client.get("/api/books/unknown/file")).status_code, 404)
async def test_missing_file(self):
self.db.get.return_value.file_path = str(self.root / "missing.epub")
self.assertEqual((await self.client.get("/api/books/book-id/file")).status_code, 404)
async def test_outside_upload_directory(self):
self.db.get.return_value.file_path = str(self.root.parent / "outside.epub")
self.assertEqual((await self.client.get("/api/books/book-id/file")).status_code, 404)
async def test_non_epub_not_served(self):
self.db.get.return_value.file_path = str(self.root / "secrets.txt")
self.assertEqual((await self.client.get("/api/books/book-id/file")).status_code, 404)