11import json
22from datetime import datetime , timezone
3- from unittest .mock import MagicMock , patch
3+ from unittest .mock import MagicMock , call , patch
44
55import pytest
66from delete_pointers_by_id import (
@@ -232,11 +232,16 @@ def test_some_unprocessed(self, mock_dynamodb):
232232
233233class TestDeletePointersById :
234234 def test_missing_params (self ):
235- with pytest .raises (ValueError ):
235+ with pytest .raises (
236+ ValueError , match = "Provide either pointers_to_delete or pointers_file"
237+ ):
236238 _delete_pointers_by_id ("t" , "G3H9E" )
237239
238240 def test_both_params_provided (self ):
239- with pytest .raises (ValueError ):
241+ with pytest .raises (
242+ ValueError ,
243+ match = "Provide either pointers_to_delete or pointers_file, not both" ,
244+ ):
240245 _delete_pointers_by_id (
241246 "t" , "G3H9E" , pointers_to_delete = ["a" ], pointers_file = "./f"
242247 )
@@ -246,38 +251,36 @@ def test_both_params_provided(self):
246251 @patch ("delete_pointers_by_id._batch_get_existing_pointers" )
247252 @patch ("delete_pointers_by_id._batch_delete_pointers" )
248253 def test_empty_pointers_list (self , mock_delete , mock_get , mock_check , mock_build ):
249- mock_build .return_value = {
250- "pointers_to_delete" : 0 ,
251- "ods_code_matched" : {"count" : 0 },
252- "output_filename" : "delete_results_G3H9E_20231125T120000Z.json" ,
253- }
254- result = _delete_pointers_by_id ("t" , "G3H9E" , pointers_to_delete = [])
255- assert result ["pointers_to_delete" ] == 0
254+ _delete_pointers_by_id ("t" , "G3H9E" , pointers_to_delete = [])
255+
256256 mock_build .assert_called_once ()
257+
257258 mock_check .assert_not_called ()
258259 mock_get .assert_not_called ()
259260 mock_delete .assert_not_called ()
260261
262+ call_args = mock_build .call_args [0 ][0 ]
263+ assert call_args .pointers_to_delete == []
264+ assert call_args .matched_pointers == []
265+
261266 @patch ("delete_pointers_by_id._build_and_write_result" )
262267 @patch ("delete_pointers_by_id._check_pointers_match_ods_code" )
263268 @patch ("delete_pointers_by_id._batch_get_existing_pointers" )
264269 @patch ("delete_pointers_by_id._batch_delete_pointers" )
265270 def test_no_matched_ods_codes (self , mock_delete , mock_get , mock_check , mock_build ):
266271 mock_check .return_value = ([], ["RAT-1" , "RAT-2" ])
267- mock_build .return_value = {
268- "ods_code_matched" : {"count" : 0 },
269- "ods_code_mismatched" : {"count" : 2 },
270- "output_filename" : "delete_results_G3H9E_20231125T120000Z.json" ,
271- }
272- result = _delete_pointers_by_id (
273- "t" , "G3H9E" , pointers_to_delete = ["RAT-1" , "RAT-2" ]
274- )
275- assert result ["ods_code_matched" ]["count" ] == 0
276- assert result ["ods_code_mismatched" ]["count" ] == 2
272+
273+ _delete_pointers_by_id ("t" , "G3H9E" , pointers_to_delete = ["RAT-1" , "RAT-2" ])
274+
277275 mock_build .assert_called_once ()
276+ mock_check .assert_called_once ()
278277 mock_get .assert_not_called ()
279278 mock_delete .assert_not_called ()
280279
280+ call_args = mock_build .call_args [0 ][0 ]
281+ assert call_args .matched_pointers == []
282+ assert call_args .mismatched_pointers == ["RAT-1" , "RAT-2" ]
283+
281284 @patch ("delete_pointers_by_id._build_and_write_result" )
282285 @patch ("delete_pointers_by_id._check_pointers_match_ods_code" )
283286 @patch ("delete_pointers_by_id._batch_get_existing_pointers" )
@@ -287,17 +290,17 @@ def test_successful_flow(self, mock_delete, mock_get, mock_check, mock_build):
287290 mock_check .return_value = (ids , [])
288291 mock_get .return_value = (ids , [])
289292 mock_delete .return_value = (ids , [])
290- mock_build .return_value = {
291- "pointers_to_delete" : 2 ,
292- "deleted_pointers" : {"count" : 2 },
293- "pointer_not_found" : {"count" : 0 },
294- "output_filename" : "delete_results_G3H9E_20231125T120000Z.json" ,
295- }
296- result = _delete_pointers_by_id ("t" , "G3H9E" , pointers_to_delete = ids )
297- assert result ["pointers_to_delete" ] == 2
298- assert result ["deleted_pointers" ]["count" ] == 2
299- assert result ["pointer_not_found" ]["count" ] == 0
293+
294+ _delete_pointers_by_id ("t" , "G3H9E" , pointers_to_delete = ids )
295+
300296 mock_build .assert_called_once ()
297+ mock_check .assert_called_once ()
298+ mock_get .assert_called_once ()
299+ mock_delete .assert_called_once ()
300+
301+ call_args = mock_build .call_args [0 ][0 ]
302+ assert call_args .pointers_deleted == ids
303+ assert call_args .failed_deletes == []
301304
302305 @patch ("delete_pointers_by_id._build_and_write_result" )
303306 @patch ("delete_pointers_by_id._check_pointers_match_ods_code" )
@@ -308,21 +311,16 @@ def test_partial_with_failures(self, mock_delete, mock_get, mock_check, mock_bui
308311 mock_check .return_value = (matched , ["RAT-1" ])
309312 mock_get .return_value = (matched , [])
310313 mock_delete .return_value = (["G3H9E-1" , "G3H9E-2" ], ["G3H9E-3" ])
311- mock_build .return_value = {
312- "ods_code_mismatched" : {"count" : 1 },
313- "deleted_pointers" : {"count" : 2 },
314- "failed_deletes" : {"count" : 1 , "ids" : ["G3H9E-3" ]},
315- "output_filename" : "delete_results_G3H9E_20231125T120000Z.json" ,
316- }
317- result = _delete_pointers_by_id (
318- "t" , "G3H9E" , pointers_to_delete = matched + ["RAT-1" ]
319- )
320- assert result ["ods_code_mismatched" ]["count" ] == 1
321- assert result ["deleted_pointers" ]["count" ] == 2
322- assert result ["failed_deletes" ]["count" ] == 1
323- assert "G3H9E-3" in result ["failed_deletes" ]["ids" ]
314+
315+ _delete_pointers_by_id ("t" , "G3H9E" , pointers_to_delete = matched + ["RAT-1" ])
316+
324317 mock_build .assert_called_once ()
325318
319+ call_args = mock_build .call_args [0 ][0 ]
320+ assert call_args .mismatched_pointers == ["RAT-1" ]
321+ assert call_args .pointers_deleted == ["G3H9E-1" , "G3H9E-2" ]
322+ assert call_args .failed_deletes == ["G3H9E-3" ]
323+
326324 @patch ("delete_pointers_by_id._build_and_write_result" )
327325 @patch ("delete_pointers_by_id._check_pointers_match_ods_code" )
328326 @patch ("delete_pointers_by_id._batch_get_existing_pointers" )
@@ -334,13 +332,30 @@ def test_some_pointers_not_found(
334332 mock_check .return_value = (matched , [])
335333 mock_get .return_value = (["G3H9E-1" , "G3H9E-2" ], ["G3H9E-3" ])
336334 mock_delete .return_value = (["G3H9E-1" , "G3H9E-2" ], [])
337- mock_build .return_value = {
338- "pointer_not_found" : {"count" : 1 , "ids" : ["G3H9E-3" ]},
339- "deleted_pointers" : {"count" : 2 },
340- "output_filename" : "delete_results_G3H9E_20231125T120000Z.json" ,
341- }
342- result = _delete_pointers_by_id ("t" , "G3H9E" , pointers_to_delete = matched )
343- assert result ["pointer_not_found" ]["count" ] == 1
344- assert "G3H9E-3" in result ["pointer_not_found" ]["ids" ]
345- assert result ["deleted_pointers" ]["count" ] == 2
335+
336+ _delete_pointers_by_id ("t" , "G3H9E" , pointers_to_delete = matched )
337+
338+ mock_build .assert_called_once ()
339+
340+ call_args = mock_build .call_args [0 ][0 ]
341+ assert call_args .not_found_pointers == ["G3H9E-3" ]
342+ assert call_args .pointers_deleted == ["G3H9E-1" , "G3H9E-2" ]
343+
344+ @patch ("delete_pointers_by_id._build_and_write_result" )
345+ @patch ("delete_pointers_by_id._check_pointers_match_ods_code" )
346+ @patch ("delete_pointers_by_id._batch_get_existing_pointers" )
347+ @patch ("delete_pointers_by_id._batch_delete_pointers" )
348+ def test_no_existing_pointers (self , mock_delete , mock_get , mock_check , mock_build ):
349+ matched = ["G3H9E-1" , "G3H9E-2" ]
350+ mock_check .return_value = (matched , [])
351+ mock_get .return_value = ([], matched )
352+
353+ _delete_pointers_by_id ("t" , "G3H9E" , pointers_to_delete = matched )
354+
346355 mock_build .assert_called_once ()
356+ mock_delete .assert_not_called ()
357+
358+ # Verify the context
359+ call_args = mock_build .call_args [0 ][0 ]
360+ assert call_args .not_found_pointers == matched
361+ assert call_args .pointers_deleted == []
0 commit comments