Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import io.getstream.chat.android.client.api.QueryParams
import io.getstream.chat.android.client.api2.UrlQueryPayload
import io.getstream.chat.android.client.api2.model.dto.DownstreamLocationDto
import io.getstream.chat.android.client.api2.model.response.LiveLocationsResponse
import io.getstream.chat.android.client.api2.model.response.QueryBlockedUsersResponse
import io.getstream.chat.android.client.api2.model.response.UpdateUsersResponse
import io.getstream.chat.android.client.api2.model.response.UsersResponse
import io.getstream.chat.android.client.call.RetrofitCall
import io.getstream.chat.android.network.models.BlockUsersRequest
import io.getstream.chat.android.network.models.BlockUsersResponse
import io.getstream.chat.android.network.models.GetBlockedUsersResponse
import io.getstream.chat.android.network.models.QueryUsersPayload
import io.getstream.chat.android.network.models.UnblockUsersRequest
import io.getstream.chat.android.network.models.UnblockUsersResponse
Expand Down Expand Up @@ -57,7 +57,7 @@ internal interface UserApi {
fun unblockUser(@Body body: UnblockUsersRequest): RetrofitCall<UnblockUsersResponse>

@GET("/users/block")
fun queryBlockedUsers(): RetrofitCall<QueryBlockedUsersResponse>
fun queryBlockedUsers(): RetrofitCall<GetBlockedUsersResponse>

@PATCH("/users")
@JvmSuppressWildcards // See issue: https://github.com/square/retrofit/issues/3275
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ import io.getstream.chat.android.client.api2.model.dto.DownstreamReminderDto
import io.getstream.chat.android.client.api2.model.dto.DownstreamReminderInfoDto
import io.getstream.chat.android.client.api2.model.dto.DownstreamThreadDto
import io.getstream.chat.android.client.api2.model.dto.DownstreamThreadInfoDto
import io.getstream.chat.android.client.api2.model.dto.DownstreamUserBlockDto
import io.getstream.chat.android.client.api2.model.dto.DownstreamUserDto
import io.getstream.chat.android.client.api2.model.dto.DownstreamUserGroupDto
import io.getstream.chat.android.client.api2.model.dto.DownstreamUserGroupMemberDto
Expand Down Expand Up @@ -130,6 +129,7 @@ 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.BlockedUserResponse
import io.getstream.chat.android.network.models.ChannelPushPreferencesResponse
import io.getstream.chat.android.network.models.ChatPreferencesResponse
import io.getstream.chat.android.network.models.DeviceResponse
Expand Down Expand Up @@ -902,18 +902,18 @@ internal class DomainMapping(
)

/**
* Transforms [DownstreamUserBlockDto] into [UserBlock]
* Transforms [BlockedUserResponse] into [UserBlock]
*/
internal fun DownstreamUserBlockDto.toDomain(): UserBlock = UserBlock(
blockedBy = user_id,
userId = blocked_user_id,
blockedAt = created_at,
internal fun BlockedUserResponse.toDomain(): UserBlock = UserBlock(
blockedBy = userId,
userId = blockedUserId,
blockedAt = createdAt,
)

/**
* Transforms a list of [DownstreamUserBlockDto] into a list of [UserBlock]
* Transforms a list of [BlockedUserResponse] into a list of [UserBlock]
*/
internal fun List<DownstreamUserBlockDto>.toDomain(): List<UserBlock> = map { it.toDomain() }
internal fun List<BlockedUserResponse>.toDomain(): List<UserBlock> = map { it.toDomain() }

/**
* Transforms [BlockUsersResponse] into [UserBlock].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,3 @@ internal data class DownstreamUserDto(
val push_preferences: DownstreamPushPreferenceDto?,
val extraData: Map<String, Any>,
) : ExtraDataDto

@JsonClass(generateAdapter = true)
internal data class DownstreamUserBlockDto(
val user_id: String,
val blocked_user_id: String,
val created_at: Date,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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 BlockedUserResponse(
@Json(name = "blocked_user_id")
internal val blockedUserId: String,

@Json(name = "created_at")
internal val createdAt: java.util.Date,

@Json(name = "user_id")
internal val userId: String,

@Json(name = "blocked_user")
internal val blockedUser: io.getstream.chat.android.network.models.UserResponse,
Comment thread
andremion marked this conversation as resolved.

@Json(name = "user")
internal val user: io.getstream.chat.android.network.models.UserResponse,
)
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,25 @@
* limitations under the License.
*/

package io.getstream.chat.android.client.api2.model.response
@file:Suppress(
"ArrayInDataClass",
"EnumEntryName",
"RemoveRedundantQualifierName",
"UnusedImport",
)

package io.getstream.chat.android.network.models

import com.squareup.moshi.Json

import com.squareup.moshi.JsonClass
import io.getstream.chat.android.client.api2.model.dto.DownstreamUserBlockDto
/**
*
*/
@com.squareup.moshi.JsonClass(generateAdapter = true)
internal data class GetBlockedUsersResponse(
@Json(name = "duration")
internal val duration: String,

@JsonClass(generateAdapter = true)
internal data class QueryBlockedUsersResponse(
val blocks: List<DownstreamUserBlockDto>,
@Json(name = "blocks")
internal val blocks: List<io.getstream.chat.android.network.models.BlockedUserResponse> = emptyList(),
)
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ import io.getstream.chat.android.client.api2.model.dto.DownstreamReactionGroupDt
import io.getstream.chat.android.client.api2.model.dto.DownstreamReminderDto
import io.getstream.chat.android.client.api2.model.dto.DownstreamThreadDto
import io.getstream.chat.android.client.api2.model.dto.DownstreamThreadInfoDto
import io.getstream.chat.android.client.api2.model.dto.DownstreamUserBlockDto
import io.getstream.chat.android.client.api2.model.dto.DownstreamUserDto
import io.getstream.chat.android.client.api2.model.dto.DownstreamUserGroupDto
import io.getstream.chat.android.client.api2.model.dto.DownstreamUserGroupMemberDto
Expand Down Expand Up @@ -92,6 +91,7 @@ import io.getstream.chat.android.models.querysort.QuerySortByField
import io.getstream.chat.android.models.querysort.QuerySorter
import io.getstream.chat.android.network.models.AppResponseFields
import io.getstream.chat.android.network.models.BlockUsersResponse
import io.getstream.chat.android.network.models.BlockedUserResponse
import io.getstream.chat.android.network.models.CreateGuestResponse
import io.getstream.chat.android.network.models.DeviceResponse
import io.getstream.chat.android.network.models.FileUploadConfig
Expand Down Expand Up @@ -1114,14 +1114,16 @@ internal object Mother {
extraData = extraData,
)

fun randomDownstreamUserBlockDto(
fun randomBlockedUserResponse(
userId: String = randomString(),
blockedUserId: String = randomString(),
createdAt: Date = randomDate(),
): DownstreamUserBlockDto = DownstreamUserBlockDto(
user_id = userId,
blocked_user_id = blockedUserId,
created_at = createdAt,
): BlockedUserResponse = BlockedUserResponse(
userId = userId,
blockedUserId = blockedUserId,
createdAt = createdAt,
blockedUser = randomUserResponse(id = blockedUserId),
user = randomUserResponse(id = userId),
)

fun randomBlockUsersResponse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ import io.getstream.chat.android.client.api2.model.response.ParsedPredefinedFilt
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.QueryBannedUsersResponse
import io.getstream.chat.android.client.api2.model.response.QueryBlockedUsersResponse
import io.getstream.chat.android.client.api2.model.response.QueryChannelsResponse
import io.getstream.chat.android.client.api2.model.response.QueryDraftMessagesResponse
import io.getstream.chat.android.client.api2.model.response.QueryGroupedChannelsGroup
Expand Down Expand Up @@ -138,6 +137,7 @@ import io.getstream.chat.android.network.models.CreateUserGroupResponse
import io.getstream.chat.android.network.models.DeliveredMessagePayload
import io.getstream.chat.android.network.models.EventRequest
import io.getstream.chat.android.network.models.GetApplicationResponse
import io.getstream.chat.android.network.models.GetBlockedUsersResponse
import io.getstream.chat.android.network.models.GetUserGroupResponse
import io.getstream.chat.android.network.models.GroupedChannelsGroupRequest
import io.getstream.chat.android.network.models.GroupedQueryChannelsRequest
Expand Down Expand Up @@ -1836,7 +1836,7 @@ internal class MoshiChatApiTest {

@ParameterizedTest
@MethodSource("io.getstream.chat.android.client.api2.MoshiChatApiTestArguments#queryBlockedUsersInput")
fun testQueryBlockedUsers(call: RetrofitCall<QueryBlockedUsersResponse>, expected: KClass<*>) = runTest {
fun testQueryBlockedUsers(call: RetrofitCall<GetBlockedUsersResponse>, expected: KClass<*>) = runTest {
// given
val api = mock<UserApi>()
whenever(api.queryBlockedUsers()).doReturn(call)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ import io.getstream.chat.android.client.api2.model.response.ParsedPredefinedFilt
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.QueryBannedUsersResponse
import io.getstream.chat.android.client.api2.model.response.QueryBlockedUsersResponse
import io.getstream.chat.android.client.api2.model.response.QueryChannelsResponse
import io.getstream.chat.android.client.api2.model.response.QueryDraftMessagesResponse
import io.getstream.chat.android.client.api2.model.response.QueryGroupedChannelsGroup
Expand Down Expand Up @@ -74,6 +73,7 @@ import io.getstream.chat.android.network.models.BlockUsersResponse
import io.getstream.chat.android.network.models.CreateGuestResponse
import io.getstream.chat.android.network.models.CreateUserGroupResponse
import io.getstream.chat.android.network.models.GetApplicationResponse
import io.getstream.chat.android.network.models.GetBlockedUsersResponse
import io.getstream.chat.android.network.models.GetUserGroupResponse
import io.getstream.chat.android.network.models.ListDevicesResponse
import io.getstream.chat.android.network.models.ListUserGroupsResponse
Expand Down Expand Up @@ -406,11 +406,13 @@ internal object MoshiChatApiTestArguments {
@JvmStatic
fun queryBlockedUsersInput() = listOf(
Arguments.of(
RetroSuccess(QueryBlockedUsersResponse(listOf(Mother.randomDownstreamUserBlockDto()))).toRetrofitCall(),
RetroSuccess(
GetBlockedUsersResponse(duration = "1ms", blocks = listOf(Mother.randomBlockedUserResponse())),
).toRetrofitCall(),
Result.Success::class,
),
Arguments.of(
RetroError<QueryBlockedUsersResponse>(statusCode = 500).toRetrofitCall(),
RetroError<GetBlockedUsersResponse>(statusCode = 500).toRetrofitCall(),
Result.Failure::class,
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import io.getstream.chat.android.client.Mother.randomAppSettingsResponse
import io.getstream.chat.android.client.Mother.randomAttachmentDto
import io.getstream.chat.android.client.Mother.randomBannedUserResponse
import io.getstream.chat.android.client.Mother.randomBlockUsersResponse
import io.getstream.chat.android.client.Mother.randomBlockedUserResponse
import io.getstream.chat.android.client.Mother.randomChannelInfoDto
import io.getstream.chat.android.client.Mother.randomCommandDto
import io.getstream.chat.android.client.Mother.randomConfigDto
Expand All @@ -48,7 +49,6 @@ import io.getstream.chat.android.client.Mother.randomDownstreamReactionGroupDto
import io.getstream.chat.android.client.Mother.randomDownstreamReminderDto
import io.getstream.chat.android.client.Mother.randomDownstreamThreadDto
import io.getstream.chat.android.client.Mother.randomDownstreamThreadInfoDto
import io.getstream.chat.android.client.Mother.randomDownstreamUserBlockDto
import io.getstream.chat.android.client.Mother.randomDownstreamUserDto
import io.getstream.chat.android.client.Mother.randomDownstreamUserGroupDto
import io.getstream.chat.android.client.Mother.randomDownstreamVoteDto
Expand Down Expand Up @@ -1007,19 +1007,21 @@ internal class DomainMappingTest {
}

@Test
fun `DownstreamUserBlockDto is correctly mapped to UserBlock`() {
val downstreamUserBlockDto = randomDownstreamUserBlockDto()
val downstreamBlocklist = listOf(downstreamUserBlockDto)
fun `BlockedUserResponse is correctly mapped to UserBlock`() {
val blockedAt = Date(1000)
val response = randomBlockedUserResponse(
userId = "blocker-1",
blockedUserId = "blocked-1",
createdAt = blockedAt,
)
val sut = Fixture().get()
val blocklist = with(sut) { downstreamBlocklist.toDomain() }
val expected = listOf(
UserBlock(
blockedBy = downstreamUserBlockDto.user_id,
userId = downstreamUserBlockDto.blocked_user_id,
blockedAt = downstreamUserBlockDto.created_at,
),

val blocklist = with(sut) { listOf(response).toDomain() }

assertEquals(
listOf(UserBlock(blockedBy = "blocker-1", userId = "blocked-1", blockedAt = blockedAt)),
blocklist,
)
assertEquals(expected, blocklist)
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* 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.api2.mapping.DomainMapping
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.models.UserBlock
import io.getstream.chat.android.network.models.GetBlockedUsersResponse
import org.intellij.lang.annotations.Language
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import java.util.Date

internal class BlockedUsersParsingTest {

private val parser = ParserFactory.createMoshiChatParser()

private val domainMapping = DomainMapping(
currentUserIdProvider = { "" },
channelTransformer = NoOpChannelTransformer,
messageTransformer = NoOpMessageTransformer,
userTransformer = NoOpUserTransformer,
)

// Each block carries two full UserResponse objects; this locks that the generated UserResponse
// (with its required non-null `language`) parses from the real wire shape.
@Language("JSON")
private val json =
"""{
"duration": "1ms",
"blocks": [
{
"user_id": "blocker-1",
"blocked_user_id": "blocked-1",
"created_at": "1970-01-01T00:00:01.000Z",
"user": {
"id": "blocker-1", "role": "user", "language": "en", "banned": false,
"online": true, "created_at": "2020-01-01T00:00:00.000Z",
"updated_at": "2020-01-01T00:00:00.000Z", "birthland": "Polis Massa"
},
"blocked_user": {
"id": "blocked-1", "role": "user", "language": "", "banned": true,
"online": false, "created_at": "2020-01-01T00:00:00.000Z",
"updated_at": "2020-01-01T00:00:00.000Z"
}
}
]
}"""

@Test
fun `deserializes the blocked-users wire shape and maps it to UserBlock`() {
val dto = parser.fromJson(json, GetBlockedUsersResponse::class.java)

assertEquals("1ms", dto.duration)
val block = dto.blocks.single()
assertEquals("blocker-1", block.user.id)
assertEquals("blocked-1", block.blockedUser.id)
// The adapter collects root-level custom data, and `language` is required non-null but arrives empty.
assertEquals(mapOf("birthland" to "Polis Massa"), block.user.custom)
assertEquals("en", block.user.language)
assertEquals("", block.blockedUser.language)

val blocks = with(domainMapping) { dto.blocks.toDomain() }

assertEquals(
Comment thread
andremion marked this conversation as resolved.
listOf(UserBlock(blockedBy = "blocker-1", userId = "blocked-1", blockedAt = Date(1000))),
blocks,
)
Comment thread
gpunto marked this conversation as resolved.
}
}
Loading