Add test on UnifiedPushGatewayResolver

This commit is contained in:
Benoit Marty
2024-05-22 09:23:24 +02:00
parent 167e52f34a
commit 39bb6d3ff3
4 changed files with 227 additions and 10 deletions

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2024 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.element.android.libraries.pushproviders.unifiedpush
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.network.RetrofitFactory
import io.element.android.libraries.pushproviders.unifiedpush.network.UnifiedPushApi
import javax.inject.Inject
interface UnifiedPushApiFactory {
fun create(baseUrl: String): UnifiedPushApi
}
@ContributesBinding(AppScope::class)
class DefaultUnifiedPushApiFactory @Inject constructor(
private val retrofitFactory: RetrofitFactory,
) : UnifiedPushApiFactory {
override fun create(baseUrl: String): UnifiedPushApi {
return retrofitFactory.create(baseUrl)
.create(UnifiedPushApi::class.java)
}
}

View File

@@ -17,28 +17,25 @@
package io.element.android.libraries.pushproviders.unifiedpush
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.network.RetrofitFactory
import io.element.android.libraries.pushproviders.unifiedpush.network.UnifiedPushApi
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.net.URL
import javax.inject.Inject
class UnifiedPushGatewayResolver @Inject constructor(
private val retrofitFactory: RetrofitFactory,
private val unifiedPushApiFactory: UnifiedPushApiFactory,
private val coroutineDispatchers: CoroutineDispatchers,
) {
suspend fun getGateway(endpoint: String): String? {
val gateway = UnifiedPushConfig.DEFAULT_PUSH_GATEWAY_HTTP_URL
val url = URL(endpoint)
val port = if (url.port != -1) ":${url.port}" else ""
val customBase = "${url.protocol}://${url.host}$port"
val customUrl = "$customBase/_matrix/push/v1/notify"
Timber.i("Testing $customUrl")
try {
val url = URL(endpoint)
val port = if (url.port != -1) ":${url.port}" else ""
val customBase = "${url.protocol}://${url.host}$port"
val customUrl = "$customBase/_matrix/push/v1/notify"
Timber.i("Testing $customUrl")
return withContext(coroutineDispatchers.io) {
val api = retrofitFactory.create(customBase)
.create(UnifiedPushApi::class.java)
val api = unifiedPushApiFactory.create(customBase)
try {
val discoveryResponse = api.discover()
if (discoveryResponse.unifiedpush.gateway == "matrix") {

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2024 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.element.android.libraries.pushproviders.unifiedpush
import io.element.android.libraries.pushproviders.unifiedpush.network.DiscoveryResponse
import io.element.android.libraries.pushproviders.unifiedpush.network.UnifiedPushApi
class FakeUnifiedPushApiFactory(
private val discoveryResponse: () -> DiscoveryResponse
) : UnifiedPushApiFactory {
var baseUrlParameter: String? = null
private set
override fun create(baseUrl: String): UnifiedPushApi {
baseUrlParameter = baseUrl
return FakeUnifiedPushApi(discoveryResponse)
}
}
class FakeUnifiedPushApi(
private val discoveryResponse: () -> DiscoveryResponse
) : UnifiedPushApi {
override suspend fun discover(): DiscoveryResponse {
return discoveryResponse()
}
}

View File

@@ -0,0 +1,143 @@
/*
* Copyright (c) 2024 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.element.android.libraries.pushproviders.unifiedpush
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.pushproviders.unifiedpush.network.DiscoveryResponse
import io.element.android.libraries.pushproviders.unifiedpush.network.DiscoveryUnifiedPush
import io.element.android.tests.testutils.testCoroutineDispatchers
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Test
class UnifiedPushGatewayResolverTest {
private val matrixDiscoveryResponse = {
DiscoveryResponse(
unifiedpush = DiscoveryUnifiedPush(
gateway = "matrix"
)
)
}
private val invalidDiscoveryResponse = {
DiscoveryResponse(
unifiedpush = DiscoveryUnifiedPush(
gateway = ""
)
)
}
@Test
fun `when a custom url provide a correct matrix gateway, the custom url is returned`() = runTest {
val unifiedPushApiFactory = FakeUnifiedPushApiFactory(
discoveryResponse = matrixDiscoveryResponse
)
val sut = createUnifiedPushGatewayResolver(
unifiedPushApiFactory = unifiedPushApiFactory
)
val result = sut.getGateway("https://custom.url")
assertThat(unifiedPushApiFactory.baseUrlParameter).isEqualTo("https://custom.url")
assertThat(result).isEqualTo("https://custom.url/_matrix/push/v1/notify")
}
@Test
fun `when a custom url with port provides a correct matrix gateway, the custom url is returned`() = runTest {
val unifiedPushApiFactory = FakeUnifiedPushApiFactory(
discoveryResponse = matrixDiscoveryResponse
)
val sut = createUnifiedPushGatewayResolver(
unifiedPushApiFactory = unifiedPushApiFactory
)
val result = sut.getGateway("https://custom.url:123")
assertThat(unifiedPushApiFactory.baseUrlParameter).isEqualTo("https://custom.url:123")
assertThat(result).isEqualTo("https://custom.url:123/_matrix/push/v1/notify")
}
@Test
fun `when a custom url with port and path provides a correct matrix gateway, the custom url is returned`() = runTest {
val unifiedPushApiFactory = FakeUnifiedPushApiFactory(
discoveryResponse = matrixDiscoveryResponse
)
val sut = createUnifiedPushGatewayResolver(
unifiedPushApiFactory = unifiedPushApiFactory
)
val result = sut.getGateway("https://custom.url:123/some/path")
assertThat(unifiedPushApiFactory.baseUrlParameter).isEqualTo("https://custom.url:123")
assertThat(result).isEqualTo("https://custom.url:123/_matrix/push/v1/notify")
}
@Test
fun `when a custom url with http scheme provides a correct matrix gateway, the custom url is returned`() = runTest {
val unifiedPushApiFactory = FakeUnifiedPushApiFactory(
discoveryResponse = matrixDiscoveryResponse
)
val sut = createUnifiedPushGatewayResolver(
unifiedPushApiFactory = unifiedPushApiFactory
)
val result = sut.getGateway("http://custom.url:123/some/path")
assertThat(unifiedPushApiFactory.baseUrlParameter).isEqualTo("http://custom.url:123")
assertThat(result).isEqualTo("http://custom.url:123/_matrix/push/v1/notify")
}
@Test
fun `when a custom url is not reachable, the default url is returned`() = runTest {
val unifiedPushApiFactory = FakeUnifiedPushApiFactory(
discoveryResponse = { throw Exception() }
)
val sut = createUnifiedPushGatewayResolver(
unifiedPushApiFactory = unifiedPushApiFactory
)
val result = sut.getGateway("http://custom.url")
assertThat(unifiedPushApiFactory.baseUrlParameter).isEqualTo("http://custom.url")
assertThat(result).isEqualTo(UnifiedPushConfig.DEFAULT_PUSH_GATEWAY_HTTP_URL)
}
@Test
fun `when a custom url is invalid, the default url is returned`() = runTest {
val unifiedPushApiFactory = FakeUnifiedPushApiFactory(
discoveryResponse = matrixDiscoveryResponse
)
val sut = createUnifiedPushGatewayResolver(
unifiedPushApiFactory = unifiedPushApiFactory
)
val result = sut.getGateway("invalid")
assertThat(unifiedPushApiFactory.baseUrlParameter).isNull()
assertThat(result).isEqualTo(UnifiedPushConfig.DEFAULT_PUSH_GATEWAY_HTTP_URL)
}
@Test
fun `when a custom url provides a invalid matrix gateway, the default url is returned`() = runTest {
val unifiedPushApiFactory = FakeUnifiedPushApiFactory(
discoveryResponse = invalidDiscoveryResponse
)
val sut = createUnifiedPushGatewayResolver(
unifiedPushApiFactory = unifiedPushApiFactory
)
val result = sut.getGateway("https://custom.url")
assertThat(unifiedPushApiFactory.baseUrlParameter).isEqualTo("https://custom.url")
assertThat(result).isEqualTo(UnifiedPushConfig.DEFAULT_PUSH_GATEWAY_HTTP_URL)
}
private fun TestScope.createUnifiedPushGatewayResolver(
unifiedPushApiFactory: UnifiedPushApiFactory = FakeUnifiedPushApiFactory(
discoveryResponse = { DiscoveryResponse() }
)
) = UnifiedPushGatewayResolver(
unifiedPushApiFactory = unifiedPushApiFactory,
coroutineDispatchers = testCoroutineDispatchers()
)
}