[books] Match books by Google Books ID or author name

This commit is contained in:
2026-09-01 11:54:14 -04:00
parent d569d31715
commit c400f8a18d
6 changed files with 255 additions and 34 deletions

View File

@ -28,7 +28,11 @@ def test_enrich_book_metadata_tags_success(mock_lookup):
@pytest.mark.django_db
@patch("books.models.lookup_book_from_ol", return_value={})
def test_enrich_book_metadata_tags_failure_when_no_match(mock_lookup):
@patch("books.models.lookup_comic_from_locg", return_value={})
@patch("books.models.lookup_book_from_google", return_value={})
def test_enrich_book_metadata_tags_failure_when_no_match(
mock_google, mock_locg, mock_ol
):
book = Book.objects.create(title="Unknown Book", pages=100)
enrich_book_metadata(book.id)
@ -40,7 +44,11 @@ def test_enrich_book_metadata_tags_failure_when_no_match(mock_lookup):
@pytest.mark.django_db
@patch("books.models.lookup_book_from_ol", side_effect=Exception("boom"))
def test_enrich_book_metadata_tags_failure_on_exception(mock_lookup):
@patch("books.models.lookup_comic_from_locg", side_effect=Exception("boom"))
@patch("books.models.lookup_book_from_google", side_effect=Exception("boom"))
def test_enrich_book_metadata_tags_failure_on_exception(
mock_google, mock_locg, mock_ol
):
book = Book.objects.create(title="Test Book", pages=100)
enrich_book_metadata(book.id)
@ -113,3 +121,120 @@ def test_fix_metadata_does_not_crash_on_locg_data_with_isbn():
assert enriched is True
book.refresh_from_db()
assert book.summary == "A comic summary"
@pytest.mark.django_db
def test_find_or_create_returns_existing_by_title():
book = Book.objects.create(original_title="Dune", title="Dune")
with patch("books.models.lookup_book_from_google") as mock_google:
found = Book.find_or_create("Dune")
assert found.id == book.id
mock_google.assert_not_called()
@pytest.mark.django_db
@patch("books.models.lookup_comic_from_comicvine", return_value={})
@patch("books.models.lookup_book_from_ol", return_value={})
@patch("books.models.lookup_book_from_google")
def test_find_or_create_reuses_existing_by_google_books_id(
mock_google, mock_ol, mock_comicvine
):
existing = Book.objects.create(
original_title="Dune - 50th Anniversary",
title="Dune",
google_books_id="gbooks_123",
)
mock_google.return_value = {
"title": "Dune",
"google_books_id": "gbooks_123",
"authors": ["Frank Herbert"],
"pages": 412,
}
found = Book.find_or_create("Dune")
assert found.id == existing.id
assert Book.objects.filter(original_title="Dune").count() == 0
assert Book.objects.count() == 1
assert found.authors.filter(name="Frank Herbert").exists()
@pytest.mark.django_db
@patch("books.models.lookup_comic_from_comicvine", return_value={})
@patch("books.models.lookup_book_from_ol", return_value={})
@patch("books.models.lookup_book_from_google")
def test_find_or_create_matches_by_title_and_author(
mock_google, mock_ol, mock_comicvine
):
author = Author.objects.create(name="Frank Herbert")
existing = Book.objects.create(original_title="Dune - Part 1", title="Dune")
existing.authors.add(author)
mock_google.return_value = {
"title": "Dune",
"authors": ["Frank Herbert"],
"pages": 412,
}
found = Book.find_or_create("Dune", author="Frank Herbert")
assert found.id == existing.id
assert Book.objects.count() == 1
@pytest.mark.django_db
@patch("books.models.lookup_comic_from_comicvine", return_value={})
@patch("books.models.lookup_book_from_ol", return_value={})
@patch("books.models.lookup_book_from_google")
def test_find_or_create_stores_google_books_id(mock_google, mock_ol, mock_comicvine):
mock_google.return_value = {
"title": "Dune",
"google_books_id": "gbooks_456",
"authors": ["Frank Herbert"],
"pages": 412,
}
book = Book.find_or_create("Dune")
assert book.google_books_id == "gbooks_456"
assert book.authors.filter(name="Frank Herbert").exists()
@patch("books.sources.google.requests.get")
def test_lookup_book_from_google_captures_volume_id(mock_get):
from books.sources.google import lookup_book_from_google
mock_response = mock_get.return_value
mock_response.status_code = 200
mock_response.content = b"""
{"items": [
{
"id": "gbooks_789",
"volumeInfo": {
"title": "Dune",
"authors": ["Frank Herbert"],
"publishedDate": "1965",
"pageCount": 412
}
}
]}
"""
result = lookup_book_from_google("Dune")
assert result["google_books_id"] == "gbooks_789"
assert result["authors"] == ["Frank Herbert"]
assert result["first_publish_year"] == 1965
@patch("books.sources.google.requests.get")
def test_lookup_book_from_google_includes_author_in_query(mock_get):
from books.sources.google import lookup_book_from_google
mock_response = mock_get.return_value
mock_response.status_code = 200
mock_response.content = b'{"items": []}'
lookup_book_from_google("Dune", author="Frank Herbert")
args, kwargs = mock_get.call_args
assert "inauthor:Frank Herbert" in kwargs["params"]["q"]