Skip to content

Commit

Permalink
feat(mls-one2one): support fetching mls 1-1 conversation details (#1848)
Browse files Browse the repository at this point in the history
* feat: support fetching mls 1-1 conversation details

* refactor: better naming of function

* chore: remove another magic number
  • Loading branch information
typfel committed Aug 18, 2023
1 parent 0f6a249 commit 24c17a6
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import com.wire.kalium.network.exceptions.APINotSupported
import com.wire.kalium.network.utils.NetworkResponse

interface BaseApi {
fun getApiNotSupportError(apiName: String, apiVersion: Int) = NetworkResponse.Error(
fun getApiNotSupportedError(apiName: String, apiVersion: Int) = NetworkResponse.Error(
APINotSupported("${this::class.simpleName}: $apiName api is only available on API V$apiVersion")
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package com.wire.kalium.network.api.base.authenticated.conversation

import com.wire.kalium.network.api.base.authenticated.BaseApi
import com.wire.kalium.network.api.base.authenticated.conversation.guestroomlink.GenerateGuestRoomLinkResponse
import com.wire.kalium.network.api.base.authenticated.conversation.model.ConversationCodeInfo
import com.wire.kalium.network.api.base.authenticated.conversation.model.ConversationMemberRoleDTO
Expand All @@ -32,7 +33,7 @@ import com.wire.kalium.network.exceptions.APINotSupported
import com.wire.kalium.network.utils.NetworkResponse

@Suppress("TooManyFunctions")
interface ConversationApi {
interface ConversationApi : BaseApi {

/**
* Fetch conversations id's in a paginated fashion, including federated conversations
Expand Down Expand Up @@ -112,6 +113,10 @@ interface ConversationApi {
key: String
): NetworkResponse<ConversationCodeInfo>

suspend fun fetchMlsOneToOneConversation(
userId: UserId
): NetworkResponse<ConversationResponse>

suspend fun fetchSubconversationDetails(
conversationId: ConversationId,
subconversationId: SubconversationId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,38 +267,33 @@ internal open class ConversationApiV0 internal constructor(
}
}

override suspend fun fetchMlsOneToOneConversation(userId: UserId): NetworkResponse<ConversationResponse> =
getApiNotSupportedError(::fetchMlsOneToOneConversation.name, MIN_API_VERSION_MLS)

override suspend fun fetchSubconversationDetails(
conversationId: ConversationId,
subconversationId: SubconversationId
): NetworkResponse<SubconversationResponse> =
NetworkResponse.Error(
APINotSupported("MLS: fetchSubconversationDetails api is only available on API V3")
)
getApiNotSupportedError(::fetchSubconversationDetails.name, MIN_API_VERSION_MLS)

override suspend fun deleteSubconversation(
conversationId: ConversationId,
subconversationId: SubconversationId,
deleteRequest: SubconversationDeleteRequest
): NetworkResponse<Unit> =
NetworkResponse.Error(
APINotSupported("MLS: deleteSubconversation api is only available on API V3")
)
getApiNotSupportedError(::deleteSubconversation.name, MIN_API_VERSION_MLS)

override suspend fun fetchSubconversationGroupInfo(
conversationId: ConversationId,
subconversationId: SubconversationId
): NetworkResponse<ByteArray> =
NetworkResponse.Error(
APINotSupported("MLS: fetchSubconversationGroupInfo api is only available on API V3")
)
getApiNotSupportedError(::fetchSubconversationGroupInfo.name, MIN_API_VERSION_MLS)

override suspend fun leaveSubconversation(
conversationId: ConversationId,
subconversationId: SubconversationId
): NetworkResponse<Unit> =
NetworkResponse.Error(
APINotSupported("MLS: leaveSubconversation api is only available on API V3")
)
getApiNotSupportedError(::leaveSubconversation.name, MIN_API_VERSION_MLS)

protected suspend fun handleConversationMemberAddedResponse(
httpResponse: HttpResponse
Expand Down Expand Up @@ -401,10 +396,8 @@ internal open class ConversationApiV0 internal constructor(
const val PATH_BOTS = "bots"
const val QUERY_KEY_CODE = "code"
const val QUERY_KEY_KEY = "key"
const val QUERY_KEY_START = "start"
const val QUERY_KEY_SIZE = "size"
const val QUERY_KEY_IDS = "qualified_ids"

const val MAX_CONVERSATION_DETAILS_COUNT = 1000
const val MIN_API_VERSION_MLS = 4
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,15 @@ internal open class SelfApiV0 internal constructor(
}
}

@Suppress("MagicNumber")
override suspend fun updateSupportedProtocols(protocols: List<SupportedProtocolDTO>): NetworkResponse<Unit> =
getApiNotSupportError(::updateSupportedProtocols.name, 4)
getApiNotSupportedError(::updateSupportedProtocols.name, MIN_API_VERSION_SUPPORTED_PROTOCOLS)

companion object {
const val PATH_SELF = "self"
const val PATH_HANDLE = "handle"
const val PATH_ACCESS = "access"
const val PATH_EMAIL = "email"

const val MIN_API_VERSION_SUPPORTED_PROTOCOLS = 4
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.wire.kalium.network.AuthenticatedNetworkClient
import com.wire.kalium.network.api.base.authenticated.conversation.AddConversationMembersRequest
import com.wire.kalium.network.api.base.authenticated.conversation.ConversationMemberAddedResponse
import com.wire.kalium.network.api.base.authenticated.conversation.ConversationResponseV3
import com.wire.kalium.network.api.base.authenticated.conversation.ConversationResponse
import com.wire.kalium.network.api.base.authenticated.conversation.ConvProtocol
import com.wire.kalium.network.api.base.authenticated.conversation.UpdateConversationProtocolRequest
import com.wire.kalium.network.api.base.authenticated.conversation.UpdateConversationProtocolResponse
Expand All @@ -36,6 +37,7 @@ import com.wire.kalium.network.api.base.model.ConversationId
import com.wire.kalium.network.api.base.model.JoinConversationRequestV4
import com.wire.kalium.network.api.base.model.QualifiedID
import com.wire.kalium.network.api.base.model.SubconversationId
import com.wire.kalium.network.api.base.model.UserId
import com.wire.kalium.network.api.v3.authenticated.ConversationApiV3
import com.wire.kalium.network.exceptions.KaliumException
import com.wire.kalium.network.utils.NetworkResponse
Expand Down Expand Up @@ -158,6 +160,7 @@ internal open class ConversationApiV4 internal constructor(
NetworkResponse.Error(KaliumException.GenericError(e))
}


override suspend fun updateProtocol(
conversationId: ConversationId,
protocol: ConvProtocol
Expand All @@ -181,9 +184,15 @@ internal open class ConversationApiV4 internal constructor(
NetworkResponse.Error(KaliumException.GenericError(e))
}

override suspend fun fetchMlsOneToOneConversation(userId: UserId): NetworkResponse<ConversationResponse> =
wrapKaliumResponse {
httpClient.get("$PATH_CONVERSATIONS/$PATH_ONE_TO_ONE/${userId.domain}/${userId.value}")
}

companion object {
const val PATH_PROTOCOL = "protocol"
const val PATH_GROUP_INFO = "groupinfo"
const val PATH_SUBCONVERSATIONS = "subconversations"
const val PATH_ONE_TO_ONE = "one2one"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,18 @@ import com.wire.kalium.network.api.base.model.ConversationAccessDTO
import com.wire.kalium.network.api.base.model.ConversationAccessRoleDTO
import com.wire.kalium.network.api.base.model.ConversationId
import com.wire.kalium.network.api.base.model.JoinConversationRequestV0
import com.wire.kalium.network.api.base.model.SupportedProtocolDTO
import com.wire.kalium.network.api.base.model.UserId
import com.wire.kalium.network.api.v0.authenticated.ConversationApiV0
import com.wire.kalium.network.api.v0.authenticated.SelfApiV0
import com.wire.kalium.network.utils.NetworkResponse
import com.wire.kalium.network.utils.isSuccessful
import io.ktor.http.HttpStatusCode
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertIs
import kotlin.test.assertTrue

Expand Down Expand Up @@ -417,6 +420,15 @@ internal class ConversationApiV0Test : ApiTest() {
assertIs<NetworkResponse.Success<Unit>>(response)
}

@Test
fun givenRequest_whenFetchingMlsOneToOneConversation_thenRequestShouldFail() = runTest {
val networkClient = mockAuthenticatedNetworkClient(responseBody = "", statusCode = HttpStatusCode.OK)
val conversationApi = ConversationApiV0(networkClient)
val response = conversationApi.fetchMlsOneToOneConversation(UserId("domain", "id"))

assertFalse(response.isSuccessful())
}

private companion object {
const val PATH_CONVERSATIONS = "/conversations"
const val PATH_CONVERSATIONS_LIST_V2 = "/conversations/list/v2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,6 @@ internal class SelfApiV0Test : ApiTest() {
}
}



@Test
fun givenUpdateEmailFailure_whenChangingSelfEmail_thenFailureIsReturned() = runTest {
val networkClient = mockAuthenticatedNetworkClient(
Expand Down Expand Up @@ -135,9 +133,6 @@ internal class SelfApiV0Test : ApiTest() {
assertFalse(response.isSuccessful())
}




private companion object {
const val PATH_SELF = "/self"
val VALID_SELF_RESPONSE = UserDTOJson.valid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
package com.wire.kalium.api.v4

import com.wire.kalium.api.ApiTest
import com.wire.kalium.api.json.model.ErrorResponseJson
import com.wire.kalium.model.EventContentDTOJson
import com.wire.kalium.api.json.model.ErrorResponseJson
import com.wire.kalium.model.conversation.ConversationResponseJson
import com.wire.kalium.model.conversation.CreateConversationRequestJson
import com.wire.kalium.model.conversation.SubconversationDeleteRequestJson
import com.wire.kalium.model.conversation.SubconversationDetailsResponseJson
Expand All @@ -34,17 +35,19 @@ import com.wire.kalium.network.api.base.model.FederationConflictResponse
import com.wire.kalium.network.api.base.model.UserId
import com.wire.kalium.network.api.v4.authenticated.ConversationApiV4
import com.wire.kalium.network.exceptions.KaliumException
import com.wire.kalium.network.utils.NetworkResponse
import com.wire.kalium.network.utils.UnreachableRemoteBackends
import com.wire.kalium.network.utils.NetworkResponse
import com.wire.kalium.network.utils.isSuccessful
import io.ktor.http.HttpStatusCode
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertIs
import kotlin.test.assertTrue

@OptIn(ExperimentalCoroutinesApi::class)
internal class ConversationApiV4Test : ApiTest() {

@Test
Expand Down Expand Up @@ -274,10 +277,34 @@ internal class ConversationApiV4Test : ApiTest() {
)
}

@Test
fun whenCallingFetchMlsOneToOneConversation_thenTheRequestShouldBeConfiguredOK() = runTest {
val networkClient = mockAuthenticatedNetworkClient(
FETCH_CONVERSATION_RESPONSE,
statusCode = HttpStatusCode.OK,
assertion = {
assertGet()
assertPathEqual("$PATH_CONVERSATIONS/one2one/${USER_ID.domain}/${USER_ID.value}")
}
)
val conversationApi = ConversationApiV4(networkClient)
conversationApi.fetchMlsOneToOneConversation(USER_ID)
}

@Test
fun given200Response_whenCallingFetchMlsOneToOneConversation_thenResponseIsParsedCorrectly() = runTest {
val networkClient = mockAuthenticatedNetworkClient(FETCH_CONVERSATION_RESPONSE, statusCode = HttpStatusCode.OK)
val conversationApi = ConversationApiV4(networkClient)

assertTrue(conversationApi.fetchMlsOneToOneConversation(USER_ID).isSuccessful())
}

private companion object {
const val PATH_CONVERSATIONS = "/conversations"
const val PATH_MEMBERS = "members"
const val PATH_PROTOCOL = "protocol"
val USER_ID = UserId("id", "domain")
val CREATE_CONVERSATION_REQUEST = CreateConversationRequestJson.v3
val FETCH_CONVERSATION_RESPONSE = ConversationResponseJson.v0.rawJson
}
}

0 comments on commit 24c17a6

Please sign in to comment.