Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions shelfmark/metadata_providers/googlebooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""

from contextlib import suppress
from dataclasses import replace
from http import HTTPStatus
from typing import Any, ClassVar

Expand All @@ -32,6 +33,7 @@
MetadataProvider,
MetadataSearchOptions,
SearchField,
SearchResult,
SearchType,
SortOrder,
TextSearchField,
Expand Down Expand Up @@ -217,6 +219,10 @@ def get_book(self, book_id: str) -> BookMetadata | None:
ttl_default=600,
key_prefix="googlebooks:isbn",
)
def search_paginated(self, options: MetadataSearchOptions) -> SearchResult:
"""Google returns at most 40 per page, so a full page is 40 whatever limit asked for."""
return super().search_paginated(replace(options, limit=min(options.limit, 40)))

def search_by_isbn(self, isbn: str) -> BookMetadata | None:
"""Search for a book by ISBN-10 or ISBN-13."""
# Clean ISBN (remove hyphens and spaces)
Expand Down
33 changes: 33 additions & 0 deletions tests/metadata/test_googlebooks_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,36 @@ def test_parse_volume_returns_none_for_malformed_rating_payload(self):
)

assert result is None


class _FullPageSession:
def __init__(self, count):
self.count = count

def get(self, *args, **kwargs):
items = [
{"id": f"v{i}", "volumeInfo": {"title": f"Book {i}", "authors": ["Alice Author"]}}
for i in range(self.count)
]
return _GoogleBooksResponse({"items": items})


def test_googlebooks_reports_more_pages_when_limit_exceeds_api_maximum():
get_metadata_cache().clear()
provider = GoogleBooksProvider(api_key="test-key")
provider.session = _FullPageSession(40)

result = provider.search_paginated(MetadataSearchOptions(query="Dune", limit=100))

assert len(result.books) == 40
assert result.has_more is True


def test_googlebooks_reports_no_more_pages_after_a_short_page():
get_metadata_cache().clear()
provider = GoogleBooksProvider(api_key="test-key")
provider.session = _FullPageSession(12)

result = provider.search_paginated(MetadataSearchOptions(query="Dune", limit=100))

assert result.has_more is False
Loading