Skip to content

Commit eabf016

Browse files
committed
Draft tests for fewer pages than per_page fix
1 parent 8e7957a commit eabf016

1 file changed

Lines changed: 151 additions & 0 deletions

File tree

discogs_client/tests/test_core.py

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,157 @@ def test_pagination(self):
111111
results.per_page = 10
112112
self.assertTrue(results._num_pages is None)
113113

114+
def test_pagination_with_short_page(self):
115+
"""Indexing walks actual page sizes when the API under-fills a page."""
116+
client = Client('ua')
117+
client._base_url = ''
118+
client._fetcher = MemoryFetcher({
119+
'/artists/1': (
120+
b'{"id": 1, "name": "Badger", "releases_url": "/artists/1/releases"}',
121+
200,
122+
),
123+
'/artists/1/releases?page=1&per_page=50': (
124+
b'{"pagination": {"per_page": 50, "pages": 2, "items": 2}, '
125+
b'"releases": [{"id": 101, "type": "release", "title": "First"}]}',
126+
200,
127+
),
128+
'/artists/1/releases?page=2&per_page=50': (
129+
b'{"pagination": {"per_page": 50, "pages": 2, "items": 2}, '
130+
b'"releases": [{"id": 102, "type": "release", "title": "Second"}]}',
131+
200,
132+
),
133+
})
134+
135+
results = client.artist(1).releases
136+
137+
self.assertEqual(results.pages, 2)
138+
self.assertEqual(len(results.page(1)), 1)
139+
self.assertEqual(results[0].id, 101)
140+
self.assertEqual(results[1].id, 102)
141+
self.assertRaises(IndexError, lambda: results[2])
142+
143+
def test_pagination_with_varying_page_sizes(self):
144+
"""Indexing works correctly with pages of different actual sizes."""
145+
client = Client('ua')
146+
client._base_url = ''
147+
client._fetcher = MemoryFetcher({
148+
'/artists/1': (
149+
b'{"id": 1, "name": "Badger", "releases_url": "/artists/1/releases"}',
150+
200,
151+
),
152+
'/artists/1/releases?page=1&per_page=50': (
153+
b'{"pagination": {"per_page": 50, "pages": 3, "items": 8}, '
154+
b'"releases": ['
155+
b'{"id": 101, "type": "release", "title": "First"},'
156+
b'{"id": 102, "type": "release", "title": "Second"},'
157+
b'{"id": 103, "type": "release", "title": "Third"}'
158+
b']}',
159+
200,
160+
),
161+
'/artists/1/releases?page=2&per_page=50': (
162+
b'{"pagination": {"per_page": 50, "pages": 3, "items": 8}, '
163+
b'"releases": ['
164+
b'{"id": 104, "type": "release", "title": "Fourth"},'
165+
b'{"id": 105, "type": "release", "title": "Fifth"}'
166+
b']}',
167+
200,
168+
),
169+
'/artists/1/releases?page=3&per_page=50': (
170+
b'{"pagination": {"per_page": 50, "pages": 3, "items": 8}, '
171+
b'"releases": ['
172+
b'{"id": 106, "type": "release", "title": "Sixth"},'
173+
b'{"id": 107, "type": "release", "title": "Seventh"},'
174+
b'{"id": 108, "type": "release", "title": "Eighth"}'
175+
b']}',
176+
200,
177+
),
178+
})
179+
180+
results = client.artist(1).releases
181+
182+
# Verify we can access items across all pages
183+
self.assertEqual(results[0].id, 101)
184+
self.assertEqual(results[1].id, 102)
185+
self.assertEqual(results[2].id, 103)
186+
self.assertEqual(results[3].id, 104) # First item on page 2
187+
self.assertEqual(results[4].id, 105) # Last item on page 2
188+
self.assertEqual(results[5].id, 106) # First item on page 3
189+
self.assertEqual(results[7].id, 108) # Last item
190+
191+
# Verify out-of-bounds access raises IndexError
192+
self.assertRaises(IndexError, lambda: results[8])
193+
194+
def test_pagination_with_short_page_sequential_traversal(self):
195+
"""Verify sequential page walking works when all pages are short."""
196+
client = Client('ua')
197+
client._base_url = ''
198+
client._fetcher = MemoryFetcher({
199+
'/artists/1': (
200+
b'{"id": 1, "name": "Badger", "releases_url": "/artists/1/releases"}',
201+
200,
202+
),
203+
'/artists/1/releases?page=1&per_page=50': (
204+
b'{"pagination": {"per_page": 50, "pages": 4, "items": 4}, '
205+
b'"releases": [{"id": 201, "type": "release", "title": "A"}]}',
206+
200,
207+
),
208+
'/artists/1/releases?page=2&per_page=50': (
209+
b'{"pagination": {"per_page": 50, "pages": 4, "items": 4}, '
210+
b'"releases": [{"id": 202, "type": "release", "title": "B"}]}',
211+
200,
212+
),
213+
'/artists/1/releases?page=3&per_page=50': (
214+
b'{"pagination": {"per_page": 50, "pages": 4, "items": 4}, '
215+
b'"releases": [{"id": 203, "type": "release", "title": "C"}]}',
216+
200,
217+
),
218+
'/artists/1/releases?page=4&per_page=50': (
219+
b'{"pagination": {"per_page": 50, "pages": 4, "items": 4}, '
220+
b'"releases": [{"id": 204, "type": "release", "title": "D"}]}',
221+
200,
222+
),
223+
})
224+
225+
results = client.artist(1).releases
226+
227+
# With per_page=50 but only 1 item per actual page,
228+
# math-based indexing would fail. Sequential walking should work.
229+
self.assertEqual(results[0].id, 201)
230+
self.assertEqual(results[1].id, 202)
231+
self.assertEqual(results[2].id, 203)
232+
self.assertEqual(results[3].id, 204)
233+
self.assertRaises(IndexError, lambda: results[4])
234+
235+
def test_pagination_404_exception_chaining(self):
236+
"""Verify that HTTPError 404 is properly chained when index is out of bounds."""
237+
client = Client('ua')
238+
client._base_url = ''
239+
client._fetcher = MemoryFetcher({
240+
'/artists/1': (
241+
b'{"id": 1, "name": "Badger", "releases_url": "/artists/1/releases"}',
242+
200,
243+
),
244+
'/artists/1/releases?page=1&per_page=50': (
245+
b'{"pagination": {"per_page": 50, "pages": 1, "items": 2}, '
246+
b'"releases": ['
247+
b'{"id": 301, "type": "release", "title": "Only"},'
248+
b'{"id": 302, "type": "release", "title": "Two"}'
249+
b']}',
250+
200,
251+
),
252+
})
253+
254+
results = client.artist(1).releases
255+
256+
# Access valid items
257+
self.assertEqual(results[0].id, 301)
258+
self.assertEqual(results[1].id, 302)
259+
260+
# Accessing beyond bounds should raise IndexError
261+
# (which is chained from HTTPError 404)
262+
with self.assertRaises(IndexError):
263+
results[100]
264+
114265
def test_timeout_defaults_to_none(self):
115266
# Need to create client without LoggingDelegator here
116267
# self.d would throw AttributeError trying to access timeout properties on LoggingDelegator

0 commit comments

Comments
 (0)