diff --git a/shelfmark/metadata_providers/googlebooks.py b/shelfmark/metadata_providers/googlebooks.py index 72929d28..86b8174a 100644 --- a/shelfmark/metadata_providers/googlebooks.py +++ b/shelfmark/metadata_providers/googlebooks.py @@ -158,10 +158,11 @@ class GoogleBooksProvider(MetadataProvider): query = "+".join(query_parts) # Build request params + page_size = min(options.limit, 40) # Google max is 40 params: dict[str, Any] = { "q": query, - "maxResults": min(options.limit, 40), # Google max is 40 - "startIndex": (options.page - 1) * options.limit, + "maxResults": page_size, + "startIndex": (options.page - 1) * page_size, "printType": "books", # Exclude magazines } diff --git a/tests/metadata/test_googlebooks_parse.py b/tests/metadata/test_googlebooks_parse.py index 9557e724..2a7ad661 100644 --- a/tests/metadata/test_googlebooks_parse.py +++ b/tests/metadata/test_googlebooks_parse.py @@ -39,6 +39,15 @@ class _FlakyGoogleBooksSession: ) +class _RecordingGoogleBooksSession: + def __init__(self): + self.params = [] + + def get(self, *args, **kwargs): + self.params.append(dict(kwargs["params"])) + return _GoogleBooksResponse({"items": []}) + + def test_googlebooks_search_does_not_cache_request_failures(): get_metadata_cache().clear() provider = GoogleBooksProvider(api_key="test-key") @@ -54,6 +63,33 @@ def test_googlebooks_search_does_not_cache_request_failures(): assert [book.title for book in result] == ["Recovered Book"] +def test_googlebooks_pages_tile_when_limit_exceeds_api_maximum(): + get_metadata_cache().clear() + provider = GoogleBooksProvider(api_key="test-key") + session = _RecordingGoogleBooksSession() + provider.session = session + + for page in (1, 2): + provider.search(MetadataSearchOptions(query="Dune", limit=50, page=page)) + + first, second = session.params + assert first["maxResults"] == 40 + assert first["startIndex"] == 0 + assert second["startIndex"] == first["startIndex"] + first["maxResults"] + + +def test_googlebooks_page_stride_follows_limit_below_api_maximum(): + get_metadata_cache().clear() + provider = GoogleBooksProvider(api_key="test-key") + session = _RecordingGoogleBooksSession() + provider.session = session + + provider.search(MetadataSearchOptions(query="Dune", limit=25, page=3)) + + assert session.params[0]["maxResults"] == 25 + assert session.params[0]["startIndex"] == 50 + + class TestGoogleBooksParseVolume: def test_parse_volume_returns_metadata_for_valid_payload(self): provider = GoogleBooksProvider(api_key="test-key")