Skip to content

Commit 3f8d14b

Browse files
committed
[AIT-53] test: add filtering validation for createOp entries in applyState
- Verified that `applyState` filters out `createOp` entries with null or older-than-clear serials as per RTLM7h. - Added unit test to ensure only entries with newer serials than `clearTimeserial` persist in the LiveMap.
1 parent 10c6157 commit 3f8d14b

1 file changed

Lines changed: 76 additions & 0 deletions

File tree

liveobjects/src/test/kotlin/io/ably/lib/objects/unit/type/livemap/LiveMapManagerTest.kt

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)