diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 0a67d2e8c85..740b66618ec 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -698,6 +698,8 @@ style: excludePackageStatements: true excludeImportStatements: true excludeCommentStatements: false + # Generated network models can have long fully-qualified nested-type lines; don't lint generated code. + excludes: ['**/io/getstream/chat/android/network/**'] ignoreAnnotated: ['Test', 'ParameterizedTest', "Language"] MayBeConst: active: true diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/MoshiChatApi.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/MoshiChatApi.kt index ffb411991a2..966d97b7472 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/MoshiChatApi.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/MoshiChatApi.kt @@ -69,10 +69,7 @@ import io.getstream.chat.android.client.api2.model.requests.UpdateLiveLocationRe import io.getstream.chat.android.client.api2.model.requests.UpdateMessageRequest import io.getstream.chat.android.client.api2.model.requests.UpsertPushPreferencesRequest import io.getstream.chat.android.client.api2.model.response.ChannelResponse -import io.getstream.chat.android.client.api2.model.response.PushPreferencesResponse import io.getstream.chat.android.client.api2.model.response.TranslateMessageRequest -import io.getstream.chat.android.client.api2.model.response.getUserChannelPreference -import io.getstream.chat.android.client.api2.model.response.getUserPreference import io.getstream.chat.android.client.call.RetrofitCall import io.getstream.chat.android.client.events.ChatEvent import io.getstream.chat.android.client.extensions.enrichWithCid @@ -177,6 +174,7 @@ import io.getstream.chat.android.network.models.UpdateUserGroupResponse import io.getstream.chat.android.network.models.UpdateUserPartialRequest import io.getstream.chat.android.network.models.UpdateUsersPartialRequest import io.getstream.chat.android.network.models.UpdateUsersRequest +import io.getstream.chat.android.network.models.UpsertPushPreferencesResponse import io.getstream.chat.android.network.models.UserGroupResponse import io.getstream.chat.android.network.models.UserRequest import io.getstream.chat.android.network.models.VoteData @@ -2022,9 +2020,9 @@ constructor( private fun RetrofitCall.mapDomain(transform: DomainMapping.(T) -> R): Call = map { domainMapping.transform(it) } - private fun RetrofitCall.parseUserPushPreferencesResponse() = flatMapDomain { + private fun RetrofitCall.parseUserPushPreferencesResponse() = flatMapDomain { val currentUserId = currentUserIdProvider().orEmpty() - val preference = it.getUserPreference(currentUserId) + val preference = it.userPreferences[currentUserId] if (preference != null) { val result = Result.Success(preference.toDomain()) CoroutineCall(coroutineScope) { result } @@ -2037,9 +2035,11 @@ constructor( } } - private fun RetrofitCall.parseChannelPushPreferencesResponse(cid: String) = flatMapDomain { + private fun RetrofitCall.parseChannelPushPreferencesResponse( + cid: String, + ) = flatMapDomain { val currentUserId = currentUserIdProvider().orEmpty() - val preference = it.getUserChannelPreference(currentUserId, cid) + val preference = it.userChannelPreferences[currentUserId]?.get(cid) if (preference != null) { val result = Result.Success(preference.toDomain()) CoroutineCall(coroutineScope) { result } diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/endpoint/PushPreferencesApi.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/endpoint/PushPreferencesApi.kt index e7282bf9220..c9ad96f39b0 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/endpoint/PushPreferencesApi.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/endpoint/PushPreferencesApi.kt @@ -18,8 +18,8 @@ package io.getstream.chat.android.client.api2.endpoint import io.getstream.chat.android.client.api.AuthenticatedApi import io.getstream.chat.android.client.api2.model.requests.UpsertPushPreferencesRequest -import io.getstream.chat.android.client.api2.model.response.PushPreferencesResponse import io.getstream.chat.android.client.call.RetrofitCall +import io.getstream.chat.android.network.models.UpsertPushPreferencesResponse import retrofit2.http.Body import retrofit2.http.POST @@ -35,5 +35,5 @@ internal interface PushPreferencesApi { * @param body The request body containing the push preferences to be upserted. */ @POST("/push_preferences") - fun upsertPushPreferences(@Body body: UpsertPushPreferencesRequest): RetrofitCall + fun upsertPushPreferences(@Body body: UpsertPushPreferencesRequest): RetrofitCall } 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 f769ce0eda9..6cd65bbb8d7 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 @@ -129,8 +129,11 @@ import io.getstream.chat.android.models.querysort.QuerySorter import io.getstream.chat.android.models.querysort.SortDirection import io.getstream.chat.android.network.models.AppResponseFields import io.getstream.chat.android.network.models.BlockUsersResponse +import io.getstream.chat.android.network.models.ChannelPushPreferencesResponse +import io.getstream.chat.android.network.models.ChatPreferencesResponse import io.getstream.chat.android.network.models.DeviceResponse import io.getstream.chat.android.network.models.GetApplicationResponse +import io.getstream.chat.android.network.models.PushPreferencesResponse import io.getstream.chat.android.network.models.UnreadCountsChannel import io.getstream.chat.android.network.models.UnreadCountsChannelType import io.getstream.chat.android.network.models.UnreadCountsThread @@ -941,6 +944,28 @@ internal class DomainMapping( defaultPreference = ChatPreferenceToggle.fromValue(default_preference), ) + internal fun PushPreferencesResponse.toDomain(): PushPreference = PushPreference( + level = PushPreferenceLevel.fromValue(chatLevel), + disabledUntil = disabledUntil, + chatPreferences = chatPreferences?.toDomain(), + ) + + internal fun ChannelPushPreferencesResponse.toDomain(): PushPreference = PushPreference( + level = PushPreferenceLevel.fromValue(chatLevel), + disabledUntil = disabledUntil, + chatPreferences = null, + ) + + internal fun ChatPreferencesResponse.toDomain(): ChatPreferences = ChatPreferences( + directMentions = ChatPreferenceToggle.fromValue(directMentions), + roleMentions = ChatPreferenceToggle.fromValue(roleMentions), + groupMentions = ChatPreferenceToggle.fromValue(groupMentions), + hereMentions = ChatPreferenceToggle.fromValue(hereMentions), + channelMentions = ChatPreferenceToggle.fromValue(channelMentions), + threadReplies = ChatPreferenceToggle.fromValue(threadReplies), + defaultPreference = ChatPreferenceToggle.fromValue(defaultPreference), + ) + internal fun List>?.toSortDomain(): QuerySorter? { if (isNullOrEmpty()) return null return fold(QuerySortByField()) { sort, sortSpecMap -> diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/response/PushPreferencesResponse.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/response/PushPreferencesResponse.kt deleted file mode 100644 index 9a1639059d4..00000000000 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/response/PushPreferencesResponse.kt +++ /dev/null @@ -1,51 +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.response - -import com.squareup.moshi.JsonClass -import io.getstream.chat.android.client.api2.model.dto.DownstreamPushPreferenceDto - -/** - * Response DTO for upserting push notification preferences. - * - * @param user_channel_preferences Map of userId to a map of channelId to their respective channel push preferences. - * @param user_preferences Map of userId to their overall push preferences. - */ -@JsonClass(generateAdapter = true) -internal data class PushPreferencesResponse( - val user_channel_preferences: Map>, - val user_preferences: Map, -) - -/** - * Extension function to get a user's overall push preference from the [PushPreferencesResponse]. - * - * @param userId The ID of the user whose preference is to be retrieved. - */ -internal fun PushPreferencesResponse.getUserPreference(userId: String): DownstreamPushPreferenceDto? = - user_preferences[userId] - -/** - * Extension function to get a user's channel-specific push preference from the [PushPreferencesResponse]. - * - * @param userId The ID of the user whose channel preference is to be retrieved. - * @param cid The channel ID (in the format "type:id") for which the preference is to be retrieved. - */ -internal fun PushPreferencesResponse.getUserChannelPreference( - userId: String, - cid: String, -): DownstreamPushPreferenceDto? = user_channel_preferences[userId]?.get(cid) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ChannelPushPreferencesResponse.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ChannelPushPreferencesResponse.kt new file mode 100644 index 00000000000..b6fc8810885 --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ChannelPushPreferencesResponse.kt @@ -0,0 +1,39 @@ +/* + * 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. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.Json + +/** + * + */ + +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class ChannelPushPreferencesResponse( + @Json(name = "chat_level") + val chatLevel: kotlin.String? = null, + + @Json(name = "disabled_until") + val disabledUntil: java.util.Date? = null, +) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ChatPreferencesResponse.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ChatPreferencesResponse.kt new file mode 100644 index 00000000000..005defc0584 --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ChatPreferencesResponse.kt @@ -0,0 +1,54 @@ +/* + * 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. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.Json + +/** + * + */ + +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class ChatPreferencesResponse( + @Json(name = "channel_mentions") + val channelMentions: kotlin.String? = null, + + @Json(name = "default_preference") + val defaultPreference: kotlin.String? = null, + + @Json(name = "direct_mentions") + val directMentions: kotlin.String? = null, + + @Json(name = "group_mentions") + val groupMentions: kotlin.String? = null, + + @Json(name = "here_mentions") + val hereMentions: kotlin.String? = null, + + @Json(name = "role_mentions") + val roleMentions: kotlin.String? = null, + + @Json(name = "thread_replies") + val threadReplies: kotlin.String? = null, +) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/FeedsPreferencesResponse.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/FeedsPreferencesResponse.kt new file mode 100644 index 00000000000..01bdd0e7beb --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/FeedsPreferencesResponse.kt @@ -0,0 +1,58 @@ +/* + * 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. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.Json +import kotlin.collections.Map + +/** + * + */ + +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class FeedsPreferencesResponse( + @Json(name = "comment") + val comment: kotlin.String? = null, + + @Json(name = "comment_mention") + val commentMention: kotlin.String? = null, + + @Json(name = "comment_reaction") + val commentReaction: kotlin.String? = null, + + @Json(name = "comment_reply") + val commentReply: kotlin.String? = null, + + @Json(name = "follow") + val follow: kotlin.String? = null, + + @Json(name = "mention") + val mention: kotlin.String? = null, + + @Json(name = "reaction") + val reaction: kotlin.String? = null, + + @Json(name = "custom_activity_types") + val customActivityTypes: kotlin.collections.Map? = emptyMap(), +) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/PushPreferencesResponse.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/PushPreferencesResponse.kt new file mode 100644 index 00000000000..0d5b19519c6 --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/PushPreferencesResponse.kt @@ -0,0 +1,51 @@ +/* + * 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. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.Json + +/** + * + */ + +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class PushPreferencesResponse( + @Json(name = "call_level") + val callLevel: kotlin.String? = null, + + @Json(name = "chat_level") + val chatLevel: kotlin.String? = null, + + @Json(name = "disabled_until") + val disabledUntil: java.util.Date? = null, + + @Json(name = "feeds_level") + val feedsLevel: kotlin.String? = null, + + @Json(name = "chat_preferences") + val chatPreferences: io.getstream.chat.android.network.models.ChatPreferencesResponse? = null, + + @Json(name = "feeds_preferences") + val feedsPreferences: io.getstream.chat.android.network.models.FeedsPreferencesResponse? = null, +) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/UpsertPushPreferencesResponse.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/UpsertPushPreferencesResponse.kt new file mode 100644 index 00000000000..7a224059a82 --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/UpsertPushPreferencesResponse.kt @@ -0,0 +1,43 @@ +/* + * 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. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.Json +import kotlin.collections.Map + +/** + * + */ + +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class UpsertPushPreferencesResponse( + @Json(name = "duration") + val duration: kotlin.String, + + @Json(name = "user_channel_preferences") + val userChannelPreferences: kotlin.collections.Map> = emptyMap(), + + @Json(name = "user_preferences") + val userPreferences: kotlin.collections.Map = emptyMap(), +) diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTest.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTest.kt index aacee4f8a2d..b499bd717d1 100644 --- a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTest.kt +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTest.kt @@ -39,9 +39,7 @@ import io.getstream.chat.android.client.api2.mapping.DomainMapping import io.getstream.chat.android.client.api2.mapping.DtoMapping import io.getstream.chat.android.client.api2.mapping.EventMapping import io.getstream.chat.android.client.api2.model.dto.AttachmentDto -import io.getstream.chat.android.client.api2.model.dto.DownstreamChatPreferencesDto import io.getstream.chat.android.client.api2.model.dto.DownstreamLocationDto -import io.getstream.chat.android.client.api2.model.dto.DownstreamPushPreferenceDto import io.getstream.chat.android.client.api2.model.dto.UpstreamChatPreferencesDto import io.getstream.chat.android.client.api2.model.dto.UpstreamPushPreferenceInputDto import io.getstream.chat.android.client.api2.model.requests.AcceptInviteRequest @@ -66,7 +64,6 @@ import io.getstream.chat.android.client.api2.model.response.ParsedPredefinedFilt import io.getstream.chat.android.client.api2.model.response.PollOptionResponse import io.getstream.chat.android.client.api2.model.response.PollResponse import io.getstream.chat.android.client.api2.model.response.PollVoteResponse -import io.getstream.chat.android.client.api2.model.response.PushPreferencesResponse import io.getstream.chat.android.client.api2.model.response.QueryBannedUsersResponse import io.getstream.chat.android.client.api2.model.response.QueryBlockedUsersResponse import io.getstream.chat.android.client.api2.model.response.QueryChannelsResponse @@ -132,6 +129,8 @@ import io.getstream.chat.android.network.models.AddUserGroupMembersResponse import io.getstream.chat.android.network.models.BlockUsersRequest import io.getstream.chat.android.network.models.BlockUsersResponse import io.getstream.chat.android.network.models.CastPollVoteRequest +import io.getstream.chat.android.network.models.ChannelPushPreferencesResponse +import io.getstream.chat.android.network.models.ChatPreferencesResponse import io.getstream.chat.android.network.models.CreateDeviceRequest import io.getstream.chat.android.network.models.CreateGuestRequest import io.getstream.chat.android.network.models.CreatePollOptionRequest @@ -155,6 +154,7 @@ import io.getstream.chat.android.network.models.MessageActionRequest import io.getstream.chat.android.network.models.MuteChannelRequest import io.getstream.chat.android.network.models.PollOptionInput import io.getstream.chat.android.network.models.PollOptionRequest +import io.getstream.chat.android.network.models.PushPreferencesResponse import io.getstream.chat.android.network.models.QueryDraftsRequest import io.getstream.chat.android.network.models.QueryPollVotesRequest import io.getstream.chat.android.network.models.QueryPollsRequest @@ -180,6 +180,7 @@ import io.getstream.chat.android.network.models.UpdateUserGroupRequest import io.getstream.chat.android.network.models.UpdateUserGroupResponse import io.getstream.chat.android.network.models.UpdateUserPartialRequest import io.getstream.chat.android.network.models.UpdateUsersPartialRequest +import io.getstream.chat.android.network.models.UpsertPushPreferencesResponse import io.getstream.chat.android.network.models.UserRequest import io.getstream.chat.android.network.models.VoteData import io.getstream.chat.android.network.models.WrappedUnreadCountsResponse @@ -2933,9 +2934,10 @@ internal class MoshiChatApiTest { // given val userId = randomString() val level = PushPreferenceLevel.all - val response = PushPreferencesResponse( - user_channel_preferences = emptyMap(), - user_preferences = mapOf(userId to DownstreamPushPreferenceDto(level.value, null)), + val response = UpsertPushPreferencesResponse( + duration = randomString(), + userChannelPreferences = emptyMap(), + userPreferences = mapOf(userId to PushPreferencesResponse(chatLevel = level.value, disabledUntil = null)), ) val call = RetroSuccess(response).toRetrofitCall() val api = mock() @@ -2966,9 +2968,10 @@ internal class MoshiChatApiTest { // given val userId = randomString() val until = randomDate() - val response = PushPreferencesResponse( - user_channel_preferences = emptyMap(), - user_preferences = mapOf(userId to DownstreamPushPreferenceDto(null, until)), + val response = UpsertPushPreferencesResponse( + duration = randomString(), + userChannelPreferences = emptyMap(), + userPreferences = mapOf(userId to PushPreferencesResponse(chatLevel = null, disabledUntil = until)), ) val call = RetroSuccess(response).toRetrofitCall() val api = mock() @@ -3000,9 +3003,12 @@ internal class MoshiChatApiTest { val userId = randomString() val cid = randomCID() val level = PushPreferenceLevel.mentions - val response = PushPreferencesResponse( - user_channel_preferences = mapOf(userId to mapOf(cid to DownstreamPushPreferenceDto(level.value, null))), - user_preferences = emptyMap(), + val response = UpsertPushPreferencesResponse( + duration = randomString(), + userChannelPreferences = mapOf( + userId to mapOf(cid to ChannelPushPreferencesResponse(chatLevel = level.value, disabledUntil = null)), + ), + userPreferences = emptyMap(), ) val call = RetroSuccess(response).toRetrofitCall() val api = mock() @@ -3034,9 +3040,12 @@ internal class MoshiChatApiTest { val userId = randomString() val cid = randomCID() val until = randomDate() - val response = PushPreferencesResponse( - user_channel_preferences = mapOf(userId to mapOf(cid to DownstreamPushPreferenceDto(null, until))), - user_preferences = emptyMap(), + val response = UpsertPushPreferencesResponse( + duration = randomString(), + userChannelPreferences = mapOf( + userId to mapOf(cid to ChannelPushPreferencesResponse(chatLevel = null, disabledUntil = until)), + ), + userPreferences = emptyMap(), ) val call = RetroSuccess(response).toRetrofitCall() val api = mock() @@ -3070,16 +3079,17 @@ internal class MoshiChatApiTest { channelMentions = ChatPreferenceToggle.none, defaultPreference = ChatPreferenceToggle.none, ) - val response = PushPreferencesResponse( - user_channel_preferences = emptyMap(), - user_preferences = mapOf( - userId to DownstreamPushPreferenceDto( - chat_level = null, - disabled_until = null, - chat_preferences = DownstreamChatPreferencesDto( - direct_mentions = "all", - channel_mentions = "none", - default_preference = "none", + val response = UpsertPushPreferencesResponse( + duration = randomString(), + userChannelPreferences = emptyMap(), + userPreferences = mapOf( + userId to PushPreferencesResponse( + chatLevel = null, + disabledUntil = null, + chatPreferences = ChatPreferencesResponse( + directMentions = "all", + channelMentions = "none", + defaultPreference = "none", ), ), ), @@ -3114,17 +3124,17 @@ internal class MoshiChatApiTest { val userId = randomString() val cid = randomCID() val prefs = ChatPreferences(directMentions = ChatPreferenceToggle.all) - val response = PushPreferencesResponse( - user_channel_preferences = mapOf( + val response = UpsertPushPreferencesResponse( + duration = randomString(), + userChannelPreferences = mapOf( userId to mapOf( - cid to DownstreamPushPreferenceDto( - chat_level = null, - disabled_until = null, - chat_preferences = DownstreamChatPreferencesDto(direct_mentions = "all"), + cid to ChannelPushPreferencesResponse( + chatLevel = null, + disabledUntil = null, ), ), ), - user_preferences = emptyMap(), + userPreferences = emptyMap(), ) val api = mock() whenever(api.upsertPushPreferences(any())).doReturn(RetroSuccess(response).toRetrofitCall()) diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/model/response/PushPreferencesResponseTest.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/model/response/PushPreferencesResponseTest.kt deleted file mode 100644 index 60306005586..00000000000 --- a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/model/response/PushPreferencesResponseTest.kt +++ /dev/null @@ -1,243 +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.response - -import io.getstream.chat.android.client.Mother -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertNull -import org.junit.jupiter.api.Test -import java.util.Date - -internal class PushPreferencesResponseTest { - - @Test - fun `getUserPreference should return user preference when user exists`() { - // Given - val userId = "user123" - val pushPreference = Mother.randomDownstreamPushPreferenceDto( - chatLevel = "all", - disabledUntil = Date(), - ) - val response = PushPreferencesResponse( - user_channel_preferences = emptyMap(), - user_preferences = mapOf(userId to pushPreference), - ) - - // When - val result = response.getUserPreference(userId) - - // Then - assertEquals(pushPreference, result) - } - - @Test - fun `getUserPreference should return null when user does not exist`() { - // Given - val userId = "nonexistent_user" - val response = PushPreferencesResponse( - user_channel_preferences = emptyMap(), - user_preferences = mapOf("other_user" to Mother.randomDownstreamPushPreferenceDto()), - ) - - // When - val result = response.getUserPreference(userId) - - // Then - assertNull(result) - } - - @Test - fun `getUserPreference should return null when user preference is explicitly null`() { - // Given - val userId = "user123" - val response = PushPreferencesResponse( - user_channel_preferences = emptyMap(), - user_preferences = mapOf(userId to null), - ) - - // When - val result = response.getUserPreference(userId) - - // Then - assertNull(result) - } - - @Test - fun `getUserPreference should return null when user_preferences map is empty`() { - // Given - val userId = "user123" - val response = PushPreferencesResponse( - user_channel_preferences = emptyMap(), - user_preferences = emptyMap(), - ) - - // When - val result = response.getUserPreference(userId) - - // Then - assertNull(result) - } - - @Test - fun `getUserChannelPreference should return channel preference when user and channel exist`() { - // Given - val userId = "user123" - val channelId = "messaging:channel456" - val pushPreference = Mother.randomDownstreamPushPreferenceDto( - chatLevel = "mentions", - disabledUntil = null, - ) - val response = PushPreferencesResponse( - user_channel_preferences = mapOf( - userId to mapOf(channelId to pushPreference), - ), - user_preferences = emptyMap(), - ) - - // When - val result = response.getUserChannelPreference(userId, channelId) - - // Then - assertEquals(pushPreference, result) - } - - @Test - fun `getUserChannelPreference should return null when user does not exist`() { - // Given - val userId = "nonexistent_user" - val channelId = "messaging:channel456" - val response = PushPreferencesResponse( - user_channel_preferences = mapOf( - "other_user" to mapOf(channelId to Mother.randomDownstreamPushPreferenceDto()), - ), - user_preferences = emptyMap(), - ) - - // When - val result = response.getUserChannelPreference(userId, channelId) - - // Then - assertNull(result) - } - - @Test - fun `getUserChannelPreference should return null when user exists but channel does not exist`() { - // Given - val userId = "user123" - val channelId = "messaging:nonexistent_channel" - val response = PushPreferencesResponse( - user_channel_preferences = mapOf( - userId to mapOf("messaging:other_channel" to Mother.randomDownstreamPushPreferenceDto()), - ), - user_preferences = emptyMap(), - ) - - // When - val result = response.getUserChannelPreference(userId, channelId) - - // Then - assertNull(result) - } - - @Test - fun `getUserChannelPreference should return null when user has empty channel preferences`() { - // Given - val userId = "user123" - val channelId = "messaging:channel456" - val response = PushPreferencesResponse( - user_channel_preferences = mapOf(userId to emptyMap()), - user_preferences = emptyMap(), - ) - - // When - val result = response.getUserChannelPreference(userId, channelId) - - // Then - assertNull(result) - } - - @Test - fun `getUserChannelPreference should return null when user_channel_preferences map is empty`() { - // Given - val userId = "user123" - val channelId = "messaging:channel456" - val response = PushPreferencesResponse( - user_channel_preferences = emptyMap(), - user_preferences = emptyMap(), - ) - - // When - val result = response.getUserChannelPreference(userId, channelId) - - // Then - assertNull(result) - } - - @Test - fun `getUserChannelPreference should handle multiple users and channels correctly`() { - // Given - val user1 = "user1" - val user2 = "user2" - val channel1 = "messaging:channel1" - val channel2 = "messaging:channel2" - val preference1 = Mother.randomDownstreamPushPreferenceDto(chatLevel = "all") - val preference2 = Mother.randomDownstreamPushPreferenceDto(chatLevel = "mentions") - val preference3 = Mother.randomDownstreamPushPreferenceDto(chatLevel = "none") - - val response = PushPreferencesResponse( - user_channel_preferences = mapOf( - user1 to mapOf( - channel1 to preference1, - channel2 to preference2, - ), - user2 to mapOf( - channel1 to preference3, - ), - ), - user_preferences = emptyMap(), - ) - - // When & Then - assertEquals(preference1, response.getUserChannelPreference(user1, channel1)) - assertEquals(preference2, response.getUserChannelPreference(user1, channel2)) - assertEquals(preference3, response.getUserChannelPreference(user2, channel1)) - assertNull(response.getUserChannelPreference(user2, channel2)) - assertNull(response.getUserChannelPreference("user3", channel1)) - } - - @Test - fun `getUserPreference should handle multiple users correctly`() { - // Given - val user1 = "user1" - val user2 = "user2" - val preference1 = Mother.randomDownstreamPushPreferenceDto(chatLevel = "all") - val preference2 = Mother.randomDownstreamPushPreferenceDto(chatLevel = "mentions") - - val response = PushPreferencesResponse( - user_channel_preferences = emptyMap(), - user_preferences = mapOf( - user1 to preference1, - user2 to preference2, - ), - ) - - // When & Then - assertEquals(preference1, response.getUserPreference(user1)) - assertEquals(preference2, response.getUserPreference(user2)) - assertNull(response.getUserPreference("user3")) - } -}