adding test for the add pusher task happy flow
- introduces the concepts of Fakes for handling the dependencies, unforuntately realm/monarchy aren't very testable in their current state so we'll need to use mocks
This commit is contained in:
parent
ced85964da
commit
48d9dfb82d
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright (c) 2021 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* 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 org.matrix.android.sdk.internal.session.pushers
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import io.mockk.MockKVerificationScope
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.verify
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmModel
|
||||
import io.realm.RealmQuery
|
||||
import io.realm.kotlin.where
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.amshove.kluent.shouldBeEqualTo
|
||||
import org.junit.Test
|
||||
import org.matrix.android.sdk.api.failure.GlobalError
|
||||
import org.matrix.android.sdk.api.session.pushers.PusherState
|
||||
import org.matrix.android.sdk.internal.database.model.PusherEntity
|
||||
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
|
||||
import org.matrix.android.sdk.internal.util.awaitTransaction
|
||||
|
||||
private val A_JSON_PUSHER = JsonPusher(
|
||||
pushKey = "push-key",
|
||||
kind = "http",
|
||||
appId = "m.email",
|
||||
appDisplayName = "Element",
|
||||
deviceDisplayName = null,
|
||||
profileTag = "",
|
||||
lang = "en-GB",
|
||||
data = JsonPusherData(brand = "Element")
|
||||
)
|
||||
|
||||
class DefaultAddPusherTaskTest {
|
||||
|
||||
private val pushersAPI = FakePushersAPI()
|
||||
private val monarchy = FakeMonarchy()
|
||||
|
||||
private val addPusherTask = DefaultAddPusherTask(
|
||||
pushersAPI = pushersAPI,
|
||||
monarchy = monarchy.instance,
|
||||
requestExecutor = FakeRequestExecutor(),
|
||||
globalErrorReceiver = FakeGlobalErrorReceiver()
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `given no persisted pusher when running task then fetches from api and inserts result with Registered state`() = runBlocking {
|
||||
monarchy.givenWhereReturns<PusherEntity>(result = null)
|
||||
|
||||
addPusherTask.execute(AddPusherTask.Params(A_JSON_PUSHER))
|
||||
|
||||
pushersAPI.verifySetPusher(A_JSON_PUSHER)
|
||||
monarchy.verifyInsertOrUpdate<PusherEntity> {
|
||||
withArg { actual ->
|
||||
actual.state shouldBeEqualTo PusherState.REGISTERED
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class FakePushersAPI : PushersAPI {
|
||||
|
||||
private var setRequestPayload: JsonPusher? = null
|
||||
private var error: Throwable? = null
|
||||
|
||||
override suspend fun getPushers(): GetPushersResponse {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override suspend fun setPusher(jsonPusher: JsonPusher) {
|
||||
error?.let { throw it }
|
||||
setRequestPayload = jsonPusher
|
||||
}
|
||||
|
||||
fun verifySetPusher(payload: JsonPusher) {
|
||||
this.setRequestPayload shouldBeEqualTo payload
|
||||
}
|
||||
|
||||
fun givenSetPusherErrors(error: Throwable) {
|
||||
this.error = error
|
||||
}
|
||||
}
|
||||
|
||||
internal class FakeMonarchy {
|
||||
|
||||
val instance = mockk<Monarchy>()
|
||||
private val realm = mockk<Realm>(relaxed = true)
|
||||
|
||||
init {
|
||||
mockkStatic("org.matrix.android.sdk.internal.util.MonarchyKt")
|
||||
coEvery {
|
||||
instance.awaitTransaction(any<suspend (Realm) -> Any>())
|
||||
} coAnswers {
|
||||
secondArg<suspend (Realm) -> Any>().invoke(realm)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T : RealmModel> givenWhereReturns(result: T?) {
|
||||
val queryResult = mockk<RealmQuery<T>>(relaxed = true)
|
||||
every { queryResult.findFirst() } returns result
|
||||
every { realm.where<T>() } returns queryResult
|
||||
}
|
||||
|
||||
inline fun <reified T : RealmModel> verifyInsertOrUpdate(crossinline verification: MockKVerificationScope.() -> T) {
|
||||
verify { realm.insertOrUpdate(verification()) }
|
||||
}
|
||||
}
|
||||
|
||||
internal class FakeRequestExecutor : RequestExecutor {
|
||||
|
||||
override suspend fun <DATA> executeRequest(globalErrorReceiver: GlobalErrorReceiver?,
|
||||
canRetry: Boolean,
|
||||
maxDelayBeforeRetry: Long,
|
||||
maxRetriesCount: Int,
|
||||
requestBlock: suspend () -> DATA): DATA {
|
||||
return requestBlock()
|
||||
}
|
||||
}
|
||||
|
||||
internal class FakeGlobalErrorReceiver : GlobalErrorReceiver {
|
||||
override fun handleGlobalError(globalError: GlobalError) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue