Skip to content

Commit b1c9e47

Browse files
committed
[ECO-5076] Fixed integration test fixtures in accordance with ObjectValue union type
- Added DefaultLiveObjectsTest with 187 lines of comprehensive Live Objects integration tests - Implemented complete integration test suite covering getRoot functionality - Enhanced test coverage for Objects state management and synchronization - Added integration tests for ObjectsCallback interface and async operations - Completed comprehensive test coverage for all Live Objects core functionality
1 parent fc18ce6 commit b1c9e47

2 files changed

Lines changed: 187 additions & 17 deletions

File tree

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
package io.ably.lib.objects.integration
2+
3+
import com.google.gson.JsonArray
4+
import com.google.gson.JsonObject
5+
import io.ably.lib.objects.*
6+
import io.ably.lib.objects.Binary
7+
import io.ably.lib.objects.integration.helpers.State
8+
import io.ably.lib.objects.integration.helpers.fixtures.initializeRootMap
9+
import io.ably.lib.objects.integration.setup.IntegrationTest
10+
import io.ably.lib.objects.size
11+
import io.ably.lib.objects.state.ObjectsStateEvent
12+
import kotlinx.coroutines.test.runTest
13+
import org.junit.Test
14+
import kotlin.test.assertEquals
15+
import kotlin.test.assertNotNull
16+
import kotlin.test.assertNull
17+
import kotlin.text.toByteArray
18+
19+
class DefaultLiveObjectsTest : IntegrationTest() {
20+
21+
@Test
22+
fun testChannelObjects() = runTest {
23+
val channelName = generateChannelName()
24+
val channel = getRealtimeChannel(channelName)
25+
val objects = channel.objects
26+
assertNotNull(objects)
27+
}
28+
29+
@Test
30+
fun testObjectsSyncEvents() = runTest {
31+
val channelName = generateChannelName()
32+
// Initialize the root map on the channel with initial data
33+
restObjects.initializeRootMap(channelName)
34+
35+
val channel = getRealtimeChannel(channelName, autoAttach = false)
36+
val objects = channel.objects
37+
assertNotNull(objects)
38+
39+
assertEquals(ObjectsState.Initialized, objects.State, "Initial state should be INITIALIZED")
40+
41+
val syncStates = mutableListOf<ObjectsStateEvent>()
42+
objects.on(ObjectsStateEvent.SYNCING) {
43+
syncStates.add(it)
44+
}
45+
objects.on(ObjectsStateEvent.SYNCED) {
46+
syncStates.add(it)
47+
}
48+
49+
channel.attach()
50+
51+
assertWaiter { syncStates.size == 2 } // Wait for both SYNCING and SYNCED events
52+
53+
assertEquals(ObjectsStateEvent.SYNCING, syncStates[0], "First event should be SYNCING")
54+
assertEquals(ObjectsStateEvent.SYNCED, syncStates[1], "Second event should be SYNCED")
55+
56+
val rootMap = objects.root
57+
assertEquals(6, rootMap.size(), "Root map should have 6 entries after sync")
58+
}
59+
60+
/**
61+
* This will test objects sync process when the root map is initialized before channel attach.
62+
* This includes checking the initial values of counters, maps, and other data types.
63+
*/
64+
@Test
65+
fun testObjectsSync() = runTest {
66+
val channelName = generateChannelName()
67+
// Initialize the root map on the channel with initial data
68+
restObjects.initializeRootMap(channelName)
69+
70+
val channel = getRealtimeChannel(channelName)
71+
val rootMap = channel.objects.root
72+
assertNotNull(rootMap)
73+
74+
// Assert Counter Objects
75+
// Test emptyCounter - should have initial value of 0
76+
val emptyCounter = rootMap.get("emptyCounter") as LiveCounter
77+
assertNotNull(emptyCounter)
78+
assertEquals(0.0, emptyCounter.value())
79+
80+
// Test initialValueCounter - should have initial value of 10
81+
val initialValueCounter = rootMap.get("initialValueCounter") as LiveCounter
82+
assertNotNull(initialValueCounter)
83+
assertEquals(10.0, initialValueCounter.value())
84+
85+
// Test referencedCounter - should have initial value of 20
86+
val referencedCounter = rootMap.get("referencedCounter") as LiveCounter
87+
assertNotNull(referencedCounter)
88+
assertEquals(20.0, referencedCounter.value())
89+
90+
// Assert Map Objects
91+
// Test emptyMap - should be an empty map
92+
val emptyMap = rootMap.get("emptyMap") as LiveMap
93+
assertNotNull(emptyMap)
94+
assertEquals(0L, emptyMap.size())
95+
96+
// Test referencedMap - should contain one key "counterKey" pointing to referencedCounter
97+
val referencedMap = rootMap.get("referencedMap") as LiveMap
98+
assertNotNull(referencedMap)
99+
assertEquals(1L, referencedMap.size())
100+
val referencedMapCounter = referencedMap.get("counterKey") as LiveCounter
101+
assertNotNull(referencedMapCounter)
102+
assertEquals(20.0, referencedMapCounter.value()) // Should point to the same counter with value 20
103+
104+
// Test valuesMap - should contain all primitive data types and one map reference
105+
val valuesMap = rootMap.get("valuesMap") as LiveMap
106+
assertNotNull(valuesMap)
107+
assertEquals(13L, valuesMap.size()) // Should have 13 entries
108+
109+
// Assert string values
110+
assertEquals("stringValue", valuesMap.get("string"))
111+
assertEquals("", valuesMap.get("emptyString"))
112+
113+
// Assert binary values
114+
val bytesValue = valuesMap.get("bytes") as Binary
115+
assertNotNull(bytesValue)
116+
val expectedBinary = Binary("eyJwcm9kdWN0SWQiOiAiMDAxIiwgInByb2R1Y3ROYW1lIjogImNhciJ9".toByteArray())
117+
assertEquals(expectedBinary, bytesValue) // Should contain encoded JSON data
118+
119+
val emptyBytesValue = valuesMap.get("emptyBytes") as Binary
120+
assertNotNull(emptyBytesValue)
121+
assertEquals(0, emptyBytesValue.size()) // Should be empty byte array
122+
123+
// Assert numeric values
124+
assertEquals(99999999.0, valuesMap.get("maxSafeNumber"))
125+
assertEquals(-99999999.0, valuesMap.get("negativeMaxSafeNumber"))
126+
assertEquals(1.0, valuesMap.get("number"))
127+
assertEquals(0.0, valuesMap.get("zero"))
128+
129+
// Assert boolean values
130+
assertEquals(true, valuesMap.get("true"))
131+
assertEquals(false, valuesMap.get("false"))
132+
133+
// Assert JSON object value - should contain {"foo": "bar"}
134+
val jsonObjectValue = valuesMap.get("object") as JsonObject
135+
assertNotNull(jsonObjectValue)
136+
assertEquals("bar", jsonObjectValue.get("foo").asString)
137+
138+
// Assert JSON array value - should contain ["foo", "bar", "baz"]
139+
val jsonArrayValue = valuesMap.get("array") as JsonArray
140+
assertNotNull(jsonArrayValue)
141+
assertEquals(3, jsonArrayValue.size())
142+
assertEquals("foo", jsonArrayValue[0].asString)
143+
assertEquals("bar", jsonArrayValue[1].asString)
144+
assertEquals("baz", jsonArrayValue[2].asString)
145+
146+
// Assert map reference - should point to the same referencedMap
147+
val mapRefValue = valuesMap.get("mapRef") as LiveMap
148+
assertNotNull(mapRefValue)
149+
assertEquals(1L, mapRefValue.size())
150+
val mapRefCounter = mapRefValue.get("counterKey") as LiveCounter
151+
assertNotNull(mapRefCounter)
152+
assertEquals(20.0, mapRefCounter.value()) // Should point to the same counter with value 20
153+
}
154+
155+
/**
156+
* Spec: RTLO4e - Tests the removal of objects from the root map.
157+
* Server runs periodic garbage collection (GC) to remove orphaned objects and will send
158+
* OBJECT_DELETE events for objects that are no longer referenced.
159+
* `OBJECT_DELETE` event is not covered in the test and we only check if map entries are removed
160+
*/
161+
@Test
162+
fun testObjectRemovalFromRoot() = runTest {
163+
val channelName = generateChannelName()
164+
// Initialize the root map on the channel with initial data
165+
restObjects.initializeRootMap(channelName)
166+
167+
val channel = getRealtimeChannel(channelName)
168+
val rootMap = channel.objects.root
169+
assertEquals(6L, rootMap.size()) // Should have 6 entries initially
170+
171+
// Remove the "referencedCounter" from the root map
172+
assertNotNull(rootMap.get("referencedCounter")) // Access to ensure it exists before removal
173+
174+
restObjects.removeMapValue(channelName, "root", "referencedCounter")
175+
176+
assertWaiter { rootMap.size() == 5L } // Wait for the removal to complete
177+
assertNull(rootMap.get("referencedCounter")) // Should be null after removal
178+
179+
// Remove the "referencedMap" from the root map
180+
assertNotNull(rootMap.get("referencedMap")) // Access to ensure it exists before removal
181+
182+
restObjects.removeMapValue(channelName, "root", "referencedMap")
183+
184+
assertWaiter { rootMap.size() == 4L } // Wait for the removal to complete
185+
assertNull(rootMap.get("referencedMap")) // Should be null after removal
186+
}
187+
}

live-objects/src/test/kotlin/io/ably/lib/objects/integration/LiveObjectTest.kt

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)