adding unified push delegate tests
This commit is contained in:
parent
093e5b64bb
commit
1e8d868348
|
@ -6,7 +6,11 @@ import kotlinx.coroutines.test.runTest
|
|||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
fun runExpectTest(testBody: suspend ExpectTestScope.() -> Unit) {
|
||||
runTest { testBody(ExpectTest(coroutineContext)) }
|
||||
runTest {
|
||||
val expectTest = ExpectTest(coroutineContext)
|
||||
testBody(expectTest)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ExpectTest(override val coroutineContext: CoroutineContext) : ExpectTestScope {
|
||||
|
@ -24,6 +28,11 @@ class ExpectTest(override val coroutineContext: CoroutineContext) : ExpectTestSc
|
|||
expects.add(times to { block(this@expectUnit) })
|
||||
}
|
||||
|
||||
override fun <T> T.expect(times: Int, block: suspend MockKMatcherScope.(T) -> Unit) {
|
||||
coJustRun { block(this@expect) }.ignore()
|
||||
expects.add(times to { block(this@expect) })
|
||||
}
|
||||
|
||||
override fun <T> T.captureExpects(block: suspend MockKMatcherScope.(T) -> Unit) {
|
||||
groups.add { block(this@captureExpects) }
|
||||
}
|
||||
|
@ -34,5 +43,6 @@ private fun Any.ignore() = Unit
|
|||
interface ExpectTestScope : CoroutineScope {
|
||||
fun verifyExpects()
|
||||
fun <T> T.expectUnit(times: Int = 1, block: suspend MockKMatcherScope.(T) -> Unit)
|
||||
fun <T> T.expect(times: Int = 1, block: suspend MockKMatcherScope.(T) -> Unit)
|
||||
fun <T> T.captureExpects(block: suspend MockKMatcherScope.(T) -> Unit)
|
||||
}
|
|
@ -10,4 +10,8 @@ dependencies {
|
|||
|
||||
implementation Dependencies.mavenCentral.kotlinSerializationJson
|
||||
implementation Dependencies.jitPack.unifiedPush
|
||||
|
||||
kotlinTest(it)
|
||||
androidImportFixturesWorkaround(project, project(":core"))
|
||||
androidImportFixturesWorkaround(project, project(":domains:android:stub"))
|
||||
}
|
||||
|
|
|
@ -22,7 +22,10 @@ private val json = Json { ignoreUnknownKeys = true }
|
|||
|
||||
class UnifiedPushMessageDelegate(
|
||||
private val scope: CoroutineScope = CoroutineScope(SupervisorJob()),
|
||||
private val pushModuleProvider: (Context) -> PushModule = { it.module() }
|
||||
private val pushModuleProvider: (Context) -> PushModule = { it.module() },
|
||||
private val endpointReader: suspend (URL) -> String = {
|
||||
runCatching { it.openStream().use { String(it.readBytes()) } }.getOrNull() ?: ""
|
||||
}
|
||||
) {
|
||||
|
||||
fun onMessage(context: Context, message: ByteArray) {
|
||||
|
@ -44,7 +47,7 @@ class UnifiedPushMessageDelegate(
|
|||
scope.launch {
|
||||
withContext(module.dispatcher().io) {
|
||||
val matrixEndpoint = URL(endpoint).let { URL("${it.protocol}://${it.host}/_matrix/push/v1/notify") }
|
||||
val content = runCatching { matrixEndpoint.openStream().use { String(it.readBytes()) } }.getOrNull() ?: ""
|
||||
val content = endpointReader(matrixEndpoint)
|
||||
val gatewayUrl = when {
|
||||
content.contains("\"gateway\":\"matrix\"") -> matrixEndpoint.toString()
|
||||
else -> FALLBACK_UNIFIED_PUSH_GATEWAY
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
package app.dapk.st.push.unifiedpush
|
||||
|
||||
import app.dapk.st.matrix.common.EventId
|
||||
import app.dapk.st.matrix.common.RoomId
|
||||
import app.dapk.st.push.PushHandler
|
||||
import app.dapk.st.push.PushModule
|
||||
import app.dapk.st.push.PushTokenPayload
|
||||
import fake.FakeContext
|
||||
import fixture.CoroutineDispatchersFixture.aCoroutineDispatchers
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import org.junit.Test
|
||||
import test.delegateReturn
|
||||
import test.runExpectTest
|
||||
import java.net.URL
|
||||
|
||||
private val A_CONTEXT = FakeContext()
|
||||
private const val A_ROOM_ID = "a room id"
|
||||
private const val AN_EVENT_ID = "an event id"
|
||||
private const val AN_ENDPOINT_HOST = "https://aendpointurl.com"
|
||||
private const val AN_ENDPOINT = "$AN_ENDPOINT_HOST/with/path"
|
||||
private const val A_GATEWAY_URL = "$AN_ENDPOINT_HOST/_matrix/push/v1/notify"
|
||||
private const val FALLBACK_GATEWAY_URL = "https://matrix.gateway.unifiedpush.org/_matrix/push/v1/notify"
|
||||
|
||||
class UnifiedPushMessageDelegateTest {
|
||||
|
||||
private val fakePushHandler = FakePushHandler()
|
||||
private val fakeEndpointReader = FakeEndpointReader()
|
||||
private val fakePushModule = FakePushModule().also {
|
||||
it.givenPushHandler().returns(fakePushHandler)
|
||||
}
|
||||
|
||||
private val unifiedPushReceiver = UnifiedPushMessageDelegate(
|
||||
CoroutineScope(UnconfinedTestDispatcher()),
|
||||
pushModuleProvider = { _ -> fakePushModule.instance },
|
||||
endpointReader = fakeEndpointReader,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `parses incoming message payloads`() = runExpectTest {
|
||||
fakePushHandler.expect { it.onMessageReceived(EventId(AN_EVENT_ID), RoomId(A_ROOM_ID)) }
|
||||
val messageBytes = createMessage(A_ROOM_ID, AN_EVENT_ID)
|
||||
|
||||
unifiedPushReceiver.onMessage(A_CONTEXT.instance, messageBytes)
|
||||
|
||||
verifyExpects()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given endpoint is a gateway, then uses original endpoint url`() = runExpectTest {
|
||||
fakeEndpointReader.given(A_GATEWAY_URL).returns("""{"unifiedpush":{"gateway":"matrix"}}""")
|
||||
fakePushHandler.expect { it.onNewToken(PushTokenPayload(token = AN_ENDPOINT, gatewayUrl = A_GATEWAY_URL)) }
|
||||
|
||||
unifiedPushReceiver.onNewEndpoint(A_CONTEXT.instance, AN_ENDPOINT)
|
||||
|
||||
verifyExpects()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given endpoint is not a gateway, then uses fallback endpoint url`() = runExpectTest {
|
||||
fakeEndpointReader.given(A_GATEWAY_URL).returns("")
|
||||
fakePushHandler.expect { it.onNewToken(PushTokenPayload(token = AN_ENDPOINT, gatewayUrl = FALLBACK_GATEWAY_URL)) }
|
||||
|
||||
unifiedPushReceiver.onNewEndpoint(A_CONTEXT.instance, AN_ENDPOINT)
|
||||
|
||||
verifyExpects()
|
||||
}
|
||||
|
||||
private fun createMessage(roomId: String, eventId: String) = """
|
||||
{
|
||||
"notification": {
|
||||
"room_id": "$roomId",
|
||||
"event_id": "$eventId"
|
||||
}
|
||||
}
|
||||
""".trimIndent().toByteArray()
|
||||
}
|
||||
|
||||
class FakePushModule {
|
||||
val instance = mockk<PushModule>()
|
||||
|
||||
init {
|
||||
every { instance.dispatcher() }.returns(aCoroutineDispatchers())
|
||||
}
|
||||
|
||||
fun givenPushHandler() = every { instance.pushHandler() }.delegateReturn()
|
||||
}
|
||||
|
||||
class FakePushHandler : PushHandler by mockk()
|
||||
|
||||
class FakeEndpointReader : suspend (URL) -> String by mockk() {
|
||||
|
||||
fun given(url: String) = coEvery { this@FakeEndpointReader.invoke(URL(url)) }.delegateReturn()
|
||||
|
||||
}
|
Loading…
Reference in New Issue