Merge pull request #5587 from element-hq/feature/bma/robustWellknown
Improve wellknown retrieval API
This commit is contained in:
commit
6326d1fc22
16 changed files with 202 additions and 104 deletions
|
|
@ -1 +1 @@
|
||||||
Subproject commit dac93821a6f9f9ad1494d3c69c115ef0696eb7ce
|
Subproject commit 867d1118e157ba89a4f5462f8d9c13e206f10026
|
||||||
|
|
@ -41,7 +41,7 @@ class DefaultAccountProviderAccessControl(
|
||||||
// Ensure that Element Pro is not required for this account provider
|
// Ensure that Element Pro is not required for this account provider
|
||||||
val wellKnown = wellknownRetriever.getElementWellKnown(
|
val wellKnown = wellknownRetriever.getElementWellKnown(
|
||||||
baseUrl = accountProviderUrl.ensureProtocol(),
|
baseUrl = accountProviderUrl.ensureProtocol(),
|
||||||
)
|
).dataOrNull()
|
||||||
if (wellKnown?.enforceElementPro == true) {
|
if (wellKnown?.enforceElementPro == true) {
|
||||||
throw AccountProviderAccessException.NeedElementProException(
|
throw AccountProviderAccessException.NeedElementProException(
|
||||||
unauthorisedAccountProviderTitle = title,
|
unauthorisedAccountProviderTitle = title,
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ class HomeserverResolver(
|
||||||
wellknownRetriever.getWellKnown(url)
|
wellknownRetriever.getWellKnown(url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val isValid = wellKnown?.isValid().orFalse()
|
val isValid = wellKnown?.dataOrNull()?.isValid().orFalse()
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
// Emit the list as soon as possible
|
// Emit the list as soon as possible
|
||||||
currentList.add(
|
currentList.add(
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ class DefaultWebClientUrlForAuthenticationRetriever(
|
||||||
Timber.w("Temporary account creation flow is only supported on matrix.org")
|
Timber.w("Temporary account creation flow is only supported on matrix.org")
|
||||||
throw AccountCreationNotSupported()
|
throw AccountCreationNotSupported()
|
||||||
}
|
}
|
||||||
val wellknown = wellknownRetriever.getElementWellKnown(homeServerUrl)
|
val wellknown = wellknownRetriever.getElementWellKnown(homeServerUrl).dataOrNull()
|
||||||
?: throw AccountCreationNotSupported()
|
?: throw AccountCreationNotSupported()
|
||||||
val registrationHelperUrl = wellknown.registrationHelperUrl
|
val registrationHelperUrl = wellknown.registrationHelperUrl
|
||||||
return if (registrationHelperUrl != null) {
|
return if (registrationHelperUrl != null) {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import io.element.android.libraries.matrix.test.AN_ACCOUNT_PROVIDER
|
||||||
import io.element.android.libraries.matrix.test.AN_ACCOUNT_PROVIDER_2
|
import io.element.android.libraries.matrix.test.AN_ACCOUNT_PROVIDER_2
|
||||||
import io.element.android.libraries.matrix.test.AN_ACCOUNT_PROVIDER_URL
|
import io.element.android.libraries.matrix.test.AN_ACCOUNT_PROVIDER_URL
|
||||||
import io.element.android.libraries.wellknown.api.ElementWellKnown
|
import io.element.android.libraries.wellknown.api.ElementWellKnown
|
||||||
|
import io.element.android.libraries.wellknown.api.WellknownRetrieverResult
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Assert.assertThrows
|
import org.junit.Assert.assertThrows
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
@ -155,7 +156,13 @@ class DefaultAccountProviderAccessControlTest {
|
||||||
defaultHomeserverListResult = { allowedAccountProviders },
|
defaultHomeserverListResult = { allowedAccountProviders },
|
||||||
),
|
),
|
||||||
wellknownRetriever = FakeWellknownRetriever(
|
wellknownRetriever = FakeWellknownRetriever(
|
||||||
getElementWellKnownResult = { elementWellKnown },
|
getElementWellKnownResult = {
|
||||||
|
if (elementWellKnown == null) {
|
||||||
|
WellknownRetrieverResult.NotFound
|
||||||
|
} else {
|
||||||
|
WellknownRetrieverResult.Success(elementWellKnown)
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import io.element.android.libraries.matrix.test.A_HOMESERVER_URL
|
||||||
import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService
|
import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService
|
||||||
import io.element.android.libraries.wellknown.api.ElementWellKnown
|
import io.element.android.libraries.wellknown.api.ElementWellKnown
|
||||||
import io.element.android.libraries.wellknown.api.WellknownRetriever
|
import io.element.android.libraries.wellknown.api.WellknownRetriever
|
||||||
|
import io.element.android.libraries.wellknown.api.WellknownRetrieverResult
|
||||||
import io.element.android.tests.testutils.WarmUpRule
|
import io.element.android.tests.testutils.WarmUpRule
|
||||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
import io.element.android.tests.testutils.lambda.value
|
import io.element.android.tests.testutils.lambda.value
|
||||||
|
|
@ -114,9 +115,11 @@ class ChangeServerPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - change server element pro required error`() = runTest {
|
fun `present - change server element pro required error`() = runTest {
|
||||||
val getElementWellKnownResult = lambdaRecorder<String, ElementWellKnown> {
|
val getElementWellKnownResult = lambdaRecorder<String, WellknownRetrieverResult<ElementWellKnown>> {
|
||||||
anElementWellKnown(
|
WellknownRetrieverResult.Success(
|
||||||
enforceElementPro = true,
|
anElementWellKnown(
|
||||||
|
enforceElementPro = true,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
createPresenter(
|
createPresenter(
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import io.element.android.libraries.architecture.AsyncData
|
||||||
import io.element.android.libraries.matrix.test.A_HOMESERVER_URL
|
import io.element.android.libraries.matrix.test.A_HOMESERVER_URL
|
||||||
import io.element.android.libraries.wellknown.api.WellKnown
|
import io.element.android.libraries.wellknown.api.WellKnown
|
||||||
import io.element.android.libraries.wellknown.api.WellKnownBaseConfig
|
import io.element.android.libraries.wellknown.api.WellKnownBaseConfig
|
||||||
|
import io.element.android.libraries.wellknown.api.WellknownRetrieverResult
|
||||||
import io.element.android.tests.testutils.WarmUpRule
|
import io.element.android.tests.testutils.WarmUpRule
|
||||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
import io.element.android.tests.testutils.lambda.value
|
import io.element.android.tests.testutils.lambda.value
|
||||||
|
|
@ -94,12 +95,12 @@ class SearchAccountProviderPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - enter text one result with wellknown`() = runTest {
|
fun `present - enter text one result with wellknown`() = runTest {
|
||||||
val getWellKnownResult = lambdaRecorder<String, WellKnown> {
|
val getWellKnownResult = lambdaRecorder<String, WellknownRetrieverResult<WellKnown>> {
|
||||||
when (it) {
|
when (it) {
|
||||||
"https://test.org" -> error("not found")
|
"https://test.org" -> WellknownRetrieverResult.NotFound
|
||||||
"https://test.com" -> error("not found")
|
"https://test.com" -> WellknownRetrieverResult.NotFound
|
||||||
"https://test.io" -> aWellKnown()
|
"https://test.io" -> WellknownRetrieverResult.Success(aWellKnown())
|
||||||
"https://test" -> error("not found")
|
"https://test" -> WellknownRetrieverResult.NotFound
|
||||||
else -> error("should not happen")
|
else -> error("should not happen")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -138,12 +139,12 @@ class SearchAccountProviderPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - enter text two results with wellknown`() = runTest {
|
fun `present - enter text two results with wellknown`() = runTest {
|
||||||
val getWellKnownResult = lambdaRecorder<String, WellKnown> {
|
val getWellKnownResult = lambdaRecorder<String, WellknownRetrieverResult<WellKnown>> {
|
||||||
when (it) {
|
when (it) {
|
||||||
"https://test.org" -> aWellKnown()
|
"https://test.org" -> WellknownRetrieverResult.Success(aWellKnown())
|
||||||
"https://test.com" -> error("not found")
|
"https://test.com" -> WellknownRetrieverResult.NotFound
|
||||||
"https://test.io" -> aWellKnown()
|
"https://test.io" -> WellknownRetrieverResult.Success(aWellKnown())
|
||||||
"https://test" -> error("not found")
|
"https://test" -> WellknownRetrieverResult.NotFound
|
||||||
else -> error("should not happen")
|
else -> error("should not happen")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,7 @@ class RustMatrixClient(
|
||||||
override suspend fun getUrl(url: String): Result<ByteArray> = withContext(sessionDispatcher) {
|
override suspend fun getUrl(url: String): Result<ByteArray> = withContext(sessionDispatcher) {
|
||||||
runCatchingExceptions {
|
runCatchingExceptions {
|
||||||
innerClient.getUrl(url)
|
innerClient.getUrl(url)
|
||||||
}
|
}.mapFailure { it.mapClientException() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getRoom(roomId: RoomId): BaseRoom? = withContext(sessionDispatcher) {
|
override suspend fun getRoom(roomId: RoomId): BaseRoom? = withContext(sessionDispatcher) {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,6 @@
|
||||||
package io.element.android.libraries.wellknown.api
|
package io.element.android.libraries.wellknown.api
|
||||||
|
|
||||||
interface SessionWellknownRetriever {
|
interface SessionWellknownRetriever {
|
||||||
suspend fun getWellKnown(): WellKnown?
|
suspend fun getWellKnown(): WellknownRetrieverResult<WellKnown>
|
||||||
suspend fun getElementWellKnown(): ElementWellKnown?
|
suspend fun getElementWellKnown(): WellknownRetrieverResult<ElementWellKnown>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,6 @@
|
||||||
package io.element.android.libraries.wellknown.api
|
package io.element.android.libraries.wellknown.api
|
||||||
|
|
||||||
interface WellknownRetriever {
|
interface WellknownRetriever {
|
||||||
suspend fun getWellKnown(baseUrl: String): WellKnown?
|
suspend fun getWellKnown(baseUrl: String): WellknownRetrieverResult<WellKnown>
|
||||||
suspend fun getElementWellKnown(baseUrl: String): ElementWellKnown?
|
suspend fun getElementWellKnown(baseUrl: String): WellknownRetrieverResult<ElementWellKnown>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||||
|
* Please see LICENSE files in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.wellknown.api
|
||||||
|
|
||||||
|
sealed interface WellknownRetrieverResult<out T> {
|
||||||
|
/**
|
||||||
|
* Well-known data has been successfully retrieved.
|
||||||
|
*/
|
||||||
|
data class Success<out T>(val data: T) : WellknownRetrieverResult<T>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Well-known data is not found (file does not exist server side, we got a 404).
|
||||||
|
*/
|
||||||
|
data object NotFound : WellknownRetrieverResult<Nothing>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Any other error.
|
||||||
|
*/
|
||||||
|
data class Error(val exception: Exception) : WellknownRetrieverResult<Nothing>
|
||||||
|
|
||||||
|
fun dataOrNull(): T? = when (this) {
|
||||||
|
is Success<T> -> data
|
||||||
|
is Error -> null
|
||||||
|
NotFound -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,9 +13,11 @@ import io.element.android.libraries.androidutils.json.JsonProvider
|
||||||
import io.element.android.libraries.core.extensions.mapCatchingExceptions
|
import io.element.android.libraries.core.extensions.mapCatchingExceptions
|
||||||
import io.element.android.libraries.di.SessionScope
|
import io.element.android.libraries.di.SessionScope
|
||||||
import io.element.android.libraries.matrix.api.MatrixClient
|
import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
|
import io.element.android.libraries.matrix.api.exception.ClientException
|
||||||
import io.element.android.libraries.wellknown.api.ElementWellKnown
|
import io.element.android.libraries.wellknown.api.ElementWellKnown
|
||||||
import io.element.android.libraries.wellknown.api.SessionWellknownRetriever
|
import io.element.android.libraries.wellknown.api.SessionWellknownRetriever
|
||||||
import io.element.android.libraries.wellknown.api.WellKnown
|
import io.element.android.libraries.wellknown.api.WellKnown
|
||||||
|
import io.element.android.libraries.wellknown.api.WellknownRetrieverResult
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
@ContributesBinding(SessionScope::class)
|
@ContributesBinding(SessionScope::class)
|
||||||
|
|
@ -26,29 +28,40 @@ class DefaultSessionWellknownRetriever(
|
||||||
) : SessionWellknownRetriever {
|
) : SessionWellknownRetriever {
|
||||||
private val domain by lazy { matrixClient.userIdServerName() }
|
private val domain by lazy { matrixClient.userIdServerName() }
|
||||||
|
|
||||||
override suspend fun getWellKnown(): WellKnown? {
|
override suspend fun getWellKnown(): WellknownRetrieverResult<WellKnown> {
|
||||||
val url = "https://$domain/.well-known/matrix/client"
|
val url = "https://$domain/.well-known/matrix/client"
|
||||||
return matrixClient
|
return matrixClient
|
||||||
.getUrl(url)
|
.getUrl(url)
|
||||||
.mapCatchingExceptions {
|
.mapCatchingExceptions {
|
||||||
val data = String(it)
|
val data = String(it)
|
||||||
json().decodeFromString(InternalWellKnown.serializer(), data)
|
json().decodeFromString<InternalWellKnown>(data).map()
|
||||||
}
|
}
|
||||||
.onFailure { Timber.e(it, "Failed to retrieve .well-known from $domain") }
|
.toWellknownRetrieverResult()
|
||||||
.map { it.map() }
|
|
||||||
.getOrNull()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getElementWellKnown(): ElementWellKnown? {
|
override suspend fun getElementWellKnown(): WellknownRetrieverResult<ElementWellKnown> {
|
||||||
val url = "https://$domain/.well-known/element/element.json"
|
val url = "https://$domain/.well-known/element/element.json"
|
||||||
return matrixClient
|
return matrixClient
|
||||||
.getUrl(url)
|
.getUrl(url)
|
||||||
.mapCatchingExceptions {
|
.mapCatchingExceptions {
|
||||||
val data = String(it)
|
val data = String(it)
|
||||||
json().decodeFromString(InternalElementWellKnown.serializer(), data)
|
json().decodeFromString<InternalElementWellKnown>(data).map()
|
||||||
}
|
}
|
||||||
.onFailure { Timber.e(it, "Failed to retrieve Element .well-known from $domain") }
|
.toWellknownRetrieverResult()
|
||||||
.map { it.map() }
|
|
||||||
.getOrNull()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun <T> Result<T>.toWellknownRetrieverResult(): WellknownRetrieverResult<T> = fold(
|
||||||
|
onSuccess = {
|
||||||
|
WellknownRetrieverResult.Success(it)
|
||||||
|
},
|
||||||
|
onFailure = {
|
||||||
|
Timber.e(it, "Failed to retrieve Element .well-known from $domain")
|
||||||
|
// This check on message value is not ideal but this is what we got from the SDK.
|
||||||
|
if ((it as? ClientException.Generic)?.message?.contains("404") == true) {
|
||||||
|
WellknownRetrieverResult.NotFound
|
||||||
|
} else {
|
||||||
|
WellknownRetrieverResult.Error(it as Exception)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,46 +10,72 @@ package io.element.android.libraries.wellknown.impl
|
||||||
import dev.zacsweers.metro.AppScope
|
import dev.zacsweers.metro.AppScope
|
||||||
import dev.zacsweers.metro.ContributesBinding
|
import dev.zacsweers.metro.ContributesBinding
|
||||||
import dev.zacsweers.metro.Inject
|
import dev.zacsweers.metro.Inject
|
||||||
|
import io.element.android.libraries.core.extensions.runCatchingExceptions
|
||||||
import io.element.android.libraries.core.uri.ensureProtocol
|
import io.element.android.libraries.core.uri.ensureProtocol
|
||||||
import io.element.android.libraries.network.RetrofitFactory
|
import io.element.android.libraries.network.RetrofitFactory
|
||||||
import io.element.android.libraries.wellknown.api.ElementWellKnown
|
import io.element.android.libraries.wellknown.api.ElementWellKnown
|
||||||
import io.element.android.libraries.wellknown.api.WellKnown
|
import io.element.android.libraries.wellknown.api.WellKnown
|
||||||
import io.element.android.libraries.wellknown.api.WellknownRetriever
|
import io.element.android.libraries.wellknown.api.WellknownRetriever
|
||||||
|
import io.element.android.libraries.wellknown.api.WellknownRetrieverResult
|
||||||
|
import retrofit2.HttpException
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import java.net.HttpURLConnection
|
||||||
|
|
||||||
@ContributesBinding(AppScope::class)
|
@ContributesBinding(AppScope::class)
|
||||||
@Inject
|
@Inject
|
||||||
class DefaultWellknownRetriever(
|
class DefaultWellknownRetriever(
|
||||||
private val retrofitFactory: RetrofitFactory,
|
private val retrofitFactory: RetrofitFactory,
|
||||||
) : WellknownRetriever {
|
) : WellknownRetriever {
|
||||||
override suspend fun getWellKnown(baseUrl: String): WellKnown? {
|
override suspend fun getWellKnown(baseUrl: String): WellknownRetrieverResult<WellKnown> {
|
||||||
val wellknownApi = buildWellknownApi(baseUrl) ?: return null
|
return buildWellknownApi(baseUrl)
|
||||||
return try {
|
.map { wellknownApi ->
|
||||||
wellknownApi.getWellKnown().map()
|
try {
|
||||||
} catch (e: Exception) {
|
val result = wellknownApi.getWellKnown().map()
|
||||||
Timber.e(e, "Failed to retrieve well-known data for $baseUrl")
|
WellknownRetrieverResult.Success(result)
|
||||||
null
|
} catch (e: Exception) {
|
||||||
}
|
Timber.e(e, "Failed to retrieve well-known data for $baseUrl")
|
||||||
|
if ((e as? HttpException)?.code() == HttpURLConnection.HTTP_NOT_FOUND) {
|
||||||
|
WellknownRetrieverResult.NotFound
|
||||||
|
} else {
|
||||||
|
WellknownRetrieverResult.Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fold(
|
||||||
|
onSuccess = { it },
|
||||||
|
onFailure = { WellknownRetrieverResult.Error(it as Exception) }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getElementWellKnown(baseUrl: String): ElementWellKnown? {
|
override suspend fun getElementWellKnown(baseUrl: String): WellknownRetrieverResult<ElementWellKnown> {
|
||||||
val wellknownApi = buildWellknownApi(baseUrl) ?: return null
|
return buildWellknownApi(baseUrl)
|
||||||
return try {
|
.map { wellknownApi ->
|
||||||
wellknownApi.getElementWellKnown().map()
|
try {
|
||||||
} catch (e: Exception) {
|
val result = wellknownApi.getElementWellKnown().map()
|
||||||
Timber.e(e, "Failed to retrieve Element well-known data for $baseUrl")
|
WellknownRetrieverResult.Success(result)
|
||||||
null
|
} catch (e: Exception) {
|
||||||
}
|
// Is it a 404?
|
||||||
|
Timber.e(e, "Failed to retrieve Element well-known data for $baseUrl")
|
||||||
|
if ((e as? HttpException)?.code() == HttpURLConnection.HTTP_NOT_FOUND) {
|
||||||
|
WellknownRetrieverResult.NotFound
|
||||||
|
} else {
|
||||||
|
WellknownRetrieverResult.Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fold(
|
||||||
|
onSuccess = { it },
|
||||||
|
onFailure = { WellknownRetrieverResult.Error(it as Exception) }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildWellknownApi(accountProviderUrl: String): WellknownAPI? {
|
private fun buildWellknownApi(accountProviderUrl: String): Result<WellknownAPI> {
|
||||||
return try {
|
return runCatchingExceptions {
|
||||||
retrofitFactory.create(accountProviderUrl.ensureProtocol())
|
retrofitFactory.create(accountProviderUrl.ensureProtocol())
|
||||||
.create(WellknownAPI::class.java)
|
.create(WellknownAPI::class.java)
|
||||||
} catch (e: Exception) {
|
}.onFailure { e ->
|
||||||
// If the base URL is not valid, we cannot retrieve the well-known data
|
// If the base URL is not valid, we cannot retrieve the well-known data
|
||||||
Timber.e(e, "Failed to create Retrofit instance for $accountProviderUrl")
|
Timber.e(e, "Failed to create Retrofit instance for $accountProviderUrl")
|
||||||
null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
import io.element.android.libraries.wellknown.api.ElementWellKnown
|
import io.element.android.libraries.wellknown.api.ElementWellKnown
|
||||||
import io.element.android.libraries.wellknown.api.WellKnown
|
import io.element.android.libraries.wellknown.api.WellKnown
|
||||||
import io.element.android.libraries.wellknown.api.WellKnownBaseConfig
|
import io.element.android.libraries.wellknown.api.WellKnownBaseConfig
|
||||||
|
import io.element.android.libraries.wellknown.api.WellknownRetrieverResult
|
||||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
import io.element.android.tests.testutils.lambda.value
|
import io.element.android.tests.testutils.lambda.value
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
|
|
@ -29,9 +30,11 @@ class DefaultSessionWellknownRetrieverTest {
|
||||||
getUrlLambda = getUrlLambda,
|
getUrlLambda = getUrlLambda,
|
||||||
)
|
)
|
||||||
assertThat(sut.getWellKnown()).isEqualTo(
|
assertThat(sut.getWellKnown()).isEqualTo(
|
||||||
WellKnown(
|
WellknownRetrieverResult.Success(
|
||||||
homeServer = null,
|
WellKnown(
|
||||||
identityServer = null,
|
homeServer = null,
|
||||||
|
identityServer = null,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
getUrlLambda.assertions().isCalledOnce()
|
getUrlLambda.assertions().isCalledOnce()
|
||||||
|
|
@ -55,13 +58,15 @@ class DefaultSessionWellknownRetrieverTest {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
assertThat(sut.getWellKnown()).isEqualTo(
|
assertThat(sut.getWellKnown()).isEqualTo(
|
||||||
WellKnown(
|
WellknownRetrieverResult.Success(
|
||||||
homeServer = WellKnownBaseConfig(
|
WellKnown(
|
||||||
baseURL = "https://example.org",
|
homeServer = WellKnownBaseConfig(
|
||||||
),
|
baseURL = "https://example.org",
|
||||||
identityServer = WellKnownBaseConfig(
|
),
|
||||||
baseURL = "https://identity.example.org",
|
identityServer = WellKnownBaseConfig(
|
||||||
),
|
baseURL = "https://identity.example.org",
|
||||||
|
),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -81,13 +86,15 @@ class DefaultSessionWellknownRetrieverTest {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
assertThat(sut.getWellKnown()).isEqualTo(
|
assertThat(sut.getWellKnown()).isEqualTo(
|
||||||
WellKnown(
|
WellknownRetrieverResult.Success(
|
||||||
homeServer = WellKnownBaseConfig(
|
WellKnown(
|
||||||
baseURL = "https://example.org",
|
homeServer = WellKnownBaseConfig(
|
||||||
),
|
baseURL = "https://example.org",
|
||||||
identityServer = WellKnownBaseConfig(
|
),
|
||||||
baseURL = null,
|
identityServer = WellKnownBaseConfig(
|
||||||
),
|
baseURL = null,
|
||||||
|
),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -110,13 +117,15 @@ class DefaultSessionWellknownRetrieverTest {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
assertThat(sut.getWellKnown()).isEqualTo(
|
assertThat(sut.getWellKnown()).isEqualTo(
|
||||||
WellKnown(
|
WellknownRetrieverResult.Success(
|
||||||
homeServer = WellKnownBaseConfig(
|
WellKnown(
|
||||||
baseURL = "https://example.org",
|
homeServer = WellKnownBaseConfig(
|
||||||
),
|
baseURL = "https://example.org",
|
||||||
identityServer = WellKnownBaseConfig(
|
),
|
||||||
baseURL = "https://identity.example.org",
|
identityServer = WellKnownBaseConfig(
|
||||||
),
|
baseURL = "https://identity.example.org",
|
||||||
|
),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -135,7 +144,7 @@ class DefaultSessionWellknownRetrieverTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
assertThat(sut.getWellKnown()).isNull()
|
assertThat(sut.getWellKnown()).isInstanceOf(WellknownRetrieverResult.Error::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -145,7 +154,7 @@ class DefaultSessionWellknownRetrieverTest {
|
||||||
Result.failure(AN_EXCEPTION)
|
Result.failure(AN_EXCEPTION)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
assertThat(sut.getWellKnown()).isNull()
|
assertThat(sut.getWellKnown()).isInstanceOf(WellknownRetrieverResult.Error::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -157,11 +166,13 @@ class DefaultSessionWellknownRetrieverTest {
|
||||||
getUrlLambda = getUrlLambda,
|
getUrlLambda = getUrlLambda,
|
||||||
)
|
)
|
||||||
assertThat(sut.getElementWellKnown()).isEqualTo(
|
assertThat(sut.getElementWellKnown()).isEqualTo(
|
||||||
ElementWellKnown(
|
WellknownRetrieverResult.Success(
|
||||||
registrationHelperUrl = null,
|
ElementWellKnown(
|
||||||
enforceElementPro = null,
|
registrationHelperUrl = null,
|
||||||
rageshakeUrl = null,
|
enforceElementPro = null,
|
||||||
brandColor = null,
|
rageshakeUrl = null,
|
||||||
|
brandColor = null,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
getUrlLambda.assertions().isCalledOnce()
|
getUrlLambda.assertions().isCalledOnce()
|
||||||
|
|
@ -183,11 +194,13 @@ class DefaultSessionWellknownRetrieverTest {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
assertThat(sut.getElementWellKnown()).isEqualTo(
|
assertThat(sut.getElementWellKnown()).isEqualTo(
|
||||||
ElementWellKnown(
|
WellknownRetrieverResult.Success(
|
||||||
registrationHelperUrl = "a_registration_url",
|
ElementWellKnown(
|
||||||
enforceElementPro = true,
|
registrationHelperUrl = "a_registration_url",
|
||||||
rageshakeUrl = "a_rageshake_url",
|
enforceElementPro = true,
|
||||||
brandColor = "#FF0000",
|
rageshakeUrl = "a_rageshake_url",
|
||||||
|
brandColor = "#FF0000",
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -207,11 +220,13 @@ class DefaultSessionWellknownRetrieverTest {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
assertThat(sut.getElementWellKnown()).isEqualTo(
|
assertThat(sut.getElementWellKnown()).isEqualTo(
|
||||||
ElementWellKnown(
|
WellknownRetrieverResult.Success(
|
||||||
registrationHelperUrl = "a_registration_url",
|
ElementWellKnown(
|
||||||
enforceElementPro = true,
|
registrationHelperUrl = "a_registration_url",
|
||||||
rageshakeUrl = "a_rageshake_url",
|
enforceElementPro = true,
|
||||||
brandColor = null,
|
rageshakeUrl = "a_rageshake_url",
|
||||||
|
brandColor = null,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -228,7 +243,7 @@ class DefaultSessionWellknownRetrieverTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
assertThat(sut.getElementWellKnown()).isNull()
|
assertThat(sut.getElementWellKnown()).isInstanceOf(WellknownRetrieverResult.Error::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -238,7 +253,7 @@ class DefaultSessionWellknownRetrieverTest {
|
||||||
Result.failure(AN_EXCEPTION)
|
Result.failure(AN_EXCEPTION)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
assertThat(sut.getElementWellKnown()).isNull()
|
assertThat(sut.getElementWellKnown()).isInstanceOf(WellknownRetrieverResult.Error::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDefaultSessionWellknownRetriever(
|
private fun createDefaultSessionWellknownRetriever(
|
||||||
|
|
|
||||||
|
|
@ -10,17 +10,18 @@ package io.element.android.features.wellknown.test
|
||||||
import io.element.android.libraries.wellknown.api.ElementWellKnown
|
import io.element.android.libraries.wellknown.api.ElementWellKnown
|
||||||
import io.element.android.libraries.wellknown.api.SessionWellknownRetriever
|
import io.element.android.libraries.wellknown.api.SessionWellknownRetriever
|
||||||
import io.element.android.libraries.wellknown.api.WellKnown
|
import io.element.android.libraries.wellknown.api.WellKnown
|
||||||
|
import io.element.android.libraries.wellknown.api.WellknownRetrieverResult
|
||||||
import io.element.android.tests.testutils.simulateLongTask
|
import io.element.android.tests.testutils.simulateLongTask
|
||||||
|
|
||||||
class FakeSessionWellknownRetriever(
|
class FakeSessionWellknownRetriever(
|
||||||
private val getWellKnownResult: () -> WellKnown? = { null },
|
private val getWellKnownResult: () -> WellknownRetrieverResult<WellKnown> = { WellknownRetrieverResult.NotFound },
|
||||||
private val getElementWellKnownResult: () -> ElementWellKnown? = { null },
|
private val getElementWellKnownResult: () -> WellknownRetrieverResult<ElementWellKnown> = { WellknownRetrieverResult.NotFound },
|
||||||
) : SessionWellknownRetriever {
|
) : SessionWellknownRetriever {
|
||||||
override suspend fun getWellKnown(): WellKnown? = simulateLongTask {
|
override suspend fun getWellKnown(): WellknownRetrieverResult<WellKnown> = simulateLongTask {
|
||||||
getWellKnownResult()
|
getWellKnownResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getElementWellKnown(): ElementWellKnown? = simulateLongTask {
|
override suspend fun getElementWellKnown(): WellknownRetrieverResult<ElementWellKnown> = simulateLongTask {
|
||||||
getElementWellKnownResult()
|
getElementWellKnownResult()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,17 +10,18 @@ package io.element.android.features.wellknown.test
|
||||||
import io.element.android.libraries.wellknown.api.ElementWellKnown
|
import io.element.android.libraries.wellknown.api.ElementWellKnown
|
||||||
import io.element.android.libraries.wellknown.api.WellKnown
|
import io.element.android.libraries.wellknown.api.WellKnown
|
||||||
import io.element.android.libraries.wellknown.api.WellknownRetriever
|
import io.element.android.libraries.wellknown.api.WellknownRetriever
|
||||||
|
import io.element.android.libraries.wellknown.api.WellknownRetrieverResult
|
||||||
import io.element.android.tests.testutils.simulateLongTask
|
import io.element.android.tests.testutils.simulateLongTask
|
||||||
|
|
||||||
class FakeWellknownRetriever(
|
class FakeWellknownRetriever(
|
||||||
private val getWellKnownResult: (String) -> WellKnown? = { null },
|
private val getWellKnownResult: (String) -> WellknownRetrieverResult<WellKnown> = { WellknownRetrieverResult.NotFound },
|
||||||
private val getElementWellKnownResult: (String) -> ElementWellKnown? = { null },
|
private val getElementWellKnownResult: (String) -> WellknownRetrieverResult<ElementWellKnown> = { WellknownRetrieverResult.NotFound },
|
||||||
) : WellknownRetriever {
|
) : WellknownRetriever {
|
||||||
override suspend fun getWellKnown(baseUrl: String): WellKnown? = simulateLongTask {
|
override suspend fun getWellKnown(baseUrl: String): WellknownRetrieverResult<WellKnown> = simulateLongTask {
|
||||||
getWellKnownResult(baseUrl)
|
getWellKnownResult(baseUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getElementWellKnown(baseUrl: String): ElementWellKnown? = simulateLongTask {
|
override suspend fun getElementWellKnown(baseUrl: String): WellknownRetrieverResult<ElementWellKnown> = simulateLongTask {
|
||||||
getElementWellKnownResult(baseUrl)
|
getElementWellKnownResult(baseUrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue