Skip to content

Commit 4c0d8b6

Browse files
committed
Handle FeedDeletedEvent for FeedList
1 parent 0f97bc2 commit 4c0d8b6

File tree

5 files changed

+78
-32
lines changed

5 files changed

+78
-32
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import io.getstream.feeds.android.client.internal.utils.mergeSorted
2727
import kotlinx.coroutines.flow.MutableStateFlow
2828
import kotlinx.coroutines.flow.StateFlow
2929
import kotlinx.coroutines.flow.asStateFlow
30+
import kotlinx.coroutines.flow.update
3031

3132
/**
3233
* An observable state object that manages the current state of a feed list.
@@ -66,6 +67,10 @@ internal class FeedListStateImpl(override val query: FeedsQuery) : FeedListMutab
6667
}
6768
}
6869

70+
override fun onFeedRemoved(feedId: String) {
71+
_feeds.update { current -> current.filter { it.fid.rawValue != feedId } }
72+
}
73+
6974
override fun onQueryMoreFeeds(
7075
result: PaginationResult<FeedData>,
7176
queryConfig: QueryConfiguration<FeedsFilterField, FeedsSort>,
@@ -101,4 +106,7 @@ internal interface FeedListStateUpdates {
101106
result: PaginationResult<FeedData>,
102107
queryConfig: QueryConfiguration<FeedsFilterField, FeedsSort>,
103108
)
109+
110+
/** Handles the removal of a feed by its ID. */
111+
fun onFeedRemoved(feedId: String)
104112
}

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

Lines changed: 5 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.FeedListStateUpdates
2020
import io.getstream.feeds.android.client.internal.subscribe.FeedsEventListener
21+
import io.getstream.feeds.android.network.models.FeedDeletedEvent
2122
import io.getstream.feeds.android.network.models.FeedUpdatedEvent
2223
import io.getstream.feeds.android.network.models.WSEvent
2324

@@ -28,6 +29,10 @@ internal class FeedListEventHandler(private val state: FeedListStateUpdates) : F
2829
is FeedUpdatedEvent -> {
2930
state.onFeedUpdated(event.feed.toModel())
3031
}
32+
33+
is FeedDeletedEvent -> {
34+
state.onFeedRemoved(event.fid)
35+
}
3136
}
3237
}
3338
}

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

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@
1616
package io.getstream.feeds.android.client.internal.state
1717

1818
import io.getstream.feeds.android.client.api.model.FeedData
19-
import io.getstream.feeds.android.client.api.model.PaginationData
20-
import io.getstream.feeds.android.client.api.model.PaginationResult
2119
import io.getstream.feeds.android.client.api.model.QueryConfiguration
2220
import io.getstream.feeds.android.client.api.state.query.FeedsFilterField
2321
import io.getstream.feeds.android.client.api.state.query.FeedsQuery
2422
import io.getstream.feeds.android.client.api.state.query.FeedsSort
23+
import io.getstream.feeds.android.client.internal.test.TestData.defaultPaginationResult
2524
import io.getstream.feeds.android.client.internal.test.TestData.feedData
2625
import kotlinx.coroutines.test.runTest
2726
import org.junit.Assert.assertEquals
@@ -40,57 +39,72 @@ internal class FeedListStateImplTest {
4039

4140
@Test
4241
fun `on queryMoreFeeds, then update feeds and pagination`() = runTest {
43-
val feeds = listOf(feedData(), feedData("feed-2", "user", "Test Feed 2"))
44-
val paginationResult =
45-
PaginationResult(
46-
models = feeds,
47-
pagination = PaginationData(next = "next-cursor", previous = null),
48-
)
49-
val queryConfig =
50-
QueryConfiguration<FeedsFilterField, FeedsSort>(filter = null, sort = FeedsSort.Default)
42+
val feed1 = feedData(id = "feed-1", groupId = "user", name = "First Feed")
43+
val feed2 = feedData(id = "feed-2", groupId = "user", name = "Second Feed")
44+
val feeds = listOf(feed1, feed2)
45+
val paginationResult = defaultPaginationResult(feeds)
5146

52-
feedListState.onQueryMoreFeeds(paginationResult, queryConfig)
47+
feedListState.onQueryMoreFeeds(paginationResult, defaultQueryConfig)
5348

5449
assertEquals(feeds, feedListState.feeds.value)
5550
assertEquals("next-cursor", feedListState.pagination?.next)
56-
assertEquals(queryConfig, feedListState.queryConfig)
51+
assertEquals(defaultQueryConfig, feedListState.queryConfig)
5752
}
5853

5954
@Test
6055
fun `on feedUpdated, then update specific feed`() = runTest {
61-
val initialFeeds = listOf(feedData(), feedData("feed-2", "user", "Test Feed 2"))
62-
val paginationResult =
63-
PaginationResult(
64-
models = initialFeeds,
65-
pagination = PaginationData(next = "next-cursor", previous = null),
66-
)
67-
val queryConfig =
68-
QueryConfiguration<FeedsFilterField, FeedsSort>(filter = null, sort = FeedsSort.Default)
69-
feedListState.onQueryMoreFeeds(paginationResult, queryConfig)
56+
val feed1 = feedData(id = "feed-1", groupId = "user", name = "First Feed")
57+
val feed2 = feedData(id = "feed-2", groupId = "user", name = "Second Feed")
58+
val initialFeeds = listOf(feed1, feed2)
59+
val paginationResult = defaultPaginationResult(initialFeeds)
60+
feedListState.onQueryMoreFeeds(paginationResult, defaultQueryConfig)
7061

7162
val updatedFeed =
72-
feedData("user-1", "user", "Updated Feed", description = "Updated description")
63+
feedData(
64+
id = "feed-1",
65+
groupId = "user",
66+
name = "Updated Feed",
67+
description = "Updated description",
68+
)
7369
feedListState.onFeedUpdated(updatedFeed)
7470

7571
val updatedFeeds = feedListState.feeds.value
76-
assertEquals(listOf(updatedFeed, initialFeeds[1]), updatedFeeds)
72+
assertEquals(listOf(updatedFeed, feed2), updatedFeeds)
7773
}
7874

7975
@Test
8076
fun `on feedUpdated with non-existent feed, then keep existing feeds unchanged`() = runTest {
81-
val initialFeeds = listOf(feedData(), feedData("feed-2", "user", "Test Feed 2"))
82-
val paginationResult =
83-
PaginationResult(
84-
models = initialFeeds,
85-
pagination = PaginationData(next = "next-cursor", previous = null),
86-
)
77+
val feed1 = feedData(id = "feed-1", groupId = "user", name = "First Feed")
78+
val feed2 = feedData(id = "feed-2", groupId = "user", name = "Second Feed")
79+
val initialFeeds = listOf(feed1, feed2)
80+
val paginationResult = defaultPaginationResult(initialFeeds)
81+
feedListState.onQueryMoreFeeds(paginationResult, defaultQueryConfig)
82+
83+
val nonExistentFeed =
84+
feedData(id = "non-existent", groupId = "user", name = "Non-existent Feed")
85+
feedListState.onFeedUpdated(nonExistentFeed)
86+
87+
assertEquals(initialFeeds, feedListState.feeds.value)
88+
}
89+
90+
@Test
91+
fun `on feedRemoved, then remove specific feed`() = runTest {
92+
val feed1 = feedData(id = "feed-1", groupId = "user", name = "First Feed")
93+
val feed2 = feedData(id = "feed-2", groupId = "user", name = "Second Feed")
94+
val initialFeeds = listOf(feed1, feed2)
95+
val paginationResult = defaultPaginationResult(initialFeeds)
8796
val queryConfig =
8897
QueryConfiguration<FeedsFilterField, FeedsSort>(filter = null, sort = FeedsSort.Default)
8998
feedListState.onQueryMoreFeeds(paginationResult, queryConfig)
9099

91-
val nonExistentFeed = feedData("non-existent", "user", "Non-existent Feed")
92-
feedListState.onFeedUpdated(nonExistentFeed)
100+
feedListState.onFeedRemoved("user:feed-1")
93101

94-
assertEquals(initialFeeds, feedListState.feeds.value)
102+
val remainingFeeds = feedListState.feeds.value
103+
assertEquals(listOf(feed2), remainingFeeds)
104+
}
105+
106+
companion object {
107+
private val defaultQueryConfig =
108+
QueryConfiguration<FeedsFilterField, FeedsSort>(filter = null, sort = FeedsSort.Default)
95109
}
96110
}

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

Lines changed: 11 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.FeedListStateUpdates
2020
import io.getstream.feeds.android.client.internal.test.TestData.feedResponse
21+
import io.getstream.feeds.android.network.models.FeedDeletedEvent
2122
import io.getstream.feeds.android.network.models.FeedUpdatedEvent
2223
import io.getstream.feeds.android.network.models.WSEvent
2324
import io.mockk.called
@@ -47,6 +48,16 @@ internal class FeedListEventHandlerTest {
4748
verify { state.onFeedUpdated(feed.toModel()) }
4849
}
4950

51+
@Test
52+
fun `on FeedDeletedEvent, then call onFeedRemoved`() {
53+
val event =
54+
FeedDeletedEvent(createdAt = Date(), fid = "user:feed-1", type = "feeds.feed.deleted")
55+
56+
handler.onEvent(event)
57+
58+
verify { state.onFeedRemoved("user:feed-1") }
59+
}
60+
5061
@Test
5162
fun `on unknown event, then do nothing`() {
5263
val unknownEvent =

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import io.getstream.feeds.android.client.api.model.FileUploadConfigData
3030
import io.getstream.feeds.android.client.api.model.FollowData
3131
import io.getstream.feeds.android.client.api.model.FollowStatus
3232
import io.getstream.feeds.android.client.api.model.ModerationConfigData
33+
import io.getstream.feeds.android.client.api.model.PaginationData
34+
import io.getstream.feeds.android.client.api.model.PaginationResult
3335
import io.getstream.feeds.android.client.api.model.PollData
3436
import io.getstream.feeds.android.client.api.model.PollOptionData
3537
import io.getstream.feeds.android.client.api.model.PollVoteData
@@ -684,4 +686,10 @@ internal object TestData {
684686
updatedAt = Date(1000),
685687
user = userResponse(),
686688
)
689+
690+
fun <T> defaultPaginationResult(list: List<T>): PaginationResult<T> =
691+
PaginationResult(
692+
models = list,
693+
pagination = PaginationData(next = "next-cursor", previous = null),
694+
)
687695
}

0 commit comments

Comments
 (0)