@@ -206,21 +206,24 @@ async def test_delete_permissions_folder_recursive_structure(self):
206
206
async def test_delete_permissions_target_entity_types_folder_only (self ):
207
207
"""Test filtering deletion by folder entity type only."""
208
208
# GIVEN a folder with child folder and file
209
- folder = Folder (id = "syn123" )
209
+ folder = Folder (id = "syn123" , name = "parent_folder" )
210
210
folder .sync_from_synapse_async = AsyncMock ()
211
211
212
- child_folder = Folder (id = "syn456" )
212
+ child_folder = Folder (id = "syn456" , name = "child_folder" )
213
213
child_folder .delete_permissions_async = AsyncMock ()
214
214
child_folder .sync_from_synapse_async = AsyncMock ()
215
215
child_folder .folders = []
216
216
child_folder .files = []
217
217
218
- child_file = File (id = "syn789" )
218
+ child_file = File (id = "syn789" , name = "child_file.txt" )
219
219
child_file .delete_permissions_async = AsyncMock ()
220
220
221
221
folder .folders = [child_folder ]
222
222
folder .files = [child_file ]
223
223
224
+ # Mock the _collect_entities method to avoid tree building complexity
225
+ folder ._collect_entities = AsyncMock (return_value = [folder , child_folder ])
226
+
224
227
# WHEN deleting permissions filtered by folder type only
225
228
await folder .delete_permissions_async (
226
229
recursive = True ,
@@ -241,21 +244,24 @@ async def test_delete_permissions_target_entity_types_folder_only(self):
241
244
async def test_delete_permissions_target_entity_types_file_only (self ):
242
245
"""Test filtering deletion by file entity type only."""
243
246
# GIVEN a folder with child folder and file
244
- folder = Folder (id = "syn123" )
247
+ folder = Folder (id = "syn123" , name = "parent_folder" )
245
248
folder .sync_from_synapse_async = AsyncMock ()
246
249
247
- child_folder = Folder (id = "syn456" )
250
+ child_folder = Folder (id = "syn456" , name = "child_folder" )
248
251
child_folder .delete_permissions_async = AsyncMock ()
249
252
child_folder .sync_from_synapse_async = AsyncMock ()
250
253
child_folder .folders = []
251
254
child_folder .files = []
252
255
253
- child_file = File (id = "syn789" )
256
+ child_file = File (id = "syn789" , name = "child_file.txt" )
254
257
child_file .delete_permissions_async = AsyncMock ()
255
258
256
259
folder .folders = [child_folder ]
257
260
folder .files = [child_file ]
258
261
262
+ # Mock the _collect_entities method to avoid tree building complexity
263
+ folder ._collect_entities = AsyncMock (return_value = [folder , child_file ])
264
+
259
265
# WHEN deleting permissions filtered by file type only
260
266
await folder .delete_permissions_async (
261
267
recursive = True ,
@@ -277,10 +283,10 @@ async def test_delete_permissions_target_entity_types_file_only(self):
277
283
async def test_delete_permissions_case_insensitive_entity_types (self ):
278
284
"""Test that entity type matching is case-insensitive."""
279
285
# GIVEN a folder with child entities
280
- folder = Folder (id = "syn123" )
286
+ folder = Folder (id = "syn123" , name = "parent_folder" )
281
287
folder .sync_from_synapse_async = AsyncMock ()
282
288
283
- child_folder = Folder (id = "syn456" )
289
+ child_folder = Folder (id = "syn456" , name = "child_folder" )
284
290
child_folder .delete_permissions_async = AsyncMock ()
285
291
child_folder .sync_from_synapse_async = AsyncMock ()
286
292
child_folder .folders = []
@@ -289,6 +295,9 @@ async def test_delete_permissions_case_insensitive_entity_types(self):
289
295
folder .folders = [child_folder ]
290
296
folder .files = []
291
297
298
+ # Mock the _collect_entities method to avoid tree building complexity
299
+ folder ._collect_entities = AsyncMock (return_value = [folder , child_folder ])
300
+
292
301
# WHEN deleting with mixed case entity types
293
302
await folder .delete_permissions_async (
294
303
include_container_content = True ,
@@ -344,7 +353,7 @@ async def test_delete_permissions_benefactor_tracking(self):
344
353
self .mock_get_benefactor .return_value = MagicMock (id = "syn999" )
345
354
346
355
# WHEN deleting permissions with benefactor tracker
347
- await file .delete_permissions_async (benefactor_tracker = tracker )
356
+ await file .delete_permissions_async (_benefactor_tracker = tracker )
348
357
349
358
# THEN delete_entity_acl should be called
350
359
self .mock_delete_acl .assert_called_once_with (
@@ -440,23 +449,28 @@ async def test_delete_permissions_complex_hierarchy_dry_run(self):
440
449
async def test_delete_permissions_folder_only_direct_children (self ):
441
450
"""Test deletion affecting only direct children, not recursive."""
442
451
# GIVEN a folder with nested structure
443
- parent_folder = Folder (id = "syn100" )
452
+ parent_folder = Folder (id = "syn100" , name = "parent_folder" )
444
453
parent_folder .sync_from_synapse_async = AsyncMock ()
445
454
446
- child_folder = Folder (id = "syn200" )
455
+ child_folder = Folder (id = "syn200" , name = "child_folder" )
447
456
child_folder .delete_permissions_async = AsyncMock ()
448
457
child_folder .sync_from_synapse_async = AsyncMock ()
449
458
child_folder .folders = []
450
459
child_folder .files = []
451
460
452
- grandchild_folder = Folder (id = "syn300" )
461
+ grandchild_folder = Folder (id = "syn300" , name = "grandchild_folder" )
453
462
grandchild_folder .delete_permissions_async = AsyncMock ()
454
463
grandchild_folder .sync_from_synapse_async = AsyncMock ()
455
464
456
465
child_folder .folders = [grandchild_folder ]
457
466
parent_folder .folders = [child_folder ]
458
467
parent_folder .files = []
459
468
469
+ # Mock the _collect_entities method to avoid tree building complexity
470
+ parent_folder ._collect_entities = AsyncMock (
471
+ return_value = [parent_folder , child_folder ]
472
+ )
473
+
460
474
# WHEN deleting with include_container_content=True but recursive=False
461
475
await parent_folder .delete_permissions_async (
462
476
include_container_content = True , recursive = False
@@ -478,7 +492,7 @@ async def test_delete_permissions_benefactor_impact_logging(self):
478
492
tracker .benefactor_children ["syn123" ] = ["syn456" , "syn789" ]
479
493
480
494
# WHEN deleting permissions
481
- await file .delete_permissions_async (benefactor_tracker = tracker )
495
+ await file .delete_permissions_async (_benefactor_tracker = tracker )
482
496
483
497
# THEN deletion should complete
484
498
self .mock_delete_acl .assert_called_once ()
@@ -516,7 +530,7 @@ async def test_delete_permissions_entity_without_sync_method(self):
516
530
async def test_delete_permissions_large_hierarchy_performance (self ):
517
531
"""Test performance considerations with large hierarchy."""
518
532
# GIVEN a folder with many children
519
- parent_folder = Folder (id = "syn100" )
533
+ parent_folder = Folder (id = "syn100" , name = "parent_folder" )
520
534
parent_folder .sync_from_synapse_async = AsyncMock ()
521
535
522
536
# Create many child entities
@@ -525,20 +539,24 @@ async def test_delete_permissions_large_hierarchy_performance(self):
525
539
child_files = []
526
540
527
541
for i in range (num_children ):
528
- child_folder = Folder (id = f"syn{ 200 + i } " )
542
+ child_folder = Folder (id = f"syn{ 200 + i } " , name = f"child_folder_ { i } " )
529
543
child_folder .delete_permissions_async = AsyncMock ()
530
544
child_folder .sync_from_synapse_async = AsyncMock ()
531
545
child_folder .folders = []
532
546
child_folder .files = []
533
547
child_folders .append (child_folder )
534
548
535
- child_file = File (id = f"syn{ 300 + i } " )
549
+ child_file = File (id = f"syn{ 300 + i } " , name = f"child_file_ { i } .txt" )
536
550
child_file .delete_permissions_async = AsyncMock ()
537
551
child_files .append (child_file )
538
552
539
553
parent_folder .folders = child_folders
540
554
parent_folder .files = child_files
541
555
556
+ # Mock the _collect_entities method to avoid tree building complexity
557
+ all_entities = [parent_folder ] + child_folders + child_files
558
+ parent_folder ._collect_entities = AsyncMock (return_value = all_entities )
559
+
542
560
# WHEN deleting permissions on large hierarchy
543
561
await parent_folder .delete_permissions_async (
544
562
recursive = True , include_container_content = True
@@ -1097,30 +1115,6 @@ async def mock_get_current_acl(client):
1097
1115
# AND result should contain ACLs for the expected entities
1098
1116
assert len (result .all_entity_acls ) > 0
1099
1117
1100
- async def test_list_acl_error_handling (self ):
1101
- """Test error handling during ACL listing."""
1102
- # GIVEN a folder with children where one child fails
1103
- folder = Folder (id = "syn123" )
1104
- folder .sync_from_synapse_async = AsyncMock ()
1105
-
1106
- child_file = File (id = "syn456" )
1107
- child_file ._get_current_entity_acl = AsyncMock ()
1108
- child_file ._get_current_entity_acl .side_effect = Exception ("Network error" )
1109
-
1110
- folder .files = [child_file ]
1111
- folder .folders = []
1112
-
1113
- folder ._collect_entities = AsyncMock ()
1114
- folder ._collect_entities .return_value = [child_file ]
1115
-
1116
- # AND mock folder ACL
1117
- self .mock_get_acl .return_value = {"id" : "syn123" , "resourceAccess" : []}
1118
- self .mock_get_user_headers .return_value = []
1119
-
1120
- # WHEN listing ACL
1121
- with pytest .raises (Exception , match = "Network error" ):
1122
- await folder .list_acl_async (include_container_content = True )
1123
-
1124
1118
async def test_list_acl_no_user_headers (self ):
1125
1119
"""Test ACL listing when user headers can't be retrieved."""
1126
1120
# GIVEN a file with ACL
0 commit comments