@@ -1256,6 +1256,116 @@ fn daemon_push_reconciles_google_calendar_draft_create_to_canonical_event_filena
12561256 ) ;
12571257}
12581258
1259+ #[ test]
1260+ fn daemon_push_reconciles_long_google_calendar_event_id_to_filesystem_safe_filename ( ) {
1261+ let fixture = PushFixture :: new ( ) ;
1262+ let state_root = fixture. root . join ( ".state" ) ;
1263+ let source_path = Path :: new ( "draft/design-review.md" ) ;
1264+ let content_root = virtual_fs_content_root ( & state_root, & fixture. mount_id ) ;
1265+ let cache_path =
1266+ virtual_fs_content_path ( & state_root, & fixture. mount_id , source_path) . expect ( "cache path" ) ;
1267+ fs:: create_dir_all ( cache_path. parent ( ) . expect ( "cache parent" ) ) . expect ( "cache parent" ) ;
1268+ fs:: write (
1269+ & cache_path,
1270+ "---\n title: Design review\n summary: Design review\n start:\n dateTime: \" 2026-07-20T10:00:00-07:00\" \n end:\n dateTime: \" 2026-07-20T10:30:00-07:00\" \n ---\n Agenda\n " ,
1271+ )
1272+ . expect ( "cache file" ) ;
1273+
1274+ let draft_folder_id = RemoteId :: new ( "google-calendar-folder:draft" ) ;
1275+ let events_folder_id = RemoteId :: new ( "google-calendar-folder:events" ) ;
1276+ let long_event_id = format ! ( "loc{}" , "a" . repeat( 1024 ) ) ;
1277+ let event_id_hash = locality_core:: shadow:: stable_hash ( & long_event_id) ;
1278+ let created_remote_id = RemoteId :: new ( format ! ( "google-calendar-event:primary:{long_event_id}" ) ) ;
1279+ let mut store = InMemoryStateStore :: new ( ) ;
1280+ store
1281+ . save_mount (
1282+ MountConfig :: new ( fixture. mount_id . clone ( ) , "google-calendar" , & fixture. root )
1283+ . projection ( ProjectionMode :: LinuxFuse ) ,
1284+ )
1285+ . expect ( "save mount" ) ;
1286+ store
1287+ . save_entity ( EntityRecord :: new (
1288+ fixture. mount_id . clone ( ) ,
1289+ draft_folder_id. clone ( ) ,
1290+ EntityKind :: Directory ,
1291+ "draft" ,
1292+ "draft" ,
1293+ ) )
1294+ . expect ( "save draft folder" ) ;
1295+ store
1296+ . save_entity ( EntityRecord :: new (
1297+ fixture. mount_id . clone ( ) ,
1298+ events_folder_id. clone ( ) ,
1299+ EntityKind :: Directory ,
1300+ "events" ,
1301+ "events" ,
1302+ ) )
1303+ . expect ( "save events folder" ) ;
1304+ store
1305+ . save_virtual_mutation ( virtual_mutation (
1306+ & fixture. mount_id ,
1307+ "local:calendar-draft" ,
1308+ VirtualMutationKind :: Create ,
1309+ None ,
1310+ Some ( draft_folder_id) ,
1311+ "draft/design-review.md" ,
1312+ Some ( cache_path) ,
1313+ ) )
1314+ . expect ( "save mutation" ) ;
1315+ let source = FakePushSource :: default ( )
1316+ . with_created_entity (
1317+ created_remote_id. clone ( ) ,
1318+ rendered_google_calendar_entity (
1319+ created_remote_id. as_str ( ) ,
1320+ "Design review" ,
1321+ "2026-07-20T10:00:00-07:00" ,
1322+ "Agenda" ,
1323+ ) ,
1324+ )
1325+ . with_apply_effects ( vec ! [ JournalApplyEffect :: CreatedEntity {
1326+ operation_id: PushOperationId ( "create-calendar-draft" . to_string( ) ) ,
1327+ operation_index: 0 ,
1328+ parent_id: events_folder_id,
1329+ entity_id: created_remote_id. clone( ) ,
1330+ } ] ) ;
1331+
1332+ let report = execute_push_job_with_content_root (
1333+ & mut store,
1334+ PushJob {
1335+ target_path : fixture. root . join ( source_path) ,
1336+ assume_yes : true ,
1337+ confirm_dangerous : false ,
1338+ } ,
1339+ & source,
1340+ Some ( & state_root) ,
1341+ )
1342+ . expect ( "push google calendar draft with long event id" ) ;
1343+
1344+ assert_eq ! ( report. action, PushJobAction :: Reconciled ) ;
1345+ let event = store
1346+ . get_entity ( & fixture. mount_id , & created_remote_id)
1347+ . expect ( "get created event" )
1348+ . expect ( "created event entity" ) ;
1349+ let filename = event
1350+ . path
1351+ . file_name ( )
1352+ . expect ( "event filename" )
1353+ . to_string_lossy ( ) ;
1354+ assert ! (
1355+ filename. len( ) <= 255 ,
1356+ "filename component must fit common filesystem limits: {}" ,
1357+ filename. len( )
1358+ ) ;
1359+ assert ! ( filename. starts_with( "20260720-100000-design-review-" ) ) ;
1360+ assert ! ( filename. ends_with( ".md" ) ) ;
1361+ assert ! (
1362+ filename. contains( & event_id_hash[ ..16 ] ) ,
1363+ "shortened event ids should keep a stable hash suffix"
1364+ ) ;
1365+ assert ! ( content_root. join( & event. path) . exists( ) ) ;
1366+ assert ! ( !content_root. join( source_path) . exists( ) ) ;
1367+ }
1368+
12591369#[ test]
12601370fn daemon_push_accepts_google_calendar_summary_only_draft_create ( ) {
12611371 let fixture = PushFixture :: new ( ) ;
0 commit comments