Skip to content

Commit 4f1fc2d

Browse files
committed
[ECO-5458] Enhanced test fixtures and unit tests for subscription support
- Updated CounterFixtures and MapFixtures with subscription test data - Enhanced IntegrationTest setup for subscription scenarios - Added comprehensive unit tests for LiveCounterManager and LiveMapManager
1 parent 1cd9657 commit 4f1fc2d

5 files changed

Lines changed: 98 additions & 47 deletions

File tree

live-objects/src/test/kotlin/io/ably/lib/objects/integration/helpers/fixtures/CounterFixtures.kt

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,7 @@ internal fun RestObjects.createUserMapWithCountersObject(channelName: String): S
4242
val loginStreakCounterObjectId = createCounter(channelName, 7.0)
4343

4444
// Create engagement metrics nested map with counters
45-
val engagementMetricsMapObjectId = createMap(
46-
channelName,
47-
data = mapOf(
48-
"totalShares" to DataFixtures.mapRef(createCounter(channelName, 34.0)),
49-
"totalBookmarks" to DataFixtures.mapRef(createCounter(channelName, 67.0)),
50-
"totalReactions" to DataFixtures.mapRef(createCounter(channelName, 189.0)),
51-
"dailyActiveStreak" to DataFixtures.mapRef(createCounter(channelName, 12.0))
52-
)
53-
)
45+
val engagementMetricsMapObjectId = createUserEngagementMatrixMap(channelName)
5446

5547
// Set up the main test map structure with references to all created counters
5648
setMapRef(channelName, testMapObjectId, "profileViews", profileViewsCounterObjectId)
@@ -63,3 +55,34 @@ internal fun RestObjects.createUserMapWithCountersObject(channelName: String): S
6355

6456
return testMapObjectId
6557
}
58+
59+
/**
60+
* Creates a user engagement matrix map object with counter references for testing.
61+
*
62+
* This method creates a simple engagement metrics map containing counter objects
63+
* that track various user engagement metrics. The map contains references to
64+
* counter objects representing different types of user interactions and activities.
65+
*
66+
* **Object Structure:**
67+
* ```
68+
* userEngagementMatrixMap (Map)
69+
* ├── "totalShares" → Counter(value=34)
70+
* ├── "totalBookmarks" → Counter(value=67)
71+
* ├── "totalReactions" → Counter(value=189)
72+
* └── "dailyActiveStreak" → Counter(value=12)
73+
* ```
74+
*
75+
* @param channelName The channel where the user engagement matrix map will be created
76+
* @return The object ID of the created user engagement matrix map
77+
*/
78+
internal fun RestObjects.createUserEngagementMatrixMap(channelName: String): String {
79+
return createMap(
80+
channelName,
81+
data = mapOf(
82+
"totalShares" to DataFixtures.mapRef(createCounter(channelName, 34.0)),
83+
"totalBookmarks" to DataFixtures.mapRef(createCounter(channelName, 67.0)),
84+
"totalReactions" to DataFixtures.mapRef(createCounter(channelName, 189.0)),
85+
"dailyActiveStreak" to DataFixtures.mapRef(createCounter(channelName, 12.0))
86+
)
87+
)
88+
}

live-objects/src/test/kotlin/io/ably/lib/objects/integration/helpers/fixtures/MapFixtures.kt

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,17 +134,9 @@ internal fun RestObjects.createUserMapObject(channelName: String): String {
134134
)
135135

136136
// Create a user profile map with mixed data types and references
137-
val userProfileMapObjectId = createMap(
138-
channelName,
139-
data = mapOf(
140-
"userId" to ObjectData(value = ObjectValue.String("user123")),
141-
"name" to ObjectData(value = ObjectValue.String("John Doe")),
142-
"email" to ObjectData(value = ObjectValue.String("john@example.com")),
143-
"isActive" to ObjectData(value = ObjectValue.Boolean(true)),
144-
"metrics" to DataFixtures.mapRef(metricsMapObjectId),
145-
"preferences" to DataFixtures.mapRef(preferencesMapObjectId)
146-
)
147-
)
137+
val userProfileMapObjectId = createUserProfileMapObject(channelName)
138+
setMapRef(channelName, userProfileMapObjectId, "metrics", metricsMapObjectId)
139+
setMapRef(channelName, userProfileMapObjectId, "preferences", preferencesMapObjectId)
148140

149141
// Set up the main test map structure with references to all created objects
150142
setMapRef(channelName, testMapObjectId, "userProfile", userProfileMapObjectId)
@@ -155,3 +147,38 @@ internal fun RestObjects.createUserMapObject(channelName: String): String {
155147

156148
return testMapObjectId
157149
}
150+
151+
/**
152+
* Creates a user profile map object with basic user information for testing.
153+
*
154+
* This method creates a simple user profile map containing essential user data fields
155+
* that are commonly used in user management systems. The map contains primitive data types
156+
* representing basic user information.
157+
*
158+
* **Object Structure:**
159+
* ```
160+
* userProfileMap (Map)
161+
* ├── "userId" → "user123"
162+
* ├── "name" → "John Doe"
163+
* ├── "email" → "john@example.com"
164+
* └── "isActive" → true
165+
* ```
166+
*
167+
* This structure provides a foundation for testing map operations on user profile data,
168+
* including field updates, additions, and removals. The map contains a mix of string,
169+
* boolean, and numeric data types to test various primitive value handling.
170+
*
171+
* @param channelName The channel where the user profile map will be created
172+
* @return The object ID of the created user profile map
173+
*/
174+
internal fun RestObjects.createUserProfileMapObject(channelName: String): String {
175+
return createMap(
176+
channelName,
177+
data = mapOf(
178+
"userId" to ObjectData(value = ObjectValue.String("user123")),
179+
"name" to ObjectData(value = ObjectValue.String("John Doe")),
180+
"email" to ObjectData(value = ObjectValue.String("john@example.com")),
181+
"isActive" to ObjectData(value = ObjectValue.Boolean(true)),
182+
)
183+
)
184+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ abstract class IntegrationTest {
2222

2323
@JvmField
2424
@Rule
25-
val timeout: Timeout = Timeout.seconds(10)
25+
val timeout: Timeout = Timeout.seconds(15)
2626

2727
private val realtimeClients = mutableMapOf<String, AblyRealtime>()
2828

live-objects/src/test/kotlin/io/ably/lib/objects/unit/type/livecounter/LiveCounterManagerTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class DefaultLiveCounterManagerTest {
2828

2929
assertFalse(liveCounter.createOperationIsMerged) // RTLC6b
3030
assertEquals(25.0, liveCounter.data.get()) // RTLC6c
31-
assertEquals(15.0, update["amount"]) // Difference between old and new data
31+
assertEquals(15.0, update.update.amount) // Difference between old and new data
3232
}
3333

3434

@@ -58,7 +58,7 @@ class DefaultLiveCounterManagerTest {
5858
val update = liveCounterManager.applyState(objectState)
5959

6060
assertEquals(25.0, liveCounter.data.get()) // 15 from state + 10 from create op
61-
assertEquals(20.0, update["amount"]) // Total change
61+
assertEquals(20.0, update.update.amount) // Total change
6262
}
6363

6464

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

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package io.ably.lib.objects.unit.type.livemap
33
import io.ably.lib.objects.*
44
import io.ably.lib.objects.type.livemap.LiveMapEntry
55
import io.ably.lib.objects.type.livemap.LiveMapManager
6+
import io.ably.lib.objects.type.map.LiveMapUpdate
67
import io.ably.lib.objects.unit.LiveMapManager
78
import io.ably.lib.objects.unit.getDefaultLiveMapWithMockedDeps
89
import io.ably.lib.types.AblyException
@@ -55,10 +56,10 @@ class LiveMapManagerTest {
5556

5657
// Assert on update field - should show changes from old to new state
5758
val expectedUpdate = mapOf(
58-
"key1" to "updated", // key1 was updated from "oldValue" to "newValue1"
59-
"key2" to "updated" // key2 was added
59+
"key1" to LiveMapUpdate.Change.UPDATED, // key1 was updated from "oldValue" to "newValue1"
60+
"key2" to LiveMapUpdate.Change.UPDATED // key2 was added
6061
)
61-
assertEquals(expectedUpdate, update)
62+
assertEquals(expectedUpdate, update.update)
6263
}
6364

6465
@Test
@@ -89,8 +90,8 @@ class LiveMapManagerTest {
8990
assertEquals(0, liveMap.data.size) // RTLM6c - should be empty map
9091

9192
// Assert on update field - should show that key1 was removed
92-
val expectedUpdate = mapOf("key1" to "removed")
93-
assertEquals(expectedUpdate, update)
93+
val expectedUpdate = mapOf("key1" to LiveMapUpdate.Change.REMOVED)
94+
assertEquals(expectedUpdate, update.update)
9495
}
9596

9697
@Test
@@ -118,8 +119,8 @@ class LiveMapManagerTest {
118119
assertEquals(0, liveMap.data.size) // RTLM6c - should be empty map when map is null
119120

120121
// Assert on update field - should show that key1 was removed
121-
val expectedUpdate = mapOf("key1" to "removed")
122-
assertEquals(expectedUpdate, update)
122+
val expectedUpdate = mapOf("key1" to LiveMapUpdate.Change.REMOVED)
123+
assertEquals(expectedUpdate, update.update)
123124
}
124125

125126
@Test
@@ -177,10 +178,10 @@ class LiveMapManagerTest {
177178

178179
// Assert on update field - should show changes from create operation
179180
val expectedUpdate = mapOf(
180-
"key1" to "updated", // key1 was updated from "existingValue" to "stateValue"
181-
"key2" to "updated" // key2 was added from create operation
181+
"key1" to LiveMapUpdate.Change.UPDATED, // key1 was updated from "existingValue" to "stateValue"
182+
"key2" to LiveMapUpdate.Change.UPDATED // key2 was added from create operation
182183
)
183-
assertEquals(expectedUpdate, update)
184+
assertEquals(expectedUpdate, update.update)
184185
}
185186

186187

@@ -637,7 +638,7 @@ class LiveMapManagerTest {
637638
val prevData1 = mapOf<String, LiveMapEntry>()
638639
val newData1 = mapOf<String, LiveMapEntry>()
639640
val result1 = livemapManager.calculateUpdateFromDataDiff(prevData1, newData1)
640-
assertEquals(emptyMap<String, String>(), result1, "Should return empty map for no changes")
641+
assertEquals(emptyMap<String, LiveMapUpdate.Change>(), result1.update, "Should return empty map for no changes")
641642

642643
// Test case 2: Entry added
643644
val prevData2 = mapOf<String, LiveMapEntry>()
@@ -649,7 +650,7 @@ class LiveMapManagerTest {
649650
)
650651
)
651652
val result2 = livemapManager.calculateUpdateFromDataDiff(prevData2, newData2)
652-
assertEquals(mapOf("key1" to "updated"), result2, "Should detect added entry")
653+
assertEquals(mapOf("key1" to LiveMapUpdate.Change.UPDATED), result2.update, "Should detect added entry")
653654

654655
// Test case 3: Entry removed
655656
val prevData3 = mapOf(
@@ -661,7 +662,7 @@ class LiveMapManagerTest {
661662
)
662663
val newData3 = mapOf<String, LiveMapEntry>()
663664
val result3 = livemapManager.calculateUpdateFromDataDiff(prevData3, newData3)
664-
assertEquals(mapOf("key1" to "removed"), result3, "Should detect removed entry")
665+
assertEquals(mapOf("key1" to LiveMapUpdate.Change.REMOVED), result3.update, "Should detect removed entry")
665666

666667
// Test case 4: Entry updated
667668
val prevData4 = mapOf(
@@ -679,7 +680,7 @@ class LiveMapManagerTest {
679680
)
680681
)
681682
val result4 = livemapManager.calculateUpdateFromDataDiff(prevData4, newData4)
682-
assertEquals(mapOf("key1" to "updated"), result4, "Should detect updated entry")
683+
assertEquals(mapOf("key1" to LiveMapUpdate.Change.UPDATED), result4.update, "Should detect updated entry")
683684

684685
// Test case 5: Entry tombstoned
685686
val prevData5 = mapOf(
@@ -697,7 +698,7 @@ class LiveMapManagerTest {
697698
)
698699
)
699700
val result5 = livemapManager.calculateUpdateFromDataDiff(prevData5, newData5)
700-
assertEquals(mapOf("key1" to "removed"), result5, "Should detect tombstoned entry")
701+
assertEquals(mapOf("key1" to LiveMapUpdate.Change.REMOVED), result5.update, "Should detect tombstoned entry")
701702

702703
// Test case 6: Entry untombstoned
703704
val prevData6 = mapOf(
@@ -715,7 +716,7 @@ class LiveMapManagerTest {
715716
)
716717
)
717718
val result6 = livemapManager.calculateUpdateFromDataDiff(prevData6, newData6)
718-
assertEquals(mapOf("key1" to "updated"), result6, "Should detect untombstoned entry")
719+
assertEquals(mapOf("key1" to LiveMapUpdate.Change.UPDATED), result6.update, "Should detect untombstoned entry")
719720

720721
// Test case 7: Both entries tombstoned (noop)
721722
val prevData7 = mapOf(
@@ -733,7 +734,7 @@ class LiveMapManagerTest {
733734
)
734735
)
735736
val result7 = livemapManager.calculateUpdateFromDataDiff(prevData7, newData7)
736-
assertEquals(emptyMap<String, String>(), result7, "Should not detect change for both tombstoned entries")
737+
assertEquals(emptyMap<String, LiveMapUpdate.Change>(), result7.update, "Should not detect change for both tombstoned entries")
737738

738739
// Test case 8: New tombstoned entry (noop)
739740
val prevData8 = mapOf<String, LiveMapEntry>()
@@ -745,7 +746,7 @@ class LiveMapManagerTest {
745746
)
746747
)
747748
val result8 = livemapManager.calculateUpdateFromDataDiff(prevData8, newData8)
748-
assertEquals(emptyMap<String, String>(), result8, "Should not detect change for new tombstoned entry")
749+
assertEquals(emptyMap<String, LiveMapUpdate.Change>(), result8.update, "Should not detect change for new tombstoned entry")
749750

750751
// Test case 9: Multiple changes
751752
val prevData9 = mapOf(
@@ -774,11 +775,11 @@ class LiveMapManagerTest {
774775
)
775776
val result9 = livemapManager.calculateUpdateFromDataDiff(prevData9, newData9)
776777
val expected9 = mapOf(
777-
"key1" to "updated",
778-
"key2" to "removed",
779-
"key3" to "updated"
778+
"key1" to LiveMapUpdate.Change.UPDATED,
779+
"key2" to LiveMapUpdate.Change.REMOVED,
780+
"key3" to LiveMapUpdate.Change.UPDATED
780781
)
781-
assertEquals(expected9, result9, "Should detect multiple changes correctly")
782+
assertEquals(expected9, result9.update, "Should detect multiple changes correctly")
782783

783784
// Test case 10: ObjectId references
784785
val prevData10 = mapOf(
@@ -796,7 +797,7 @@ class LiveMapManagerTest {
796797
)
797798
)
798799
val result10 = livemapManager.calculateUpdateFromDataDiff(prevData10, newData10)
799-
assertEquals(mapOf("key1" to "updated"), result10, "Should detect objectId change")
800+
assertEquals(mapOf("key1" to LiveMapUpdate.Change.UPDATED), result10.update, "Should detect objectId change")
800801

801802
// Test case 11: Same data, no change
802803
val prevData11 = mapOf(
@@ -814,6 +815,6 @@ class LiveMapManagerTest {
814815
)
815816
)
816817
val result11 = livemapManager.calculateUpdateFromDataDiff(prevData11, newData11)
817-
assertEquals(emptyMap<String, String>(), result11, "Should not detect change for same data")
818+
assertEquals(emptyMap<String, LiveMapUpdate.Change>(), result11.update, "Should not detect change for same data")
818819
}
819820
}

0 commit comments

Comments
 (0)