@@ -1096,9 +1096,8 @@ async def test_sync_regular_file_race_condition_handling(
10961096 sync_service : SyncService , project_config : ProjectConfig
10971097):
10981098 """Test that sync_regular_file handles race condition with IntegrityError (lines 380-401)."""
1099- from unittest .mock import patch , AsyncMock
1099+ from unittest .mock import patch
11001100 from sqlalchemy .exc import IntegrityError
1101- from pathlib import Path
11021101 from datetime import datetime , timezone
11031102
11041103 # Create a test file
@@ -1114,11 +1113,9 @@ async def test_sync_regular_file_race_condition_handling(
11141113
11151114 # Mock the entity_repository.add to raise IntegrityError on first call
11161115 original_add = sync_service .entity_repository .add
1117- original_get_by_file_path = sync_service .entity_repository .get_by_file_path
1118- original_update = sync_service .entity_repository .update
1119-
1116+
11201117 call_count = 0
1121-
1118+
11221119 async def mock_add (* args , ** kwargs ):
11231120 nonlocal call_count
11241121 call_count += 1
@@ -1127,10 +1124,11 @@ async def mock_add(*args, **kwargs):
11271124 raise IntegrityError ("UNIQUE constraint failed: entity.file_path" , None , None )
11281125 else :
11291126 return await original_add (* args , ** kwargs )
1130-
1127+
11311128 # Mock get_by_file_path to return an existing entity (simulating the race condition result)
11321129 async def mock_get_by_file_path (file_path ):
11331130 from basic_memory .models import Entity
1131+
11341132 return Entity (
11351133 id = 1 ,
11361134 title = "Test Race Condition" ,
@@ -1142,14 +1140,15 @@ async def mock_get_by_file_path(file_path):
11421140 created_at = datetime .now (timezone .utc ),
11431141 updated_at = datetime .now (timezone .utc ),
11441142 )
1145-
1143+
11461144 # Mock update to return the updated entity
11471145 async def mock_update (entity_id , updates ):
11481146 from basic_memory .models import Entity
1147+
11491148 return Entity (
11501149 id = entity_id ,
11511150 title = "Test Race Condition" ,
1152- entity_type = "knowledge" ,
1151+ entity_type = "knowledge" ,
11531152 file_path = updates ["file_path" ],
11541153 permalink = "test-race-condition" ,
11551154 content_type = "text/markdown" ,
@@ -1158,18 +1157,25 @@ async def mock_update(entity_id, updates):
11581157 updated_at = datetime .now (timezone .utc ),
11591158 )
11601159
1161- with patch .object (sync_service .entity_repository , 'add' , side_effect = mock_add ), \
1162- patch .object (sync_service .entity_repository , 'get_by_file_path' , side_effect = mock_get_by_file_path ) as mock_get , \
1163- patch .object (sync_service .entity_repository , 'update' , side_effect = mock_update ) as mock_update_call :
1164-
1160+ with (
1161+ patch .object (sync_service .entity_repository , "add" , side_effect = mock_add ),
1162+ patch .object (
1163+ sync_service .entity_repository , "get_by_file_path" , side_effect = mock_get_by_file_path
1164+ ) as mock_get ,
1165+ patch .object (
1166+ sync_service .entity_repository , "update" , side_effect = mock_update
1167+ ) as mock_update_call ,
1168+ ):
11651169 # Call sync_regular_file
1166- entity , checksum = await sync_service .sync_regular_file (str (test_file .relative_to (project_config .home )), new = True )
1167-
1170+ entity , checksum = await sync_service .sync_regular_file (
1171+ str (test_file .relative_to (project_config .home )), new = True
1172+ )
1173+
11681174 # Verify it handled the race condition gracefully
11691175 assert entity is not None
11701176 assert entity .title == "Test Race Condition"
11711177 assert entity .file_path == str (test_file .relative_to (project_config .home ))
1172-
1178+
11731179 # Verify that get_by_file_path and update were called as fallback
11741180 assert mock_get .call_count >= 1 # May be called multiple times
11751181 mock_update_call .assert_called_once ()
@@ -1199,10 +1205,14 @@ async def mock_add(*args, **kwargs):
11991205 # Simulate a different constraint violation
12001206 raise IntegrityError ("UNIQUE constraint failed: entity.some_other_field" , None , None )
12011207
1202- with patch .object (sync_service .entity_repository , ' add' , side_effect = mock_add ):
1208+ with patch .object (sync_service .entity_repository , " add" , side_effect = mock_add ):
12031209 # Should re-raise the IntegrityError since it's not a file_path constraint
1204- with pytest .raises (IntegrityError , match = "UNIQUE constraint failed: entity.some_other_field" ):
1205- await sync_service .sync_regular_file (str (test_file .relative_to (project_config .home )), new = True )
1210+ with pytest .raises (
1211+ IntegrityError , match = "UNIQUE constraint failed: entity.some_other_field"
1212+ ):
1213+ await sync_service .sync_regular_file (
1214+ str (test_file .relative_to (project_config .home )), new = True
1215+ )
12061216
12071217
12081218@pytest .mark .asyncio
@@ -1227,17 +1237,22 @@ async def test_sync_regular_file_race_condition_entity_not_found(
12271237 # Mock the entity_repository.add to raise IntegrityError
12281238 async def mock_add (* args , ** kwargs ):
12291239 raise IntegrityError ("UNIQUE constraint failed: entity.file_path" , None , None )
1230-
1240+
12311241 # Mock get_by_file_path to return None (entity not found)
12321242 async def mock_get_by_file_path (file_path ):
12331243 return None
12341244
1235- with patch .object (sync_service .entity_repository , 'add' , side_effect = mock_add ), \
1236- patch .object (sync_service .entity_repository , 'get_by_file_path' , side_effect = mock_get_by_file_path ):
1237-
1245+ with (
1246+ patch .object (sync_service .entity_repository , "add" , side_effect = mock_add ),
1247+ patch .object (
1248+ sync_service .entity_repository , "get_by_file_path" , side_effect = mock_get_by_file_path
1249+ ),
1250+ ):
12381251 # Should raise ValueError when entity is not found after constraint violation
12391252 with pytest .raises (ValueError , match = "Entity not found after constraint violation" ):
1240- await sync_service .sync_regular_file (str (test_file .relative_to (project_config .home )), new = True )
1253+ await sync_service .sync_regular_file (
1254+ str (test_file .relative_to (project_config .home )), new = True
1255+ )
12411256
12421257
12431258@pytest .mark .asyncio
@@ -1263,10 +1278,11 @@ async def test_sync_regular_file_race_condition_update_failed(
12631278 # Mock the entity_repository.add to raise IntegrityError
12641279 async def mock_add (* args , ** kwargs ):
12651280 raise IntegrityError ("UNIQUE constraint failed: entity.file_path" , None , None )
1266-
1281+
12671282 # Mock get_by_file_path to return an existing entity
12681283 async def mock_get_by_file_path (file_path ):
12691284 from basic_memory .models import Entity
1285+
12701286 return Entity (
12711287 id = 1 ,
12721288 title = "Test Update Fail" ,
@@ -1278,15 +1294,20 @@ async def mock_get_by_file_path(file_path):
12781294 created_at = datetime .now (timezone .utc ),
12791295 updated_at = datetime .now (timezone .utc ),
12801296 )
1281-
1297+
12821298 # Mock update to return None (failure)
12831299 async def mock_update (entity_id , updates ):
12841300 return None
12851301
1286- with patch .object (sync_service .entity_repository , 'add' , side_effect = mock_add ), \
1287- patch .object (sync_service .entity_repository , 'get_by_file_path' , side_effect = mock_get_by_file_path ), \
1288- patch .object (sync_service .entity_repository , 'update' , side_effect = mock_update ):
1289-
1302+ with (
1303+ patch .object (sync_service .entity_repository , "add" , side_effect = mock_add ),
1304+ patch .object (
1305+ sync_service .entity_repository , "get_by_file_path" , side_effect = mock_get_by_file_path
1306+ ),
1307+ patch .object (sync_service .entity_repository , "update" , side_effect = mock_update ),
1308+ ):
12901309 # Should raise ValueError when update fails
12911310 with pytest .raises (ValueError , match = "Failed to update entity with ID" ):
1292- await sync_service .sync_regular_file (str (test_file .relative_to (project_config .home )), new = True )
1311+ await sync_service .sync_regular_file (
1312+ str (test_file .relative_to (project_config .home )), new = True
1313+ )
0 commit comments