From 16474d6ece4ce14c47151fdf99508c764f240f95 Mon Sep 17 00:00:00 2001 From: Gian <47775302+gpunto@users.noreply.github.com> Date: Mon, 31 Aug 2026 17:03:03 +0200 Subject: [PATCH 1/6] Migrate the channel config to the generated ChannelConfigWithInfo model --- .../client/api2/mapping/DomainMapping.kt | 34 ---- .../client/api2/model/dto/ChannelDtos.kt | 3 +- .../client/api2/model/dto/ConfigDto.kt | 52 ------ .../android/client/EventChatJsonProvider.kt | 5 + .../getstream/chat/android/client/Mother.kt | 90 ++++------- .../client/api2/mapping/DomainMappingTest.kt | 117 ++++++++------ ...QueryGroupedChannelsResponseAdapterTest.kt | 26 ++- .../parser2/testdata/ChannelDtoTestData.kt | 148 ++++-------------- 8 files changed, 165 insertions(+), 310 deletions(-) delete mode 100644 stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/ConfigDto.kt diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DomainMapping.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DomainMapping.kt index fb2c6458fe8..3ed0c3e9318 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DomainMapping.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DomainMapping.kt @@ -22,7 +22,6 @@ import io.getstream.chat.android.ReadReceipts import io.getstream.chat.android.TypingIndicators import io.getstream.chat.android.client.api2.model.dto.AttachmentDto import io.getstream.chat.android.client.api2.model.dto.ChannelInfoDto -import io.getstream.chat.android.client.api2.model.dto.ConfigDto import io.getstream.chat.android.client.api2.model.dto.DeliveryReceiptsDto import io.getstream.chat.android.client.api2.model.dto.DeviceDto import io.getstream.chat.android.client.api2.model.dto.DownstreamChannelDto @@ -993,39 +992,6 @@ internal class DomainMapping( set = set, ) - /** - * Transforms [ConfigDto] to [Config]. - */ - internal fun ConfigDto.toDomain(): Config = Config( - createdAt = created_at, - updatedAt = updated_at, - name = name ?: "", - typingEventsEnabled = typing_events, - readEventsEnabled = read_events, - deliveryEventsEnabled = delivery_events, - connectEventsEnabled = connect_events, - searchEnabled = search, - isReactionsEnabled = reactions, - isThreadEnabled = replies, - muteEnabled = mutes, - uploadsEnabled = uploads, - urlEnrichmentEnabled = url_enrichment, - customEventsEnabled = custom_events, - pushNotificationsEnabled = push_notifications, - skipLastMsgUpdateForSystemMsgs = skip_last_msg_update_for_system_msgs ?: false, - pollsEnabled = polls, - messageRetention = message_retention, - maxMessageLength = max_message_length, - automod = automod, - automodBehavior = automod_behavior, - blocklistBehavior = blocklist_behavior ?: "", - commands = commands.map { it.toDomain() }, - messageRemindersEnabled = user_message_reminders ?: false, - sharedLocationsEnabled = shared_locations ?: false, - markMessagesPending = mark_messages_pending, - pushLevel = push_level, - ) - /** * Transforms [ChannelConfigWithInfo] to [Config]. */ diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/ChannelDtos.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/ChannelDtos.kt index e79c19e291f..86cbdc48309 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/ChannelDtos.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/ChannelDtos.kt @@ -17,6 +17,7 @@ package io.getstream.chat.android.client.api2.model.dto import com.squareup.moshi.JsonClass +import io.getstream.chat.android.network.models.ChannelConfigWithInfo import java.util.Date @JsonClass(generateAdapter = true) @@ -41,7 +42,7 @@ internal data class DownstreamChannelDto( val members: List = emptyList(), val watchers: List = emptyList(), val read: List = emptyList(), - val config: ConfigDto, + val config: ChannelConfigWithInfo, val created_by: DownstreamUserDto?, val team: String = "", val cooldown: Int = 0, diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/ConfigDto.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/ConfigDto.kt deleted file mode 100644 index 9f50810b302..00000000000 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/ConfigDto.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2014-2026 Stream.io Inc. All rights reserved. - * - * Licensed under the Stream License; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://github.com/GetStream/stream-chat-android/blob/main/LICENSE - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.getstream.chat.android.client.api2.model.dto - -import com.squareup.moshi.JsonClass -import java.util.Date -import io.getstream.chat.android.network.models.Command as CommandDto - -@JsonClass(generateAdapter = true) -internal data class ConfigDto( - val created_at: Date?, - val updated_at: Date?, - val name: String?, - val typing_events: Boolean, - val read_events: Boolean, - val delivery_events: Boolean = true, - val connect_events: Boolean, - val search: Boolean, - val reactions: Boolean, - val replies: Boolean, - val mutes: Boolean, - val uploads: Boolean, - val url_enrichment: Boolean, - val custom_events: Boolean, - val push_notifications: Boolean, - val skip_last_msg_update_for_system_msgs: Boolean?, - val polls: Boolean, - val message_retention: String, - val max_message_length: Int, - val automod: String, - val automod_behavior: String, - val blocklist_behavior: String?, - val commands: List, - val user_message_reminders: Boolean?, - val shared_locations: Boolean?, - val mark_messages_pending: Boolean, - val push_level: String? = null, -) diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/EventChatJsonProvider.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/EventChatJsonProvider.kt index f2a62c2d693..e3cc59c928f 100644 --- a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/EventChatJsonProvider.kt +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/EventChatJsonProvider.kt @@ -943,6 +943,11 @@ private fun createConfigJsonString() = "updated_at": "2020-06-29T06:14:28.000Z", "name": "team", "typing_events": true, + "count_messages": true, + "quotes": true, + "reminders": false, + "shared_locations": false, + "user_message_reminders": false, "read_events": true, "delivery_events": true, "connect_events": true, diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/Mother.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/Mother.kt index 717d9d8a580..6bf4fb395a8 100644 --- a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/Mother.kt +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/Mother.kt @@ -25,7 +25,6 @@ import io.getstream.chat.android.client.api.models.SendActionRequest import io.getstream.chat.android.client.api.models.UpdatePollRequest import io.getstream.chat.android.client.api2.model.dto.AttachmentDto import io.getstream.chat.android.client.api2.model.dto.ChannelInfoDto -import io.getstream.chat.android.client.api2.model.dto.ConfigDto import io.getstream.chat.android.client.api2.model.dto.DeviceDto import io.getstream.chat.android.client.api2.model.dto.DownstreamChannelDto import io.getstream.chat.android.client.api2.model.dto.DownstreamChannelMuteDto @@ -90,6 +89,7 @@ import io.getstream.chat.android.network.models.AppResponseFields import io.getstream.chat.android.network.models.BanResponse import io.getstream.chat.android.network.models.BlockUsersResponse import io.getstream.chat.android.network.models.BlockedUserResponse +import io.getstream.chat.android.network.models.ChannelConfigWithInfo import io.getstream.chat.android.network.models.ChannelMemberResponse import io.getstream.chat.android.network.models.ChannelResponse import io.getstream.chat.android.network.models.CreateGuestResponse @@ -461,7 +461,7 @@ internal object Mother { members: List = emptyList(), watchers: List = emptyList(), read: List = emptyList(), - config: ConfigDto = randomConfigDto(), + config: ChannelConfigWithInfo = randomChannelConfigWithInfo(), created_by: DownstreamUserDto? = randomDownstreamUserDto(), team: String = randomString(), cooldown: Int = randomInt(), @@ -516,67 +516,39 @@ internal object Mother { image = image, ) - fun randomConfigDto( - created_at: Date? = randomDateOrNull(), - updated_at: Date? = randomDateOrNull(), - name: String? = randomString(), - typing_events: Boolean = randomBoolean(), - read_events: Boolean = randomBoolean(), - delivery_events: Boolean = randomBoolean(), - connect_events: Boolean = randomBoolean(), - search: Boolean = randomBoolean(), - reactions: Boolean = randomBoolean(), - replies: Boolean = randomBoolean(), - mutes: Boolean = randomBoolean(), - uploads: Boolean = randomBoolean(), - url_enrichment: Boolean = randomBoolean(), - custom_events: Boolean = randomBoolean(), - push_notifications: Boolean = randomBoolean(), - skip_last_msg_update_for_system_msgs: Boolean? = randomBoolean(), - polls: Boolean = randomBoolean(), - message_retention: String = randomString(), - max_message_length: Int = randomInt(), - automod: String = randomString(), - automod_behavior: String = randomString(), - blocklist_behavior: String? = randomString(), + fun randomChannelConfigWithInfo( commands: List = emptyList(), - user_message_reminders: Boolean? = randomBoolean(), - shared_locations: Boolean = randomBoolean(), - mark_messages_pending: Boolean = randomBoolean(), - push_level: String? = randomString(), - ): ConfigDto = ConfigDto( - created_at = created_at, - updated_at = updated_at, - name = name, - typing_events = typing_events, - read_events = read_events, - delivery_events = delivery_events, - connect_events = connect_events, - search = search, - reactions = reactions, - replies = replies, - mutes = mutes, - uploads = uploads, - url_enrichment = url_enrichment, - custom_events = custom_events, - push_notifications = push_notifications, - skip_last_msg_update_for_system_msgs = skip_last_msg_update_for_system_msgs, - polls = polls, - message_retention = message_retention, - max_message_length = max_message_length, - automod = automod, - automod_behavior = automod_behavior, - blocklist_behavior = blocklist_behavior, + ): ChannelConfigWithInfo = ChannelConfigWithInfo( + createdAt = randomDate(), + updatedAt = randomDate(), + name = randomString(), + typingEvents = randomBoolean(), + readEvents = randomBoolean(), + deliveryEvents = randomBoolean(), + connectEvents = randomBoolean(), + search = randomBoolean(), + reactions = randomBoolean(), + replies = randomBoolean(), + quotes = randomBoolean(), + mutes = randomBoolean(), + uploads = randomBoolean(), + urlEnrichment = randomBoolean(), + customEvents = randomBoolean(), + pushNotifications = randomBoolean(), + reminders = randomBoolean(), + countMessages = randomBoolean(), + skipLastMsgUpdateForSystemMsgs = randomBoolean(), + polls = randomBoolean(), + messageRetention = randomString(), + maxMessageLength = randomInt(), + automod = ChannelConfigWithInfo.Automod.Disabled, + automodBehavior = ChannelConfigWithInfo.AutomodBehavior.Flag, commands = commands, - user_message_reminders = user_message_reminders, - shared_locations = shared_locations, - mark_messages_pending = mark_messages_pending, - push_level = push_level, + userMessageReminders = randomBoolean(), + sharedLocations = randomBoolean(), + markMessagesPending = randomBoolean(), ) - /** - * Provides a [QueryChannelsRequest] with random parameters (that can also be customized). - */ fun randomQueryChannelRequest( state: Boolean = randomBoolean(), watch: Boolean = randomBoolean(), diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/mapping/DomainMappingTest.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/mapping/DomainMappingTest.kt index 555953fdb10..476b21ee9c4 100644 --- a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/mapping/DomainMappingTest.kt +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/mapping/DomainMappingTest.kt @@ -30,7 +30,6 @@ import io.getstream.chat.android.client.Mother.randomChannelInfoDto import io.getstream.chat.android.client.Mother.randomChannelMemberResponse import io.getstream.chat.android.client.Mother.randomChannelResponse import io.getstream.chat.android.client.Mother.randomCommandDto -import io.getstream.chat.android.client.Mother.randomConfigDto import io.getstream.chat.android.client.Mother.randomDeviceResponse import io.getstream.chat.android.client.Mother.randomDownstreamChannelDto import io.getstream.chat.android.client.Mother.randomDownstreamChannelMuteDto @@ -134,6 +133,7 @@ import io.getstream.chat.android.models.VotingVisibility import io.getstream.chat.android.models.querysort.QuerySortByField.Companion.ascByName import io.getstream.chat.android.models.querysort.QuerySortByField.Companion.descByName import io.getstream.chat.android.models.querysort.QuerySorter +import io.getstream.chat.android.network.models.ChannelConfigWithInfo import io.getstream.chat.android.network.models.ChannelPushPreferencesResponse import io.getstream.chat.android.network.models.ChatPreferencesResponse import io.getstream.chat.android.network.models.DeliveryReceiptsResponse @@ -400,17 +400,83 @@ internal class DomainMappingTest { @Test fun `ChannelConfigWithInfo is correctly mapped to Config`() { + val response = alternatingConfigResponse() val sut = Fixture().get() - val config = with(sut) { ChannelDtoTestData.channelResponse.config!!.toDomain() } + val config = with(sut) { response.toDomain() } - assertEquals("retention", config.messageRetention) - assertEquals("disabled", config.automod) - assertEquals("flag", config.automodBehavior) - assertEquals("block", config.blocklistBehavior) - assertEquals(500, config.maxMessageLength) + val commands = with(sut) { response.commands.map { it.toDomain() } } + assertEquals(expectedAlternatingConfig(commands), config) } + /** + * Every boolean alternates so that two fields mapped from the wrong source cannot both be right. + */ + private fun alternatingConfigResponse(): ChannelConfigWithInfo = + ChannelConfigWithInfo( + createdAt = Date(1000), + updatedAt = Date(2000), + name = "messaging", + typingEvents = true, + readEvents = false, + deliveryEvents = true, + connectEvents = false, + search = true, + reactions = false, + replies = true, + quotes = false, + mutes = true, + uploads = false, + urlEnrichment = true, + customEvents = false, + pushNotifications = true, + reminders = false, + countMessages = true, + skipLastMsgUpdateForSystemMsgs = false, + polls = true, + messageRetention = "retention", + maxMessageLength = 500, + automod = ChannelConfigWithInfo.Automod.Disabled, + automodBehavior = ChannelConfigWithInfo.AutomodBehavior.Flag, + blocklistBehavior = ChannelConfigWithInfo.BlocklistBehavior.Block, + pushLevel = ChannelConfigWithInfo.PushLevel.Mentions, + commands = listOf(randomCommandDto(name = "giphy")), + userMessageReminders = true, + sharedLocations = false, + markMessagesPending = true, + ) + + private fun expectedAlternatingConfig(commands: List): Config = + Config( + createdAt = Date(1000), + updatedAt = Date(2000), + name = "messaging", + typingEventsEnabled = true, + readEventsEnabled = false, + deliveryEventsEnabled = true, + connectEventsEnabled = false, + searchEnabled = true, + isReactionsEnabled = false, + isThreadEnabled = true, + muteEnabled = true, + uploadsEnabled = false, + urlEnrichmentEnabled = true, + customEventsEnabled = false, + pushNotificationsEnabled = true, + skipLastMsgUpdateForSystemMsgs = false, + pollsEnabled = true, + messageRetention = "retention", + maxMessageLength = 500, + automod = "disabled", + automodBehavior = "flag", + blocklistBehavior = "block", + pushLevel = "mentions", + commands = commands, + messageRemindersEnabled = true, + sharedLocationsEnabled = false, + markMessagesPending = true, + ) + @Test fun `DownstreamChannelDto is correctly mapped to Channel`() { val downstreamChannelDto = randomDownstreamChannelDto() @@ -1139,43 +1205,6 @@ internal class DomainMappingTest { assertEquals(expected, command) } - @Test - fun `ConfigDto is correctly mapped to Config`() { - val configDto = randomConfigDto() - val sut = Fixture().get() - val config = with(sut) { configDto.toDomain() } - val expected = Config( - createdAt = configDto.created_at, - updatedAt = configDto.updated_at, - name = configDto.name ?: "", - typingEventsEnabled = configDto.typing_events, - readEventsEnabled = configDto.read_events, - deliveryEventsEnabled = configDto.delivery_events, - connectEventsEnabled = configDto.connect_events, - searchEnabled = configDto.search, - isReactionsEnabled = configDto.reactions, - isThreadEnabled = configDto.replies, - muteEnabled = configDto.mutes, - uploadsEnabled = configDto.uploads, - urlEnrichmentEnabled = configDto.url_enrichment, - customEventsEnabled = configDto.custom_events, - pushNotificationsEnabled = configDto.push_notifications, - skipLastMsgUpdateForSystemMsgs = configDto.skip_last_msg_update_for_system_msgs ?: false, - pollsEnabled = configDto.polls, - messageRetention = configDto.message_retention, - maxMessageLength = configDto.max_message_length, - automod = configDto.automod, - automodBehavior = configDto.automod_behavior, - blocklistBehavior = configDto.blocklist_behavior ?: "", - commands = configDto.commands.map { with(sut) { it.toDomain() } }, - messageRemindersEnabled = configDto.user_message_reminders ?: false, - sharedLocationsEnabled = configDto.shared_locations ?: false, - markMessagesPending = configDto.mark_messages_pending, - pushLevel = configDto.push_level, - ) - assertEquals(expected, config) - } - @Test fun `DeviceResponse is correctly mapped to Device`() { val deviceDto = randomDeviceResponse() diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/QueryGroupedChannelsResponseAdapterTest.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/QueryGroupedChannelsResponseAdapterTest.kt index 9bf2010a8ec..4027d04d804 100644 --- a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/QueryGroupedChannelsResponseAdapterTest.kt +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/QueryGroupedChannelsResponseAdapterTest.kt @@ -48,12 +48,19 @@ internal class QueryGroupedChannelsResponseAdapterTest { "disabled": false, "config": { "typing_events": true, + "delivery_events": true, + "name": "messaging", + "shared_locations": false, + "skip_last_msg_update_for_system_msgs": false, + "user_message_reminders": false, "read_events": true, "connect_events": true, "search": true, "reactions": true, "replies": true, "quotes": true, + "reminders": false, + "count_messages": true, "uploads": true, "url_enrichment": true, "custom_events": false, @@ -104,12 +111,19 @@ internal class QueryGroupedChannelsResponseAdapterTest { "disabled": false, "config": { "typing_events": true, + "delivery_events": true, + "name": "messaging", + "shared_locations": false, + "skip_last_msg_update_for_system_msgs": false, + "user_message_reminders": false, "read_events": true, "connect_events": true, "search": true, "reactions": true, "replies": true, "quotes": true, + "reminders": false, + "count_messages": true, "uploads": true, "url_enrichment": true, "custom_events": false, @@ -161,17 +175,17 @@ internal class QueryGroupedChannelsResponseAdapterTest { assertEquals("https://getstream.imgix.net/images/random_svg/stream_logo.svg", channelResponse.channel.image) assertFalse(channelResponse.channel.frozen) assertEquals(0, channelResponse.channel.member_count) - assertTrue(channelResponse.channel.config.typing_events) - assertTrue(channelResponse.channel.config.read_events) - assertTrue(channelResponse.channel.config.connect_events) + assertTrue(channelResponse.channel.config.typingEvents) + assertTrue(channelResponse.channel.config.readEvents) + assertTrue(channelResponse.channel.config.connectEvents) assertTrue(channelResponse.channel.config.search) assertTrue(channelResponse.channel.config.reactions) assertTrue(channelResponse.channel.config.replies) assertTrue(channelResponse.channel.config.uploads) - assertTrue(channelResponse.channel.config.url_enrichment) + assertTrue(channelResponse.channel.config.urlEnrichment) assertTrue(channelResponse.channel.config.mutes) - assertEquals("infinite", channelResponse.channel.config.message_retention) - assertEquals(5000, channelResponse.channel.config.max_message_length) + assertEquals("infinite", channelResponse.channel.config.messageRetention) + assertEquals(5000, channelResponse.channel.config.maxMessageLength) assertEquals(emptyList(), channelResponse.members) assertEquals(emptyList(), channelResponse.messages) assertEquals(emptyList(), channelResponse.pinned_messages) diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/testdata/ChannelDtoTestData.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/testdata/ChannelDtoTestData.kt index e50a96fc135..8646e52d50b 100644 --- a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/testdata/ChannelDtoTestData.kt +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/testdata/ChannelDtoTestData.kt @@ -16,7 +16,6 @@ package io.getstream.chat.android.client.parser2.testdata -import io.getstream.chat.android.client.api2.model.dto.ConfigDto import io.getstream.chat.android.client.api2.model.dto.DownstreamChannelDto import io.getstream.chat.android.client.api2.model.dto.DownstreamChannelUserRead import io.getstream.chat.android.client.api2.model.dto.DownstreamMemberDto @@ -35,7 +34,7 @@ internal object ChannelDtoTestData { """{ "created_at": "2020-06-10T11:04:31.000Z", "updated_at": "2020-06-10T11:04:31.588Z", - "name" : "config1", + "name": "config1", "typing_events": true, "read_events": true, "delivery_events": true, @@ -43,18 +42,21 @@ internal object ChannelDtoTestData { "search": false, "reactions": true, "replies": true, + "quotes": true, "mutes": true, "uploads": true, "url_enrichment": false, "custom_events": false, "push_notifications": true, + "reminders": false, + "count_messages": true, "skip_last_msg_update_for_system_msgs": false, "polls": true, "message_retention": "retention", "max_message_length": 500, - "automod": "none", - "automod_behavior": "none", - "blocklist_behavior": "empty", + "automod": "disabled", + "automod_behavior": "flag", + "blocklist_behavior": "block", "commands": [ { "name": "giphy", @@ -69,29 +71,31 @@ internal object ChannelDtoTestData { } """.withoutWhitespace() - private val configDto: ConfigDto = ConfigDto( - created_at = Date(1591787071000), - updated_at = Date(1591787071588), + private val expectedConfig = ChannelConfigWithInfo( + createdAt = Date(1591787071000), + updatedAt = Date(1591787071588), name = "config1", - typing_events = true, - read_events = true, - delivery_events = true, - connect_events = true, + typingEvents = true, + readEvents = true, + deliveryEvents = true, + connectEvents = true, search = false, reactions = true, replies = true, + quotes = true, mutes = true, uploads = true, - url_enrichment = false, - custom_events = false, - push_notifications = true, - skip_last_msg_update_for_system_msgs = false, + urlEnrichment = false, + customEvents = false, + pushNotifications = true, + reminders = false, + countMessages = true, + skipLastMsgUpdateForSystemMsgs = false, polls = true, - message_retention = "retention", - max_message_length = 500, - automod = "none", - automod_behavior = "none", - blocklist_behavior = "empty", + maxMessageLength = 500, + automod = ChannelConfigWithInfo.Automod.Disabled, + automodBehavior = ChannelConfigWithInfo.AutomodBehavior.Flag, + blocklistBehavior = ChannelConfigWithInfo.BlocklistBehavior.Block, commands = listOf( CommandDto( name = "giphy", @@ -100,12 +104,12 @@ internal object ChannelDtoTestData { set = "none", ), ), - user_message_reminders = false, - shared_locations = true, - mark_messages_pending = false, + userMessageReminders = false, + sharedLocations = true, + markMessagesPending = false, + messageRetention = "retention", ) - @Language("JSON") val downstreamJson = """{ "cid": "channelType:channelId", @@ -218,7 +222,7 @@ internal object ChannelDtoTestData { last_read_message_id = "messageId", ), ), - config = configDto, + config = expectedConfig, created_by = UserDtoTestData.downstreamUser, team = "team1", cooldown = 1, @@ -281,7 +285,7 @@ internal object ChannelDtoTestData { members = emptyList(), watchers = emptyList(), read = emptyList(), - config = configDto, + config = expectedConfig, created_by = null, team = "", cooldown = 0, @@ -290,90 +294,6 @@ internal object ChannelDtoTestData { extraData = emptyMap(), ) - /** - * The config as sent for a generated [io.getstream.chat.android.network.models.ChannelResponse]. - */ - @Language("JSON") - private val channelResponseConfigJson = - """{ - "created_at": "2020-06-10T11:04:31.000Z", - "updated_at": "2020-06-10T11:04:31.588Z", - "name": "config1", - "typing_events": true, - "read_events": true, - "delivery_events": true, - "connect_events": true, - "search": false, - "reactions": true, - "replies": true, - "quotes": true, - "mutes": true, - "uploads": true, - "url_enrichment": false, - "custom_events": false, - "push_notifications": true, - "reminders": false, - "count_messages": true, - "skip_last_msg_update_for_system_msgs": false, - "polls": true, - "message_retention": "retention", - "max_message_length": 500, - "automod": "disabled", - "automod_behavior": "flag", - "blocklist_behavior": "block", - "commands": [ - { - "name": "giphy", - "description": "gif", - "args": "empty", - "set": "none" - } - ], - "user_message_reminders": false, - "shared_locations": true, - "mark_messages_pending": false - } - """.withoutWhitespace() - - private val channelResponseConfig = ChannelConfigWithInfo( - createdAt = Date(1591787071000), - updatedAt = Date(1591787071588), - name = "config1", - typingEvents = true, - readEvents = true, - deliveryEvents = true, - connectEvents = true, - search = false, - reactions = true, - replies = true, - quotes = true, - mutes = true, - uploads = true, - urlEnrichment = false, - customEvents = false, - pushNotifications = true, - reminders = false, - countMessages = true, - skipLastMsgUpdateForSystemMsgs = false, - polls = true, - maxMessageLength = 500, - automod = ChannelConfigWithInfo.Automod.Disabled, - automodBehavior = ChannelConfigWithInfo.AutomodBehavior.Flag, - blocklistBehavior = ChannelConfigWithInfo.BlocklistBehavior.Block, - commands = listOf( - CommandDto( - name = "giphy", - description = "gif", - args = "empty", - set = "none", - ), - ), - userMessageReminders = false, - sharedLocations = true, - markMessagesPending = false, - messageRetention = "retention", - ) - /** * A channel as embedded in a thread: `name` and `image` are custom data, and the type carries no * messages, watchers or reads. @@ -396,7 +316,7 @@ internal object ChannelDtoTestData { "hidden": true, "hide_messages_before": "2020-06-10T11:04:31.588Z", "own_capabilities": ["connect-events", "pin-message"], - "config": $channelResponseConfigJson, + "config": $configJson, "customKey1": "customVal1" } """.withoutWhitespace() @@ -418,7 +338,7 @@ internal object ChannelDtoTestData { ChannelOwnCapability.ConnectEvents, ChannelOwnCapability.PinMessage, ), - config = channelResponseConfig, + config = expectedConfig, custom = mapOf( "name" to "channelName", "image" to "channelImage", @@ -464,7 +384,7 @@ internal object ChannelDtoTestData { members = emptyList(), watchers = emptyList(), read = emptyList(), - config = configDto, + config = expectedConfig, created_by = null, team = "", cooldown = 0, From d6b1407be973e1f249e030a2819e92728f49cf03 Mon Sep 17 00:00:00 2001 From: Gian <47775302+gpunto@users.noreply.github.com> Date: Wed, 2 Sep 2026 10:20:22 +0200 Subject: [PATCH 2/6] Add the required channel config keys to the uitests fixtures and assert them --- .../parser2/QueryGroupedChannelsResponseAdapterTest.kt | 8 ++++++++ .../src/androidTest/resources/http_channel.json | 7 +++++++ .../src/androidTest/resources/http_channels.json | 6 ++++++ 3 files changed, 21 insertions(+) diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/QueryGroupedChannelsResponseAdapterTest.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/QueryGroupedChannelsResponseAdapterTest.kt index 4027d04d804..0abd55ba707 100644 --- a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/QueryGroupedChannelsResponseAdapterTest.kt +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/QueryGroupedChannelsResponseAdapterTest.kt @@ -184,6 +184,14 @@ internal class QueryGroupedChannelsResponseAdapterTest { assertTrue(channelResponse.channel.config.uploads) assertTrue(channelResponse.channel.config.urlEnrichment) assertTrue(channelResponse.channel.config.mutes) + assertTrue(channelResponse.channel.config.deliveryEvents) + assertTrue(channelResponse.channel.config.quotes) + assertTrue(channelResponse.channel.config.countMessages) + assertFalse(channelResponse.channel.config.reminders) + assertFalse(channelResponse.channel.config.userMessageReminders) + assertFalse(channelResponse.channel.config.sharedLocations) + assertFalse(channelResponse.channel.config.skipLastMsgUpdateForSystemMsgs) + assertEquals("messaging", channelResponse.channel.config.name) assertEquals("infinite", channelResponse.channel.config.messageRetention) assertEquals(5000, channelResponse.channel.config.maxMessageLength) assertEquals(emptyList(), channelResponse.members) diff --git a/stream-chat-android-ui-uitests/src/androidTest/resources/http_channel.json b/stream-chat-android-ui-uitests/src/androidTest/resources/http_channel.json index c5f18583c26..8fbeb154789 100644 --- a/stream-chat-android-ui-uitests/src/androidTest/resources/http_channel.json +++ b/stream-chat-android-ui-uitests/src/androidTest/resources/http_channel.json @@ -38,6 +38,13 @@ "url_enrichment": true, "custom_events": true, "push_notifications": true, + "delivery_events": true, + "count_messages": true, + "polls": true, + "skip_last_msg_update_for_system_msgs": false, + "user_message_reminders": false, + "shared_locations": false, + "mark_messages_pending": false, "reminders": false, "message_retention": "infinite", "max_message_length": 5000, diff --git a/stream-chat-android-ui-uitests/src/androidTest/resources/http_channels.json b/stream-chat-android-ui-uitests/src/androidTest/resources/http_channels.json index 38b25f60623..c1a283a7411 100644 --- a/stream-chat-android-ui-uitests/src/androidTest/resources/http_channels.json +++ b/stream-chat-android-ui-uitests/src/androidTest/resources/http_channels.json @@ -41,6 +41,12 @@ "url_enrichment": true, "custom_events": true, "push_notifications": true, + "delivery_events": true, + "count_messages": true, + "skip_last_msg_update_for_system_msgs": false, + "user_message_reminders": false, + "shared_locations": false, + "mark_messages_pending": false, "reminders": false, "message_retention": "infinite", "max_message_length": 5000, From 48adcd67255cd7d4803b90d8df0a2e922f7c3a93 Mon Sep 17 00:00:00 2001 From: Gian <47775302+gpunto@users.noreply.github.com> Date: Wed, 2 Sep 2026 13:11:09 +0200 Subject: [PATCH 3/6] Lock in that unrecognised channel config modes reach the domain unchanged --- .../parser2/ChannelConfigEnumParsingTest.kt | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/ChannelConfigEnumParsingTest.kt diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/ChannelConfigEnumParsingTest.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/ChannelConfigEnumParsingTest.kt new file mode 100644 index 00000000000..c97127a97b3 --- /dev/null +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/ChannelConfigEnumParsingTest.kt @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014-2026 Stream.io Inc. All rights reserved. + * + * Licensed under the Stream License; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://github.com/GetStream/stream-chat-android/blob/main/LICENSE + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.getstream.chat.android.client.parser2 + +import io.getstream.chat.android.client.parser2.testdata.ChannelDtoTestData +import io.getstream.chat.android.network.models.ChannelConfigWithInfo +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +/** + * The config's automod, blocklist and push fields used to be plain strings that accepted any value. + * They are sealed classes now, so a mode the SDK does not know must still reach the domain unchanged + * rather than being dropped or coerced. + */ +internal class ChannelConfigEnumParsingTest { + + private val parser = ParserFactory.createMoshiChatParser() + + // Derived from the shared fixture so the required fields stay in one place. + private val configJsonWithUnknownEnums = ChannelDtoTestData.configJson + .replace("\"automod\":\"disabled\"", "\"automod\":\"future_mode\"") + .replace("\"automod_behavior\":\"flag\"", "\"automod_behavior\":\"future_behavior\"") + .replace("\"blocklist_behavior\":\"block\"", "\"blocklist_behavior\":\"future_blocklist\"") + + @Test + fun `Unrecognised config modes are preserved as Unknown`() { + val config = parser.fromJson(configJsonWithUnknownEnums, ChannelConfigWithInfo::class.java) + + assertEquals(ChannelConfigWithInfo.Automod.Unknown("future_mode"), config.automod) + assertEquals( + ChannelConfigWithInfo.AutomodBehavior.Unknown("future_behavior"), + config.automodBehavior, + ) + assertEquals( + ChannelConfigWithInfo.BlocklistBehavior.Unknown("future_blocklist"), + config.blocklistBehavior, + ) + } + + @Test + fun `Unrecognised config modes reach the domain as the raw wire value`() { + val config = parser.fromJson(configJsonWithUnknownEnums, ChannelConfigWithInfo::class.java) + + assertEquals("future_mode", config.automod.value) + assertEquals("future_behavior", config.automodBehavior.value) + assertEquals("future_blocklist", config.blocklistBehavior?.value) + } +} From db05fa70605e8e2a5ff361c2a6dafe1c1acf83b8 Mon Sep 17 00:00:00 2001 From: Gian <47775302+gpunto@users.noreply.github.com> Date: Fri, 4 Sep 2026 10:06:55 +0200 Subject: [PATCH 4/6] Choose config fixture values that differ from the domain defaults --- .../client/api2/mapping/DomainMappingTest.kt | 50 ++++++++++--------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/mapping/DomainMappingTest.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/mapping/DomainMappingTest.kt index 476b21ee9c4..c11b3db58bf 100644 --- a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/mapping/DomainMappingTest.kt +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/mapping/DomainMappingTest.kt @@ -410,39 +410,41 @@ internal class DomainMappingTest { } /** - * Every boolean alternates so that two fields mapped from the wrong source cannot both be right. + * Every value differs from the [Config] default it maps onto, so a field the mapper fails to map + * lands on its default and the comparison notices. Alternating values is not enough: a value that + * happens to equal the default hides a dropped mapping. */ private fun alternatingConfigResponse(): ChannelConfigWithInfo = ChannelConfigWithInfo( createdAt = Date(1000), updatedAt = Date(2000), name = "messaging", - typingEvents = true, + typingEvents = false, readEvents = false, - deliveryEvents = true, + deliveryEvents = false, connectEvents = false, - search = true, + search = false, reactions = false, - replies = true, + replies = false, quotes = false, - mutes = true, + mutes = false, uploads = false, - urlEnrichment = true, - customEvents = false, - pushNotifications = true, - reminders = false, + urlEnrichment = false, + customEvents = true, + pushNotifications = false, + reminders = true, countMessages = true, - skipLastMsgUpdateForSystemMsgs = false, + skipLastMsgUpdateForSystemMsgs = true, polls = true, messageRetention = "retention", maxMessageLength = 500, - automod = ChannelConfigWithInfo.Automod.Disabled, + automod = ChannelConfigWithInfo.Automod.AI, automodBehavior = ChannelConfigWithInfo.AutomodBehavior.Flag, blocklistBehavior = ChannelConfigWithInfo.BlocklistBehavior.Block, pushLevel = ChannelConfigWithInfo.PushLevel.Mentions, commands = listOf(randomCommandDto(name = "giphy")), userMessageReminders = true, - sharedLocations = false, + sharedLocations = true, markMessagesPending = true, ) @@ -451,29 +453,29 @@ internal class DomainMappingTest { createdAt = Date(1000), updatedAt = Date(2000), name = "messaging", - typingEventsEnabled = true, + typingEventsEnabled = false, readEventsEnabled = false, - deliveryEventsEnabled = true, + deliveryEventsEnabled = false, connectEventsEnabled = false, - searchEnabled = true, + searchEnabled = false, isReactionsEnabled = false, - isThreadEnabled = true, - muteEnabled = true, + isThreadEnabled = false, + muteEnabled = false, uploadsEnabled = false, - urlEnrichmentEnabled = true, - customEventsEnabled = false, - pushNotificationsEnabled = true, - skipLastMsgUpdateForSystemMsgs = false, + urlEnrichmentEnabled = false, + customEventsEnabled = true, + pushNotificationsEnabled = false, + skipLastMsgUpdateForSystemMsgs = true, pollsEnabled = true, messageRetention = "retention", maxMessageLength = 500, - automod = "disabled", + automod = "AI", automodBehavior = "flag", blocklistBehavior = "block", pushLevel = "mentions", commands = commands, messageRemindersEnabled = true, - sharedLocationsEnabled = false, + sharedLocationsEnabled = true, markMessagesPending = true, ) From d4f5d1e6f1da36f784be4f4fdcd6f203475fd811 Mon Sep 17 00:00:00 2001 From: Gian <47775302+gpunto@users.noreply.github.com> Date: Mon, 7 Sep 2026 16:53:00 +0200 Subject: [PATCH 5/6] Accept a channel without a config instead of failing the whole response --- .../client/api2/mapping/DomainMapping.kt | 2 +- .../client/api2/model/dto/ChannelDtos.kt | 3 +- .../DownstreamChannelDtoAdapterTest.kt | 22 +++++++++++ ...QueryGroupedChannelsResponseAdapterTest.kt | 39 ++++++++++--------- 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DomainMapping.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DomainMapping.kt index 3ed0c3e9318..c310ff3006b 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DomainMapping.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DomainMapping.kt @@ -218,7 +218,7 @@ internal class DomainMapping( lastReceivedEventDate = last_message_at ?: it.last_read, ) }, - config = config.toDomain(), + config = config?.toDomain() ?: Config(), createdBy = created_by?.toDomain() ?: User(), team = team, cooldown = cooldown, diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/ChannelDtos.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/ChannelDtos.kt index 86cbdc48309..94b1cb0f4d1 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/ChannelDtos.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/ChannelDtos.kt @@ -42,7 +42,8 @@ internal data class DownstreamChannelDto( val members: List = emptyList(), val watchers: List = emptyList(), val read: List = emptyList(), - val config: ChannelConfigWithInfo, + // Absent for a channel whose type is no longer in the app config. + val config: ChannelConfigWithInfo? = null, val created_by: DownstreamUserDto?, val team: String = "", val cooldown: Int = 0, diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/DownstreamChannelDtoAdapterTest.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/DownstreamChannelDtoAdapterTest.kt index 9773aed4a07..2139a17e5ff 100644 --- a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/DownstreamChannelDtoAdapterTest.kt +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/DownstreamChannelDtoAdapterTest.kt @@ -16,8 +16,13 @@ package io.getstream.chat.android.client.parser2 +import io.getstream.chat.android.client.api2.mapping.DomainMapping import io.getstream.chat.android.client.api2.model.dto.DownstreamChannelDto import io.getstream.chat.android.client.parser2.testdata.ChannelDtoTestData +import io.getstream.chat.android.models.Config +import io.getstream.chat.android.models.NoOpChannelTransformer +import io.getstream.chat.android.models.NoOpMessageTransformer +import io.getstream.chat.android.models.NoOpUserTransformer import org.amshove.kluent.invoking import org.amshove.kluent.shouldBeEqualTo import org.amshove.kluent.shouldThrow @@ -27,6 +32,13 @@ import java.util.Date internal class DownstreamChannelDtoAdapterTest { private val parser = ParserFactory.createMoshiChatParser() + private val domainMapping = DomainMapping( + currentUserIdProvider = { null }, + channelTransformer = NoOpChannelTransformer, + messageTransformer = NoOpMessageTransformer, + userTransformer = NoOpUserTransformer, + ) + @Test fun `Deserialize JSON channel with custom fields`() { val channel = parser.fromJson( @@ -69,6 +81,16 @@ internal class DownstreamChannelDtoAdapterTest { channel.extraData["blocked"] shouldBeEqualTo true } + @Test + fun `Deserialize JSON channel with an explicitly null config`() { + val json = ChannelDtoTestData.downstreamJson.replace(ChannelDtoTestData.configJson, "null") + + val channel = parser.fromJson(json, DownstreamChannelDto::class.java) + + channel.config shouldBeEqualTo null + with(domainMapping) { channel.toDomain() }.config shouldBeEqualTo Config() + } + @Test fun `Can't serialize downstream dto`() { invoking { diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/QueryGroupedChannelsResponseAdapterTest.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/QueryGroupedChannelsResponseAdapterTest.kt index 0abd55ba707..ef7b543c510 100644 --- a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/QueryGroupedChannelsResponseAdapterTest.kt +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/QueryGroupedChannelsResponseAdapterTest.kt @@ -175,25 +175,26 @@ internal class QueryGroupedChannelsResponseAdapterTest { assertEquals("https://getstream.imgix.net/images/random_svg/stream_logo.svg", channelResponse.channel.image) assertFalse(channelResponse.channel.frozen) assertEquals(0, channelResponse.channel.member_count) - assertTrue(channelResponse.channel.config.typingEvents) - assertTrue(channelResponse.channel.config.readEvents) - assertTrue(channelResponse.channel.config.connectEvents) - assertTrue(channelResponse.channel.config.search) - assertTrue(channelResponse.channel.config.reactions) - assertTrue(channelResponse.channel.config.replies) - assertTrue(channelResponse.channel.config.uploads) - assertTrue(channelResponse.channel.config.urlEnrichment) - assertTrue(channelResponse.channel.config.mutes) - assertTrue(channelResponse.channel.config.deliveryEvents) - assertTrue(channelResponse.channel.config.quotes) - assertTrue(channelResponse.channel.config.countMessages) - assertFalse(channelResponse.channel.config.reminders) - assertFalse(channelResponse.channel.config.userMessageReminders) - assertFalse(channelResponse.channel.config.sharedLocations) - assertFalse(channelResponse.channel.config.skipLastMsgUpdateForSystemMsgs) - assertEquals("messaging", channelResponse.channel.config.name) - assertEquals("infinite", channelResponse.channel.config.messageRetention) - assertEquals(5000, channelResponse.channel.config.maxMessageLength) + val config = channelResponse.channel.config!! + assertTrue(config.typingEvents) + assertTrue(config.readEvents) + assertTrue(config.connectEvents) + assertTrue(config.search) + assertTrue(config.reactions) + assertTrue(config.replies) + assertTrue(config.uploads) + assertTrue(config.urlEnrichment) + assertTrue(config.mutes) + assertTrue(config.deliveryEvents) + assertTrue(config.quotes) + assertTrue(config.countMessages) + assertFalse(config.reminders) + assertFalse(config.userMessageReminders) + assertFalse(config.sharedLocations) + assertFalse(config.skipLastMsgUpdateForSystemMsgs) + assertEquals("messaging", config.name) + assertEquals("infinite", config.messageRetention) + assertEquals(5000, config.maxMessageLength) assertEquals(emptyList(), channelResponse.members) assertEquals(emptyList(), channelResponse.messages) assertEquals(emptyList(), channelResponse.pinned_messages) From 82c3fd58410471942789603536fe100794cc8af4 Mon Sep 17 00:00:00 2001 From: Gian <47775302+gpunto@users.noreply.github.com> Date: Mon, 7 Sep 2026 16:53:00 +0200 Subject: [PATCH 6/6] Assert the unknown config modes through the mapper and restore the lost annotations --- .../getstream/chat/android/client/Mother.kt | 3 +++ .../parser2/ChannelConfigEnumParsingTest.kt | 21 +++++++++++++++---- .../parser2/testdata/ChannelDtoTestData.kt | 1 + 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/Mother.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/Mother.kt index 6bf4fb395a8..90e6b5ac1cd 100644 --- a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/Mother.kt +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/Mother.kt @@ -549,6 +549,9 @@ internal object Mother { markMessagesPending = randomBoolean(), ) + /** + * Provides a [QueryChannelsRequest] with random parameters (that can also be customized). + */ fun randomQueryChannelRequest( state: Boolean = randomBoolean(), watch: Boolean = randomBoolean(), diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/ChannelConfigEnumParsingTest.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/ChannelConfigEnumParsingTest.kt index c97127a97b3..bf40a183508 100644 --- a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/ChannelConfigEnumParsingTest.kt +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/ChannelConfigEnumParsingTest.kt @@ -16,7 +16,11 @@ package io.getstream.chat.android.client.parser2 +import io.getstream.chat.android.client.api2.mapping.DomainMapping import io.getstream.chat.android.client.parser2.testdata.ChannelDtoTestData +import io.getstream.chat.android.models.NoOpChannelTransformer +import io.getstream.chat.android.models.NoOpMessageTransformer +import io.getstream.chat.android.models.NoOpUserTransformer import io.getstream.chat.android.network.models.ChannelConfigWithInfo import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test @@ -30,6 +34,13 @@ internal class ChannelConfigEnumParsingTest { private val parser = ParserFactory.createMoshiChatParser() + private val domainMapping = DomainMapping( + currentUserIdProvider = { null }, + channelTransformer = NoOpChannelTransformer, + messageTransformer = NoOpMessageTransformer, + userTransformer = NoOpUserTransformer, + ) + // Derived from the shared fixture so the required fields stay in one place. private val configJsonWithUnknownEnums = ChannelDtoTestData.configJson .replace("\"automod\":\"disabled\"", "\"automod\":\"future_mode\"") @@ -53,10 +64,12 @@ internal class ChannelConfigEnumParsingTest { @Test fun `Unrecognised config modes reach the domain as the raw wire value`() { - val config = parser.fromJson(configJsonWithUnknownEnums, ChannelConfigWithInfo::class.java) + val parsed = parser.fromJson(configJsonWithUnknownEnums, ChannelConfigWithInfo::class.java) + + val config = with(domainMapping) { parsed.toDomain() } - assertEquals("future_mode", config.automod.value) - assertEquals("future_behavior", config.automodBehavior.value) - assertEquals("future_blocklist", config.blocklistBehavior?.value) + assertEquals("future_mode", config.automod) + assertEquals("future_behavior", config.automodBehavior) + assertEquals("future_blocklist", config.blocklistBehavior) } } diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/testdata/ChannelDtoTestData.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/testdata/ChannelDtoTestData.kt index 8646e52d50b..d573f7e38c1 100644 --- a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/testdata/ChannelDtoTestData.kt +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/testdata/ChannelDtoTestData.kt @@ -110,6 +110,7 @@ internal object ChannelDtoTestData { messageRetention = "retention", ) + @Language("JSON") val downstreamJson = """{ "cid": "channelType:channelId",