Skip to content

Commit 26e47a0

Browse files
committed
Fix MemberListState not upserting in order
1 parent 465f0ac commit 26e47a0

File tree

2 files changed

+48
-38
lines changed

2 files changed

+48
-38
lines changed

stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/MemberListStateImpl.kt

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import io.getstream.feeds.android.client.api.state.query.MembersQuery
2626
import io.getstream.feeds.android.client.api.state.query.MembersQueryConfig
2727
import io.getstream.feeds.android.client.api.state.query.MembersSort
2828
import io.getstream.feeds.android.client.internal.utils.mergeSorted
29-
import io.getstream.feeds.android.client.internal.utils.upsert
29+
import io.getstream.feeds.android.client.internal.utils.upsertSorted
3030
import kotlinx.coroutines.flow.MutableStateFlow
3131
import kotlinx.coroutines.flow.StateFlow
3232
import kotlinx.coroutines.flow.asStateFlow
@@ -70,7 +70,9 @@ internal class MemberListStateImpl(override val query: MembersQuery) : MemberLis
7070
}
7171

7272
override fun onMemberAdded(member: FeedMemberData) {
73-
_members.update { current -> current.upsert(member, FeedMemberData::id) }
73+
_members.update { current ->
74+
current.upsertSorted(member, FeedMemberData::id, membersSorting)
75+
}
7476
}
7577

7678
override fun onMemberRemoved(memberId: String) {
@@ -79,13 +81,7 @@ internal class MemberListStateImpl(override val query: MembersQuery) : MemberLis
7981

8082
override fun onMemberUpdated(member: FeedMemberData) {
8183
_members.update { current ->
82-
current.map {
83-
if (it.id == member.id) {
84-
member
85-
} else {
86-
it
87-
}
88-
}
84+
current.upsertSorted(member, FeedMemberData::id, membersSorting)
8985
}
9086
}
9187

stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/MemberListStateImplTest.kt

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ package io.getstream.feeds.android.client.internal.state
1818
import io.getstream.feeds.android.client.api.model.FeedId
1919
import io.getstream.feeds.android.client.api.model.FeedMemberData
2020
import io.getstream.feeds.android.client.api.model.ModelUpdates
21-
import io.getstream.feeds.android.client.api.model.PaginationData
22-
import io.getstream.feeds.android.client.api.model.PaginationResult
2321
import io.getstream.feeds.android.client.api.state.query.MembersQuery
2422
import io.getstream.feeds.android.client.api.state.query.MembersQueryConfig
2523
import io.getstream.feeds.android.client.api.state.query.MembersSort
@@ -54,23 +52,27 @@ internal class MemberListStateImplTest {
5452
}
5553

5654
@Test
57-
fun `on memberUpdated, then update specific member`() = runTest {
58-
val initialMembers = listOf(feedMemberData(), feedMemberData("user-2"))
59-
val paginationResult = defaultPaginationResult(initialMembers)
60-
memberListState.onQueryMoreMembers(paginationResult, queryConfig)
55+
fun `on memberUpdated, then update and reposition member`() = runTest {
56+
// Initial members already sorted by createdAt desc
57+
val initialMembers =
58+
listOf(
59+
feedMemberData("user-2", createdAt = Date(2000)),
60+
feedMemberData("user-1", createdAt = Date(1000)),
61+
)
62+
setupInitialState(initialMembers)
6163

62-
val updatedMember = feedMemberData("user-1", role = "admin")
64+
val updatedMember = feedMemberData("user-1", role = "admin", createdAt = Date(3000))
6365
memberListState.onMemberUpdated(updatedMember)
6466

65-
val expectedMembers = listOf(updatedMember, initialMembers[1])
67+
// Member should be repositioned according to new sort criteria
68+
val expectedMembers = listOf(updatedMember, initialMembers[0])
6669
assertEquals(expectedMembers, memberListState.members.value)
6770
}
6871

6972
@Test
7073
fun `on memberRemoved, then remove specific member`() = runTest {
7174
val initialMembers = listOf(feedMemberData(), feedMemberData("user-2"))
72-
val paginationResult = defaultPaginationResult(initialMembers)
73-
memberListState.onQueryMoreMembers(paginationResult, queryConfig)
75+
setupInitialState(initialMembers)
7476

7577
memberListState.onMemberRemoved(initialMembers[0].id)
7678

@@ -79,15 +81,14 @@ internal class MemberListStateImplTest {
7981
}
8082

8183
@Test
82-
fun `on membersUpdated, then apply add update and remove operations`() = runTest {
84+
fun `on membersUpdated, then apply add, update, and remove operations`() = runTest {
8385
val initialMembers =
8486
listOf(
8587
feedMemberData("user-3", createdAt = Date(3000)),
8688
feedMemberData("user-2", createdAt = Date(2000)),
8789
feedMemberData("user-1", createdAt = Date(1000)),
8890
)
89-
val paginationResult = defaultPaginationResult(initialMembers)
90-
memberListState.onQueryMoreMembers(paginationResult, queryConfig)
91+
setupInitialState(initialMembers)
9192

9293
val updatedMember = feedMemberData("user-1", role = "admin", createdAt = Date(5000))
9394
val newMember = feedMemberData("user-4", createdAt = Date(4000))
@@ -105,42 +106,55 @@ internal class MemberListStateImplTest {
105106
}
106107

107108
@Test
108-
fun `on memberAdded, then add member`() = runTest {
109-
val initialMembers = listOf(feedMemberData(), feedMemberData("user-2"))
110-
val paginationResult =
111-
PaginationResult(models = initialMembers, pagination = PaginationData())
112-
memberListState.onQueryMoreMembers(paginationResult, queryConfig)
109+
fun `on memberAdded, then add member in sorted position`() = runTest {
110+
// Initial members already sorted by createdAt desc
111+
val initialMembers =
112+
listOf(
113+
feedMemberData("user-3", createdAt = Date(3000)),
114+
feedMemberData("user-1", createdAt = Date(1000)),
115+
)
116+
setupInitialState(initialMembers)
113117

114-
val newMember = feedMemberData("user-3")
118+
val newMember = feedMemberData("user-2", createdAt = Date(2000))
115119
memberListState.onMemberAdded(newMember)
116120

117-
assertEquals(initialMembers + newMember, memberListState.members.value)
121+
// Member should be inserted in correct sorted position
122+
val expectedMembers = listOf(initialMembers[0], newMember, initialMembers[1])
123+
assertEquals(expectedMembers, memberListState.members.value)
118124
}
119125

120126
@Test
121-
fun `on memberAdded with existing id, then update member`() = runTest {
122-
val initialMembers = listOf(feedMemberData(), feedMemberData("user-2"))
123-
val paginationResult = defaultPaginationResult(initialMembers)
124-
memberListState.onQueryMoreMembers(paginationResult, queryConfig)
127+
fun `on memberAdded with existing id, then update and reposition member`() = runTest {
128+
// Initial members already sorted by createdAt desc
129+
val initialMembers =
130+
listOf(
131+
feedMemberData("user-2", createdAt = Date(2000)),
132+
feedMemberData("user-1", createdAt = Date(1000)),
133+
)
134+
setupInitialState(initialMembers)
125135

126-
val updatedMember = feedMemberData("user-1", role = "admin")
136+
// Add existing user-1 with newer createdAt that should move it to the front
137+
val updatedMember = feedMemberData("user-1", role = "admin", createdAt = Date(3000))
127138
memberListState.onMemberAdded(updatedMember)
128139

129-
val expectedMembers = listOf(updatedMember, initialMembers[1])
140+
// Member should be updated and repositioned according to new sort criteria (3000, 2000)
141+
val expectedMembers = listOf(updatedMember, initialMembers[0])
130142
assertEquals(expectedMembers, memberListState.members.value)
131143
}
132144

133145
@Test
134146
fun `on clear, then remove all members`() = runTest {
135-
val initialMembers = listOf(feedMemberData(), feedMemberData("user-2"))
136-
val paginationResult = defaultPaginationResult(initialMembers)
137-
memberListState.onQueryMoreMembers(paginationResult, queryConfig)
147+
setupInitialState(listOf(feedMemberData(), feedMemberData("user-2")))
138148

139149
memberListState.clear()
140150

141151
assertEquals(emptyList<FeedMemberData>(), memberListState.members.value)
142152
}
143153

154+
private fun setupInitialState(members: List<FeedMemberData>) {
155+
memberListState.onQueryMoreMembers(defaultPaginationResult(members), queryConfig)
156+
}
157+
144158
companion object {
145159
private val queryConfig = MembersQueryConfig(filter = null, sort = MembersSort.Default)
146160
}

0 commit comments

Comments
 (0)