58 lines
2.4 KiB
Python
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)
|