Skip to content

Commit bd30ecf

Browse files
committed
Handler PollVoteCastedFeedEvent for PollVoteList
1 parent 38110f7 commit bd30ecf

File tree

4 files changed

+95
-22
lines changed

4 files changed

+95
-22
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ import io.getstream.feeds.android.client.api.state.query.PollVotesFilterField
2424
import io.getstream.feeds.android.client.api.state.query.PollVotesQuery
2525
import io.getstream.feeds.android.client.api.state.query.PollVotesSort
2626
import io.getstream.feeds.android.client.internal.utils.mergeSorted
27+
import io.getstream.feeds.android.client.internal.utils.upsertSorted
2728
import kotlinx.coroutines.flow.MutableStateFlow
2829
import kotlinx.coroutines.flow.StateFlow
2930
import kotlinx.coroutines.flow.asStateFlow
31+
import kotlinx.coroutines.flow.update
3032

3133
/**
3234
* An observable state object that manages the current state of a poll vote list.
@@ -63,6 +65,10 @@ internal class PollVoteListStateImpl(override val query: PollVotesQuery) :
6365
_votes.value = _votes.value.mergeSorted(result.models, PollVoteData::id, votesSorting)
6466
}
6567

68+
override fun pollVoteAdded(vote: PollVoteData) {
69+
_votes.update { current -> current.upsertSorted(vote, PollVoteData::id, votesSorting) }
70+
}
71+
6672
override fun pollVoteRemoved(voteId: String) {
6773
_votes.value = _votes.value.filter { it.id != voteId }
6874
}
@@ -102,6 +108,9 @@ internal interface PollVoteListStateUpdates {
102108
queryConfig: QueryConfiguration<PollVotesFilterField, PollVotesSort>,
103109
)
104110

111+
/** Handles the addition of a new poll vote to the list. */
112+
fun pollVoteAdded(vote: PollVoteData)
113+
105114
/** Handles the removal of a poll vote from the list. */
106115
fun pollVoteRemoved(voteId: String)
107116

stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandler.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package io.getstream.feeds.android.client.internal.state.event.handler
1818
import io.getstream.feeds.android.client.api.model.toModel
1919
import io.getstream.feeds.android.client.internal.state.PollVoteListStateUpdates
2020
import io.getstream.feeds.android.client.internal.subscribe.FeedsEventListener
21+
import io.getstream.feeds.android.network.models.PollVoteCastedFeedEvent
2122
import io.getstream.feeds.android.network.models.PollVoteChangedFeedEvent
2223
import io.getstream.feeds.android.network.models.PollVoteRemovedFeedEvent
2324
import io.getstream.feeds.android.network.models.WSEvent
@@ -35,10 +36,16 @@ internal class PollVoteListEventHandler(
3536

3637
override fun onEvent(event: WSEvent) {
3738
when (event) {
39+
is PollVoteCastedFeedEvent -> {
40+
if (event.poll.id != pollId) return
41+
state.pollVoteAdded(event.pollVote.toModel())
42+
}
43+
3844
is PollVoteChangedFeedEvent -> {
3945
if (event.poll.id != pollId) return
4046
state.pollVoteUpdated(event.pollVote.toModel())
4147
}
48+
4249
is PollVoteRemovedFeedEvent -> {
4350
if (event.poll.id != pollId) return
4451
state.pollVoteRemoved(event.pollVote.id)

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

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,12 @@
1515
*/
1616
package io.getstream.feeds.android.client.internal.state
1717

18-
import io.getstream.feeds.android.client.api.model.PaginationData
19-
import io.getstream.feeds.android.client.api.model.PaginationResult
2018
import io.getstream.feeds.android.client.api.model.PollVoteData
2119
import io.getstream.feeds.android.client.api.model.QueryConfiguration
2220
import io.getstream.feeds.android.client.api.state.query.PollVotesFilterField
2321
import io.getstream.feeds.android.client.api.state.query.PollVotesQuery
2422
import io.getstream.feeds.android.client.api.state.query.PollVotesSort
23+
import io.getstream.feeds.android.client.internal.test.TestData.defaultPaginationResult
2524
import io.getstream.feeds.android.client.internal.test.TestData.pollVoteData
2625
import kotlinx.coroutines.test.runTest
2726
import org.junit.Assert.assertEquals
@@ -41,11 +40,7 @@ internal class PollVoteListStateImplTest {
4140
@Test
4241
fun `on queryMorePollVotes, then update votes and pagination`() = runTest {
4342
val votes = listOf(pollVoteData(), pollVoteData("vote-2", "poll-1", "option-2", "user-2"))
44-
val paginationResult =
45-
PaginationResult(
46-
models = votes,
47-
pagination = PaginationData(next = "next-cursor", previous = null),
48-
)
43+
val paginationResult = defaultPaginationResult(votes)
4944
val queryConfig =
5045
QueryConfiguration<PollVotesFilterField, PollVotesSort>(
5146
filter = null,
@@ -63,11 +58,7 @@ internal class PollVoteListStateImplTest {
6358
fun `on pollVoteUpdated, then update specific vote`() = runTest {
6459
val initialVotes =
6560
listOf(pollVoteData(), pollVoteData("vote-2", "poll-1", "option-2", "user-2"))
66-
val paginationResult =
67-
PaginationResult(
68-
models = initialVotes,
69-
pagination = PaginationData(next = "next-cursor", previous = null),
70-
)
61+
val paginationResult = defaultPaginationResult(initialVotes)
7162
val queryConfig =
7263
QueryConfiguration<PollVotesFilterField, PollVotesSort>(
7364
filter = null,
@@ -87,11 +78,7 @@ internal class PollVoteListStateImplTest {
8778
fun `on pollVoteRemoved, then remove specific vote`() = runTest {
8879
val initialVotes =
8980
listOf(pollVoteData(), pollVoteData("vote-2", "poll-1", "option-2", "user-2"))
90-
val paginationResult =
91-
PaginationResult(
92-
models = initialVotes,
93-
pagination = PaginationData(next = "next-cursor", previous = null),
94-
)
81+
val paginationResult = defaultPaginationResult(initialVotes)
9582
val queryConfig =
9683
QueryConfiguration<PollVotesFilterField, PollVotesSort>(
9784
filter = null,
@@ -109,11 +96,7 @@ internal class PollVoteListStateImplTest {
10996
fun `on pollVoteUpdated with non-existent vote, then keep unchanged`() = runTest {
11097
val initialVotes =
11198
listOf(pollVoteData(), pollVoteData("vote-2", "poll-1", "option-2", "user-2"))
112-
val paginationResult =
113-
PaginationResult(
114-
models = initialVotes,
115-
pagination = PaginationData(next = "next-cursor", previous = null),
116-
)
99+
val paginationResult = defaultPaginationResult(initialVotes)
117100
val queryConfig =
118101
QueryConfiguration<PollVotesFilterField, PollVotesSort>(
119102
filter = null,
@@ -126,4 +109,41 @@ internal class PollVoteListStateImplTest {
126109

127110
assertEquals(initialVotes, pollVoteListState.votes.value)
128111
}
112+
113+
@Test
114+
fun `on pollVoteAdded with new vote, then add vote to list in sorted order`() = runTest {
115+
val initial =
116+
listOf(pollVoteData("vote-1"), pollVoteData("vote-3", "poll-1", "option-3", "user-3"))
117+
val pagination = defaultPaginationResult(initial)
118+
val queryConfig =
119+
QueryConfiguration<PollVotesFilterField, PollVotesSort>(
120+
filter = null,
121+
sort = PollVotesSort.Default,
122+
)
123+
pollVoteListState.onQueryMorePollVotes(pagination, queryConfig)
124+
125+
val newVote = pollVoteData("vote-2", "poll-1", "option-2", "user-2")
126+
pollVoteListState.pollVoteAdded(newVote)
127+
128+
val expectedVotes = listOf(initial[0], newVote, initial[1])
129+
assertEquals(expectedVotes, pollVoteListState.votes.value)
130+
}
131+
132+
@Test
133+
fun `on pollVoteAdded with existing vote, then update existing vote`() = runTest {
134+
val initial =
135+
pollVoteData("vote-1", "poll-1", "option-1", "user-1", answerText = "Original")
136+
val pagination = defaultPaginationResult(listOf(initial))
137+
val queryConfig =
138+
QueryConfiguration<PollVotesFilterField, PollVotesSort>(
139+
filter = null,
140+
sort = PollVotesSort.Default,
141+
)
142+
pollVoteListState.onQueryMorePollVotes(pagination, queryConfig)
143+
144+
val updated = pollVoteData("vote-1", "poll-1", "option-1", "user-1", answerText = "Updated")
145+
pollVoteListState.pollVoteAdded(updated)
146+
147+
assertEquals(listOf(updated), pollVoteListState.votes.value)
148+
}
129149
}

stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandlerTest.kt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import io.getstream.feeds.android.client.api.model.toModel
1919
import io.getstream.feeds.android.client.internal.state.PollVoteListStateUpdates
2020
import io.getstream.feeds.android.client.internal.test.TestData.pollResponseData
2121
import io.getstream.feeds.android.client.internal.test.TestData.pollVoteResponseData
22+
import io.getstream.feeds.android.network.models.PollVoteCastedFeedEvent
2223
import io.getstream.feeds.android.network.models.PollVoteChangedFeedEvent
2324
import io.getstream.feeds.android.network.models.PollVoteRemovedFeedEvent
2425
import io.getstream.feeds.android.network.models.WSEvent
@@ -106,6 +107,42 @@ internal class PollVoteListEventHandlerTest {
106107
verify(exactly = 0) { state.pollVoteRemoved(any()) }
107108
}
108109

110+
@Test
111+
fun `on PollVoteCastedFeedEvent for matching poll, then call pollVoteAdded`() {
112+
val poll = pollResponseData().copy(id = pollId)
113+
val pollVote = pollVoteResponseData()
114+
val event =
115+
PollVoteCastedFeedEvent(
116+
createdAt = Date(),
117+
fid = "user:feed-1",
118+
poll = poll,
119+
pollVote = pollVote,
120+
type = "feeds.poll.vote_casted",
121+
)
122+
123+
handler.onEvent(event)
124+
125+
verify { state.pollVoteAdded(pollVote.toModel()) }
126+
}
127+
128+
@Test
129+
fun `on PollVoteCastedFeedEvent for different poll, then do not call pollVoteAdded`() {
130+
val poll = pollResponseData().copy(id = "different-poll")
131+
val pollVote = pollVoteResponseData()
132+
val event =
133+
PollVoteCastedFeedEvent(
134+
createdAt = Date(),
135+
fid = "user:feed-1",
136+
poll = poll,
137+
pollVote = pollVote,
138+
type = "feeds.poll.vote_casted",
139+
)
140+
141+
handler.onEvent(event)
142+
143+
verify(exactly = 0) { state.pollVoteAdded(any()) }
144+
}
145+
109146
@Test
110147
fun `on unknown event, then do nothing`() {
111148
val unknownEvent =

0 commit comments

Comments
 (0)