@@ -28,9 +28,7 @@ def test_fetch_metadata_success(
2828 client : TINDClient ,
2929) -> None :
3030 """fetch_metadata returns a PyMARC Record for a valid record ID."""
31- requests_mock .get (
32- f"{ BASE_URL } /record/12345/" , text = sample_marc_xml , status_code = 200
33- )
31+ requests_mock .get (f"{ BASE_URL } /record/12345/" , text = sample_marc_xml , status_code = 200 )
3432 record = client .fetch_metadata ("12345" )
3533 assert record ["245" ]["a" ] == "Sample Title"
3634
@@ -42,9 +40,7 @@ def test_fetch_metadata_404(requests_mock: req_mock.Mocker, client: TINDClient)
4240 client .fetch_metadata ("99999" )
4341
4442
45- def test_fetch_metadata_empty_body (
46- requests_mock : req_mock .Mocker , client : TINDClient
47- ) -> None :
43+ def test_fetch_metadata_empty_body (requests_mock : req_mock .Mocker , client : TINDClient ) -> None :
4844 """fetch_metadata raises RecordNotFoundError when the response body is empty."""
4945 requests_mock .get (f"{ BASE_URL } /record/11111/" , text = " " , status_code = 200 )
5046 with pytest .raises (RecordNotFoundError ):
@@ -96,9 +92,7 @@ def test_fetch_file_not_found(
9692# ---------------------------------------------------------------------------
9793
9894
99- def test_fetch_file_metadata_success (
100- requests_mock : req_mock .Mocker , client : TINDClient
101- ) -> None :
95+ def test_fetch_file_metadata_success (requests_mock : req_mock .Mocker , client : TINDClient ) -> None :
10296 """fetch_file_metadata returns a list of file metadata dicts."""
10397 payload = [{"name" : "file.pdf" , "size" : 1024 }]
10498 requests_mock .get (
@@ -110,9 +104,7 @@ def test_fetch_file_metadata_success(
110104 assert result [0 ]["name" ] == "file.pdf"
111105
112106
113- def test_fetch_file_metadata_error (
114- requests_mock : req_mock .Mocker , client : TINDClient
115- ) -> None :
107+ def test_fetch_file_metadata_error (requests_mock : req_mock .Mocker , client : TINDClient ) -> None :
116108 """fetch_file_metadata raises TINDError on non-200 responses."""
117109 requests_mock .get (
118110 f"{ BASE_URL } /record/12345/files" ,
@@ -128,9 +120,7 @@ def test_fetch_file_metadata_error(
128120# ---------------------------------------------------------------------------
129121
130122
131- def test_fetch_ids_search_success (
132- requests_mock : req_mock .Mocker , client : TINDClient
133- ) -> None :
123+ def test_fetch_ids_search_success (requests_mock : req_mock .Mocker , client : TINDClient ) -> None :
134124 """fetch_ids_search returns the list of record IDs from the search response."""
135125 requests_mock .get (
136126 f"{ BASE_URL } /search" ,
@@ -141,9 +131,7 @@ def test_fetch_ids_search_success(
141131 assert ids == ["1" , "2" , "3" ]
142132
143133
144- def test_fetch_ids_search_error (
145- requests_mock : req_mock .Mocker , client : TINDClient
146- ) -> None :
134+ def test_fetch_ids_search_error (requests_mock : req_mock .Mocker , client : TINDClient ) -> None :
147135 """fetch_ids_search raises TINDError on non-200 responses."""
148136 requests_mock .get (
149137 f"{ BASE_URL } /search" ,
@@ -184,6 +172,7 @@ def test_search_returns_xml(
184172 assert len (results ) >= 1
185173 assert requests_mock .call_count == 1
186174
175+
187176# ---------------------------------------------------------------------------
188177# write_search_results_to_file / _iter_xml_records
189178# ---------------------------------------------------------------------------
@@ -197,7 +186,7 @@ def test_write_search_results_to_file_with_malformed_output_filename(
197186) -> None :
198187 """write_search_results_to_file raises ValueError for a malformed output filename."""
199188 with pytest .raises (ValueError , match = "output_file_name" ):
200- client .write_search_results_to_file ("" , output_file_name = malformed_filename )
189+ client .write_search_results_to_file ("" , output_file_name = malformed_filename )
201190
202191
203192def test_write_search_results_to_file_empty_filename (client : TINDClient ) -> None :
@@ -247,15 +236,18 @@ def test_write_search_results_to_file_success(
247236 tree = E .parse (tmp_path / "out.xml" )
248237 records = tree .getroot ().findall (f"{{{ marc21_ns } }}record" )
249238 assert len (records ) == 3
250- assert tree .getroot ().findtext (f"{{{ marc21_ns } }}record/{{{ marc21_ns } }}controlfield[@tag='001']" ) == "27320"
239+ assert (
240+ tree .getroot ().findtext (f"{{{ marc21_ns } }}record/{{{ marc21_ns } }}controlfield[@tag='001']" )
241+ == "27320"
242+ )
251243
252244
253- def test_write_search_results_to_file_count_mismatch (
245+ def test_write_search_results_to_file_matched_but_no_records_returned (
254246 requests_mock : req_mock .Mocker ,
255247 client : TINDClient ,
256248 tmp_path : Path ,
257249) -> None :
258- """write_search_results_to_file raises TINDError when streamed record count != ID count. """
250+ """write_search_results_to_file raises TINDError when API returns no records for matched IDs """
259251 client .default_storage_dir = str (tmp_path )
260252 requests_mock .get (
261253 f"{ BASE_URL } /search" ,
@@ -266,13 +258,39 @@ def test_write_search_results_to_file_count_mismatch(
266258 {"text" : (FIXTURES / "end-of-batch-tind-response.xml" ).read_text (), "status_code" : 200 },
267259 ],
268260 )
269- with pytest .raises (TINDError , match = "Expected 3 records" ):
261+ with pytest .raises (TINDError , match = "API did not return any." ):
262+ client .write_search_results_to_file ("collection:'test'" , "mismatch.xml" )
263+
264+
265+ def test_write_search_results_to_file_matched_but_api_mismatch (
266+ requests_mock : req_mock .Mocker ,
267+ client : TINDClient ,
268+ tmp_path : Path ,
269+ ) -> None :
270+ """write_search_results_to_file raises TINDError when streamed record count != ID count."""
271+ client .default_storage_dir = str (tmp_path )
272+ requests_mock .get (
273+ f"{ BASE_URL } /search" ,
274+ response_list = [
275+ # fetch_ids_search says 3 hits
276+ {
277+ "text" : json .dumps ({"hits" : ["27320" , "28819" , "29563" , "123123" ]}),
278+ "status_code" : 200 ,
279+ },
280+ # first paginated XML batch, but only 3 records instead of 4 as expected from the IDs
281+ {"text" : (FIXTURES / "1st-batch-tind-response.xml" ).read_text (), "status_code" : 200 },
282+ # but the XML stream returns nothing immediately
283+ {"text" : (FIXTURES / "end-of-batch-tind-response.xml" ).read_text (), "status_code" : 200 },
284+ ],
285+ )
286+ with pytest .raises (TINDError , match = "Expected 4 records" ):
270287 client .write_search_results_to_file ("collection:'test'" , "mismatch.xml" )
271288
289+
272290def test_write_search_results_to_file_malformed_xml_response (
273- requests_mock : req_mock .Mocker ,
274- client : TINDClient ,
275- tmp_path : Path ,
291+ requests_mock : req_mock .Mocker ,
292+ client : TINDClient ,
293+ tmp_path : Path ,
276294) -> None :
277295 """write_search_results_to_file raises TINDError when the API returns malformed XML."""
278296 client .default_storage_dir = str (tmp_path )
0 commit comments