@@ -1285,6 +1285,82 @@ class LiveMapManagerTest {
12851285 assertEquals(" serial1" , liveMap.clearTimeserial)
12861286 }
12871287
1288+ @Test
1289+ fun `(RTLM6i) applyState resets clearTimeserial to null when objectState has no clearTimeserial` () {
1290+ val liveMap = getDefaultLiveMapWithMockedDeps()
1291+ val liveMapManager = liveMap.LiveMapManager
1292+
1293+ liveMap.clearTimeserial = " serial1"
1294+
1295+ val objectState = ObjectState (
1296+ objectId = " map:testMap@1" ,
1297+ map = ObjectsMap (
1298+ semantics = ObjectsMapSemantics .LWW ,
1299+ entries = emptyMap(),
1300+ clearTimeserial = null
1301+ ),
1302+ siteTimeserials = emptyMap(),
1303+ tombstone = false ,
1304+ )
1305+
1306+ liveMapManager.applyState(objectState, null )
1307+
1308+ assertNull(liveMap.clearTimeserial)
1309+ }
1310+
1311+ @Test
1312+ fun `(RTLM6i, RTLM6d, RTLM7h) applyState filters createOp entries older than or equal to clearTimeserial` () {
1313+ val liveMap = getDefaultLiveMapWithMockedDeps()
1314+ val liveMapManager = liveMap.LiveMapManager
1315+
1316+ // createOp has three entries:
1317+ // key-null-serial — no timeserial (treated as pre-clear by RTLM7h)
1318+ // key-old-serial — serial1, strictly older than the clear serial (serial2)
1319+ // key-new-serial — serial3, strictly newer than the clear serial (serial2)
1320+ val createOp = ObjectOperation (
1321+ action = ObjectOperationAction .MapCreate ,
1322+ objectId = " map:testMap@1" ,
1323+ mapCreate = MapCreate (
1324+ semantics = ObjectsMapSemantics .LWW ,
1325+ entries = mapOf (
1326+ " key-null-serial" to ObjectsMapEntry (
1327+ data = ObjectData (string = " nullSerialValue" ),
1328+ timeserial = null
1329+ ),
1330+ " key-old-serial" to ObjectsMapEntry (
1331+ data = ObjectData (string = " oldSerialValue" ),
1332+ timeserial = " serial1"
1333+ ),
1334+ " key-new-serial" to ObjectsMapEntry (
1335+ data = ObjectData (string = " newSerialValue" ),
1336+ timeserial = " serial3"
1337+ )
1338+ )
1339+ )
1340+ )
1341+
1342+ val objectState = ObjectState (
1343+ objectId = " map:testMap@1" ,
1344+ map = ObjectsMap (
1345+ semantics = ObjectsMapSemantics .LWW ,
1346+ entries = emptyMap(),
1347+ clearTimeserial = " serial2" // RTLM6i: set before createOp entries are merged
1348+ ),
1349+ createOp = createOp,
1350+ siteTimeserials = mapOf (" site1" to " serial1" ),
1351+ tombstone = false ,
1352+ )
1353+
1354+ liveMapManager.applyState(objectState, null )
1355+
1356+ // RTLM7h: entries with null or older-than-clear serials must be filtered out
1357+ assertNull(liveMap.data[" key-null-serial" ], " Entry with null serial should be filtered by RTLM7h" )
1358+ assertNull(liveMap.data[" key-old-serial" ], " Entry with serial1 <= clearTimeserial serial2 should be filtered by RTLM7h" )
1359+ // Entry whose serial is strictly newer than clearTimeserial must survive
1360+ assertNotNull(liveMap.data[" key-new-serial" ], " Entry with serial3 > clearTimeserial serial2 should be present" )
1361+ assertEquals(" newSerialValue" , liveMap.data[" key-new-serial" ]?.data?.string)
1362+ }
1363+
12881364 @Test
12891365 fun `(RTLM4) clearData resets clearTimeserial` () {
12901366 val liveMap = getDefaultLiveMapWithMockedDeps()
0 commit comments