"""Tests for KOReader-compatible file hash generation.""" import pytest from httpx import AsyncClient from pathlib import Path # Known KOReader hashes for test files TEST_FILES = { "Moby Dick; Or, The Whale - Herman Melville.epub": { "path": Path("tests/data_files/Moby Dick; Or, The Whale - Herman Melville.epub"), "hash": "ceeef909ec65653ba77e1380dff998fb", "content_type": "application/epub+zip", }, "Calculus Made Easy - Silvanus Thompson.pdf": { "path": Path("tests/data_files/Calculus Made Easy - Silvanus Thompson.pdf"), "hash": "ace67d512efd1efdea20f3c2436b6075", "content_type": "application/pdf", }, } @pytest.mark.parametrize( ("book_name",), [(name,) for name in TEST_FILES.keys()], ) async def test_upload_book_generates_correct_hash( authenticated_client: AsyncClient, book_name: str, ) -> None: """Test that uploading a book generates the correct KOReader-compatible hash.""" book_info = TEST_FILES[book_name] file_content = book_info["path"].read_bytes() files = [("files", (book_name, file_content, book_info["content_type"]))] data = {"library_id": "1"} response = await authenticated_client.post( "/books?library_id=1", files=files, data=data, ) assert response.status_code == 201 book_data = response.json() assert len(book_data["files"]) == 1 file_metadata = book_data["files"][0] assert "hash" in file_metadata assert file_metadata["hash"] == book_info["hash"] async def test_add_file_to_book_generates_correct_hash( authenticated_client: AsyncClient, ) -> None: """Test that adding a file to an existing book generates the correct hash.""" # Create a book with the first file first_book = TEST_FILES["Moby Dick; Or, The Whale - Herman Melville.epub"] first_content = first_book["path"].read_bytes() files = [("files", (first_book["path"].name, first_content, first_book["content_type"]))] data = {"library_id": "1"} create_response = await authenticated_client.post( "/books?library_id=1", files=files, data=data, ) assert create_response.status_code == 201 book_id = create_response.json()["id"] # Add the second file to the book second_book = TEST_FILES["Calculus Made Easy - Silvanus Thompson.pdf"] second_content = second_book["path"].read_bytes() add_files = [("data", (second_book["path"].name, second_content, second_book["content_type"]))] add_response = await authenticated_client.post( f"/books/{book_id}/files", files=add_files, ) assert add_response.status_code == 201 updated_book = add_response.json() # Verify both files have correct hashes assert len(updated_book["files"]) == 2 for file_metadata in updated_book["files"]: assert "hash" in file_metadata epub_file = next(f for f in updated_book["files"] if f["path"].endswith(".epub")) pdf_file = next(f for f in updated_book["files"] if f["path"].endswith(".pdf")) assert epub_file["hash"] == first_book["hash"] assert pdf_file["hash"] == second_book["hash"]