Skip to content

Commit 33516e7

Browse files
committed
Improve test coverage.
1 parent 1746dcd commit 33516e7

1 file changed

Lines changed: 120 additions & 0 deletions

File tree

tests/manager/integration/metadata/lexile/test_api.py

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22

33
from __future__ import annotations
44

5+
from unittest.mock import patch
6+
57
import pytest
68

79
from palace.manager.core.exceptions import IntegrationException
810
from palace.manager.integration.metadata.lexile.api import LexileDBAPI
911
from palace.manager.integration.metadata.lexile.settings import LexileDBSettings
12+
from palace.manager.util.http.http import HTTP
1013
from tests.fixtures.http import MockHttpClientFixture
1114

1215

@@ -197,3 +200,120 @@ def test_fetch_lexile_for_isbn_raise_on_error_403(
197200
api.fetch_lexile_for_isbn("9780123456789", raise_on_error=True)
198201

199202
assert "authentication" in str(excinfo.value).lower()
203+
204+
def test_fetch_lexile_for_isbn_http_exception_returns_none(
205+
self, http_client: MockHttpClientFixture
206+
) -> None:
207+
"""API returns None when HTTP request raises an exception."""
208+
with patch.object(
209+
HTTP, "get_with_timeout", side_effect=Exception("Connection refused")
210+
):
211+
settings = LexileDBSettings(
212+
username="user",
213+
password="pass",
214+
base_url="https://api.example.com",
215+
)
216+
api = LexileDBAPI(settings)
217+
218+
result = api.fetch_lexile_for_isbn("9780123456789")
219+
220+
assert result is None
221+
222+
def test_fetch_lexile_for_isbn_http_exception_raise_on_error(
223+
self, http_client: MockHttpClientFixture
224+
) -> None:
225+
"""API raises IntegrationException when HTTP request fails and raise_on_error=True."""
226+
with patch.object(
227+
HTTP, "get_with_timeout", side_effect=Exception("Connection refused")
228+
):
229+
settings = LexileDBSettings(
230+
username="user",
231+
password="pass",
232+
base_url="https://api.example.com",
233+
)
234+
api = LexileDBAPI(settings)
235+
236+
with pytest.raises(IntegrationException) as excinfo:
237+
api.fetch_lexile_for_isbn("9780123456789", raise_on_error=True)
238+
239+
assert "Lexile API request failed" in str(excinfo.value)
240+
assert "Connection refused" in str(excinfo.value)
241+
242+
def test_fetch_lexile_for_isbn_non_401_403_raise_on_error(
243+
self, http_client: MockHttpClientFixture
244+
) -> None:
245+
"""API raises IntegrationException on 500 when raise_on_error=True."""
246+
http_client.queue_response(500, content="Internal Server Error")
247+
settings = LexileDBSettings(
248+
username="user",
249+
password="pass",
250+
base_url="https://api.example.com",
251+
)
252+
api = LexileDBAPI(settings)
253+
254+
with pytest.raises(IntegrationException) as excinfo:
255+
api.fetch_lexile_for_isbn("9780123456789", raise_on_error=True)
256+
257+
assert "Lexile API request failed" in str(excinfo.value)
258+
assert "500" in str(excinfo.value)
259+
260+
def test_fetch_lexile_for_isbn_invalid_json(
261+
self, http_client: MockHttpClientFixture
262+
) -> None:
263+
"""API returns None when response body is invalid JSON."""
264+
http_client.queue_response(200, content="not valid json")
265+
settings = LexileDBSettings(
266+
username="user",
267+
password="pass",
268+
base_url="https://api.example.com",
269+
)
270+
api = LexileDBAPI(settings)
271+
272+
result = api.fetch_lexile_for_isbn("9780123456789")
273+
274+
assert result is None
275+
276+
def test_fetch_lexile_for_isbn_non_numeric_lexile(
277+
self, http_client: MockHttpClientFixture
278+
) -> None:
279+
"""API returns None when lexile field is non-numeric."""
280+
http_client.queue_response(
281+
200,
282+
content={
283+
"meta": {"total_count": 1},
284+
"objects": [{"lexile": "abc"}],
285+
},
286+
)
287+
settings = LexileDBSettings(
288+
username="user",
289+
password="pass",
290+
base_url="https://api.example.com",
291+
)
292+
api = LexileDBAPI(settings)
293+
294+
result = api.fetch_lexile_for_isbn("9780123456789")
295+
296+
assert result is None
297+
298+
def test_fetch_lexile_for_isbn_base_url_trailing_slash(
299+
self, http_client: MockHttpClientFixture
300+
) -> None:
301+
"""API constructs URL correctly when base_url has trailing slash."""
302+
http_client.queue_response(
303+
200,
304+
content={
305+
"meta": {"total_count": 1},
306+
"objects": [{"lexile": 650}],
307+
},
308+
)
309+
settings = LexileDBSettings(
310+
username="user",
311+
password="pass",
312+
base_url="https://api.example.com/",
313+
)
314+
api = LexileDBAPI(settings)
315+
316+
result = api.fetch_lexile_for_isbn("9780123456789")
317+
318+
assert result == 650
319+
assert "https://api.example.com/api/fab/v3/book/" in http_client.requests[0]

0 commit comments

Comments
 (0)