@@ -41,33 +41,6 @@ def test_load_empty_file(self, mock_open):
4141 assert result == []
4242
4343
44- class TestBuildAndWriteResult :
45- @patch ("delete_pointers_by_id._write_result_file" )
46- @patch ("delete_pointers_by_id._print_summary" )
47- def test_build_and_write_result (self , mock_print , mock_write ):
48- start_time = datetime .now (tz = timezone .utc )
49- end_time = datetime .now (tz = timezone .utc )
50- ctx = PointerDeletionContext (
51- pointers_to_delete = ["G3H9E-1" , "G3H9E-2" ],
52- ods_code = "G3H9E" ,
53- matched_pointers = ["G3H9E-1" , "G3H9E-2" ],
54- mismatched_pointers = [],
55- not_found_pointers = [],
56- pointers_deleted = ["G3H9E-1" , "G3H9E-2" ],
57- failed_deletes = [],
58- start_time = start_time ,
59- end_time = end_time ,
60- output_file_path = "/tmp/test.json" ,
61- )
62- result = _build_and_write_result (ctx )
63-
64- assert result ["pointers_to_delete" ] == 2
65- assert result ["deleted_pointers" ]["count" ] == 2
66- assert result ["ods_code" ] == "G3H9E"
67- mock_write .assert_called_once ()
68- mock_print .assert_called_once ()
69-
70-
7144class TestParseJsonPointers :
7245 def test_invalid_json (self ):
7346 content = '[{"id": "G3H9E-id1"'
@@ -131,6 +104,60 @@ def test_empty_plain_text(self):
131104 assert result == []
132105
133106
107+ class TestBuildAndWriteResult :
108+ @patch ("delete_pointers_by_id._write_result_file" )
109+ @patch ("delete_pointers_by_id._print_summary" )
110+ def test_build_and_write_result_success (self , mock_print , mock_write ):
111+ start_time = datetime .now (tz = timezone .utc )
112+ end_time = datetime .now (tz = timezone .utc )
113+ ctx = PointerDeletionContext (
114+ pointers_to_delete = ["G3H9E-1" , "G3H9E-2" ],
115+ ods_code = "G3H9E" ,
116+ matched_pointers = ["G3H9E-1" , "G3H9E-2" ],
117+ mismatched_pointers = [],
118+ not_found_pointers = [],
119+ pointers_deleted = ["G3H9E-1" , "G3H9E-2" ],
120+ failed_deletes = [],
121+ start_time = start_time ,
122+ end_time = end_time ,
123+ output_filename = "delete_results_G3H9E_20231125T120000Z.json" ,
124+ )
125+ result = _build_and_write_result (ctx )
126+
127+ assert result ["pointers_to_delete" ] == 2
128+ assert result ["deleted_pointers" ]["count" ] == 2
129+ assert result ["ods_code" ] == "G3H9E"
130+ assert result ["output_filename" ] == "delete_results_G3H9E_20231125T120000Z.json"
131+ assert "_output_error" not in result
132+ mock_write .assert_called_once ()
133+ mock_print .assert_called_once ()
134+
135+ @patch ("delete_pointers_by_id._write_result_file" )
136+ @patch ("delete_pointers_by_id._print_summary" )
137+ def test_build_and_write_result_with_error (self , mock_print , mock_write ):
138+ mock_write .side_effect = Exception ("Write failed" )
139+ start_time = datetime .now (tz = timezone .utc )
140+ end_time = datetime .now (tz = timezone .utc )
141+ ctx = PointerDeletionContext (
142+ pointers_to_delete = ["G3H9E-1" ],
143+ ods_code = "G3H9E" ,
144+ matched_pointers = ["G3H9E-1" ],
145+ mismatched_pointers = [],
146+ not_found_pointers = [],
147+ pointers_deleted = ["G3H9E-1" ],
148+ failed_deletes = [],
149+ start_time = start_time ,
150+ end_time = end_time ,
151+ output_filename = "delete_results_G3H9E_20231125T120000Z.json" ,
152+ )
153+ result = _build_and_write_result (ctx )
154+
155+ assert "_output_error" in result
156+ assert "Write failed" in result ["_output_error" ]
157+ mock_write .assert_called_once ()
158+ mock_print .assert_called_once ()
159+
160+
134161class TestCheckPointersMatchOdsCode :
135162 def test_all_match (self ):
136163 ods = "G3H9E"
@@ -173,16 +200,6 @@ def test_none_exist(self, mock_dynamodb):
173200 existing , not_found = _batch_get_existing_pointers (table , ids )
174201 assert existing == [] and not_found == ids
175202
176- @patch ("delete_pointers_by_id.dynamodb" )
177- def test_some_exist (self , mock_dynamodb ):
178- table = "t"
179- ids = ["G3H9E-1" , "G3H9E-3" ]
180- mock_dynamodb .batch_get_item .return_value = {
181- "Responses" : {table : [{"pk" : {"S" : "D#G3H9E-1" }}]}
182- }
183- existing , not_found = _batch_get_existing_pointers (table , ids )
184- assert existing == ["G3H9E-1" ] and not_found == ["G3H9E-3" ]
185-
186203
187204class TestBatchDeletePointers :
188205 @patch ("delete_pointers_by_id.dynamodb" )
@@ -224,6 +241,23 @@ def test_both_params_provided(self):
224241 "t" , "G3H9E" , pointers_to_delete = ["a" ], pointers_file = "./f"
225242 )
226243
244+ @patch ("delete_pointers_by_id._build_and_write_result" )
245+ @patch ("delete_pointers_by_id._check_pointers_match_ods_code" )
246+ @patch ("delete_pointers_by_id._batch_get_existing_pointers" )
247+ @patch ("delete_pointers_by_id._batch_delete_pointers" )
248+ 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
256+ mock_build .assert_called_once ()
257+ mock_check .assert_not_called ()
258+ mock_get .assert_not_called ()
259+ mock_delete .assert_not_called ()
260+
227261 @patch ("delete_pointers_by_id._build_and_write_result" )
228262 @patch ("delete_pointers_by_id._check_pointers_match_ods_code" )
229263 @patch ("delete_pointers_by_id._batch_get_existing_pointers" )
@@ -233,13 +267,16 @@ def test_no_matched_ods_codes(self, mock_delete, mock_get, mock_check, mock_buil
233267 mock_build .return_value = {
234268 "ods_code_matched" : {"count" : 0 },
235269 "ods_code_mismatched" : {"count" : 2 },
270+ "output_filename" : "delete_results_G3H9E_20231125T120000Z.json" ,
236271 }
237272 result = _delete_pointers_by_id (
238273 "t" , "G3H9E" , pointers_to_delete = ["RAT-1" , "RAT-2" ]
239274 )
240275 assert result ["ods_code_matched" ]["count" ] == 0
241276 assert result ["ods_code_mismatched" ]["count" ] == 2
242277 mock_build .assert_called_once ()
278+ mock_get .assert_not_called ()
279+ mock_delete .assert_not_called ()
243280
244281 @patch ("delete_pointers_by_id._build_and_write_result" )
245282 @patch ("delete_pointers_by_id._check_pointers_match_ods_code" )
@@ -254,6 +291,7 @@ def test_successful_flow(self, mock_delete, mock_get, mock_check, mock_build):
254291 "pointers_to_delete" : 2 ,
255292 "deleted_pointers" : {"count" : 2 },
256293 "pointer_not_found" : {"count" : 0 },
294+ "output_filename" : "delete_results_G3H9E_20231125T120000Z.json" ,
257295 }
258296 result = _delete_pointers_by_id ("t" , "G3H9E" , pointers_to_delete = ids )
259297 assert result ["pointers_to_delete" ] == 2
@@ -274,6 +312,7 @@ def test_partial_with_failures(self, mock_delete, mock_get, mock_check, mock_bui
274312 "ods_code_mismatched" : {"count" : 1 },
275313 "deleted_pointers" : {"count" : 2 },
276314 "failed_deletes" : {"count" : 1 , "ids" : ["G3H9E-3" ]},
315+ "output_filename" : "delete_results_G3H9E_20231125T120000Z.json" ,
277316 }
278317 result = _delete_pointers_by_id (
279318 "t" , "G3H9E" , pointers_to_delete = matched + ["RAT-1" ]
@@ -298,6 +337,7 @@ def test_some_pointers_not_found(
298337 mock_build .return_value = {
299338 "pointer_not_found" : {"count" : 1 , "ids" : ["G3H9E-3" ]},
300339 "deleted_pointers" : {"count" : 2 },
340+ "output_filename" : "delete_results_G3H9E_20231125T120000Z.json" ,
301341 }
302342 result = _delete_pointers_by_id ("t" , "G3H9E" , pointers_to_delete = matched )
303343 assert result ["pointer_not_found" ]["count" ] == 1
0 commit comments