Skip to content

Add unit tests in some push classes #2899

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 37 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
50004e3
Add test on UnifiedPushGatewayResolver
bmarty May 22, 2024
86eceb3
UnifiedPushGatewayResolver.getGateway cannot return null.
bmarty May 22, 2024
1bf38e9
Add test on `UnifiedPushProvider`
bmarty May 22, 2024
538c2b0
Create FakeIsPlayServiceAvailable
bmarty May 22, 2024
0087972
Add test for FirebasePushProvider
bmarty May 22, 2024
b70c591
Remove unused code notificationStyleChanged()
bmarty May 22, 2024
20880b0
Extract testPush to its own class and rename PushersManager to Defaul…
bmarty May 22, 2024
dc6e62a
Add test on PushGatewayNotifyRequest
bmarty May 22, 2024
505f6d4
Add test on DefaultPushService
bmarty May 22, 2024
08f70b9
Move some classes to the test module.
bmarty May 22, 2024
707a530
Fix wrong package name.
bmarty May 22, 2024
97530e7
Add test on DefaultPusherSubscriber
bmarty May 22, 2024
3bde744
Add test on DefaultTestPush
bmarty May 22, 2024
fe771a3
isCalledExactly(1) -> isCalledOnce()
bmarty May 22, 2024
980a80b
Cleanup
bmarty May 22, 2024
5b074dc
Create interface for NotifiableEventResolver
bmarty May 22, 2024
b2a3b96
Add test on DefaultPushHandler
bmarty May 22, 2024
eafa713
Add test on VectorFirebaseMessagingService
bmarty May 22, 2024
90a14ce
Change to lambda
bmarty May 22, 2024
b38c144
Add test on DefaultFirebaseNewTokenHandler
bmarty May 22, 2024
5c68956
Fix test on `VectorFirebaseMessagingService`
bmarty May 22, 2024
738bb83
Create interface UnifiedPushGatewayResolver
bmarty May 22, 2024
09b2b2c
Create interface UnifiedPushNewGatewayHandler
bmarty May 22, 2024
50b7f2c
Add test on VectorUnifiedPushMessagingReceiver
bmarty May 22, 2024
f304c1f
Add test on DefaultRegisterUnifiedPushUseCase
bmarty May 22, 2024
f974cdd
Add test on DefaultUnifiedPushNewGatewayHandler
bmarty May 22, 2024
02fa405
Add test on UnifiedPushTest.isRelevant
bmarty May 22, 2024
0a2d87f
Add test on DefaultUnregisterUnifiedPushUseCase
bmarty May 22, 2024
4e7f5c4
Refactor: change signature to always have `clientSecret` first, since…
bmarty May 22, 2024
cf3b2bb
Add test on isRelevant
bmarty May 22, 2024
c71c491
Clean up
bmarty May 22, 2024
f042532
Introduce lambdaError instead of using TODO, to handle error when a l…
bmarty May 23, 2024
de032fa
Use lambdaError() instead of `throw NotImplementedError()`
bmarty May 23, 2024
b8b66b3
Add missing import
bmarty May 23, 2024
0639bc6
Simplify `RegisterUnifiedPushUseCase`, fix test
jmartinesp May 23, 2024
b716482
No need to use advanceTimeBy
bmarty May 23, 2024
788d9e0
No need to use StandardTestDispatcher
bmarty May 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.matrix.test.A_THREAD_ID
import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser
import io.element.android.tests.testutils.lambda.lambdaError
import org.junit.Assert.assertThrows
import org.junit.Test
import org.junit.runner.RunWith
Expand Down Expand Up @@ -229,7 +230,7 @@ class IntentResolverTest {
}

private fun createIntentResolver(
permalinkParserResult: () -> PermalinkData = { throw NotImplementedError() }
permalinkParserResult: () -> PermalinkData = { lambdaError() }
): IntentResolver {
return IntentResolver(
deeplinkParser = DeeplinkParser(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,11 @@ class AcceptDeclineInvitePresenterTest {
cancelAndConsumeRemainingEvents()
}
assert(joinRoomFailure)
.isCalledExactly(1)
.withSequence(
listOf(value(A_ROOM_ID), value(emptyList<String>()), value(JoinedRoom.Trigger.Invite))
.isCalledOnce()
.with(
value(A_ROOM_ID),
value(emptyList<String>()),
value(JoinedRoom.Trigger.Invite)
)
}

Expand All @@ -221,9 +223,11 @@ class AcceptDeclineInvitePresenterTest {
cancelAndConsumeRemainingEvents()
}
assert(joinRoomSuccess)
.isCalledExactly(1)
.withSequence(
listOf(value(A_ROOM_ID), value(emptyList<String>()), value(JoinedRoom.Trigger.Invite))
.isCalledOnce()
.with(
value(A_ROOM_ID),
value(emptyList<String>()),
value(JoinedRoom.Trigger.Invite)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ package io.element.android.features.preferences.impl.notifications
import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.element.android.libraries.pushstore.test.userpushstore.FakeUserPushStoreFactory
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.test.A_THROWABLE
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
import io.element.android.libraries.pushstore.test.userpushstore.FakeUserPushStoreFactory
import io.element.android.tests.testutils.consumeItemsUntilPredicate
import kotlinx.coroutines.test.runTest
import org.junit.Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class BugReportPresenterTest {
initialState.eventSink.invoke(BugReportEvents.ResetAll)
val resetState = awaitItem()
assertThat(resetState.hasCrashLogs).isFalse()
logFilesRemoverLambda.assertions().isCalledExactly(1)
logFilesRemoverLambda.assertions().isCalledOnce()
// TODO Make it live assertThat(resetState.screenshotUri).isNull()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ class DefaultJoinRoomTest {
.isNeverCalled()
joinRoomLambda
.assertions()
.isCalledExactly(1)
.withSequence(
listOf(value(A_ROOM_ID))
.isCalledOnce()
.with(
value(A_ROOM_ID)
)
assertThat(analyticsService.capturedEvents).containsExactly(
roomResult.toAnalyticsJoinedRoom(aTrigger)
Expand Down Expand Up @@ -88,9 +88,10 @@ class DefaultJoinRoomTest {
sut.invoke(A_ROOM_ID, A_SERVER_LIST, aTrigger)
joinRoomByIdOrAliasLambda
.assertions()
.isCalledExactly(1)
.withSequence(
listOf(value(A_ROOM_ID), value(A_SERVER_LIST))
.isCalledOnce()
.with(
value(A_ROOM_ID),
value(A_SERVER_LIST)
)
joinRoomLambda
.assertions()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import io.element.android.libraries.matrix.api.room.RoomNotificationSettings

const val A_USER_NAME = "alice"
const val A_PASSWORD = "password"
const val A_SECRET = "secret"

val A_USER_ID = UserId("@alice:server.org")
val A_USER_ID_2 = UserId("@bob:server.org")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ import kotlinx.coroutines.flow.flowOf

val A_OIDC_DATA = OidcDetails(url = "a-url")

class FakeAuthenticationService : MatrixAuthenticationService {
class FakeAuthenticationService(
private val matrixClientResult: ((SessionId) -> Result<MatrixClient>)? = null
) : MatrixAuthenticationService {
private val homeserver = MutableStateFlow<MatrixHomeServerDetails?>(null)
private var oidcError: Throwable? = null
private var oidcCancelError: Throwable? = null
Expand All @@ -48,6 +50,9 @@ class FakeAuthenticationService : MatrixAuthenticationService {
override suspend fun getLatestSessionId(): SessionId? = getLatestSessionIdLambda()

override suspend fun restoreSession(sessionId: SessionId): Result<MatrixClient> {
if (matrixClientResult != null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally it would be nice to use matrixClientResult here to the get MatrixClient instead of having 2 sources of truth, but changing it may not be worth it.

return matrixClientResult.invoke(sessionId)
}
return if (matrixClient != null) {
Result.success(matrixClient!!)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ package io.element.android.libraries.matrix.test.permalink

import io.element.android.libraries.matrix.api.permalink.PermalinkData
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
import io.element.android.tests.testutils.lambda.lambdaError

class FakePermalinkParser(
private var result: () -> PermalinkData = { TODO("Not implemented") }
private var result: () -> PermalinkData = { lambdaError() }
) : PermalinkParser {
fun givenResult(result: PermalinkData) {
this.result = { result }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ package io.element.android.libraries.matrix.test.pushers
import io.element.android.libraries.matrix.api.pusher.PushersService
import io.element.android.libraries.matrix.api.pusher.SetHttpPusherData
import io.element.android.libraries.matrix.api.pusher.UnsetHttpPusherData
import io.element.android.tests.testutils.lambda.lambdaError

class FakePushersService : PushersService {
override suspend fun setHttpPusher(setHttpPusherData: SetHttpPusherData) = Result.success(Unit)
override suspend fun unsetHttpPusher(unsetHttpPusherData: UnsetHttpPusherData): Result<Unit> = Result.success(Unit)
class FakePushersService(
private val setHttpPusherResult: (SetHttpPusherData) -> Result<Unit> = { lambdaError() },
private val unsetHttpPusherResult: (UnsetHttpPusherData) -> Result<Unit> = { lambdaError() },
) : PushersService {
override suspend fun setHttpPusher(setHttpPusherData: SetHttpPusherData) = setHttpPusherResult(setHttpPusherData)
override suspend fun unsetHttpPusher(unsetHttpPusherData: UnsetHttpPusherData): Result<Unit> = unsetHttpPusherResult(unsetHttpPusherData)
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ import io.element.android.libraries.pushproviders.api.Distributor
import io.element.android.libraries.pushproviders.api.PushProvider

interface PushService {
// TODO Move away
fun notificationStyleChanged()

/**
* Return the current push provider, or null if none.
*/
Expand Down
1 change: 1 addition & 0 deletions libraries/push/impl/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ dependencies {
testImplementation(projects.libraries.matrix.test)
testImplementation(projects.libraries.push.test)
testImplementation(projects.libraries.pushproviders.test)
testImplementation(projects.libraries.pushstore.test)
testImplementation(projects.tests.testutils)
testImplementation(projects.services.appnavstate.test)
testImplementation(projects.services.toolbox.impl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import io.element.android.libraries.di.AppScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.push.api.GetCurrentPushProvider
import io.element.android.libraries.push.api.PushService
import io.element.android.libraries.push.impl.notifications.DefaultNotificationDrawerManager
import io.element.android.libraries.push.impl.test.TestPush
import io.element.android.libraries.pushproviders.api.Distributor
import io.element.android.libraries.pushproviders.api.PushProvider
import io.element.android.libraries.pushstore.api.UserPushStoreFactory
Expand All @@ -30,16 +30,11 @@ import javax.inject.Inject

@ContributesBinding(AppScope::class)
class DefaultPushService @Inject constructor(
private val defaultNotificationDrawerManager: DefaultNotificationDrawerManager,
private val pushersManager: PushersManager,
private val testPush: TestPush,
private val userPushStoreFactory: UserPushStoreFactory,
private val pushProviders: Set<@JvmSuppressWildcards PushProvider>,
private val getCurrentPushProvider: GetCurrentPushProvider,
) : PushService {
override fun notificationStyleChanged() {
defaultNotificationDrawerManager.notificationStyleChanged()
}

override suspend fun getCurrentPushProvider(): PushProvider? {
val currentPushProvider = getCurrentPushProvider.getCurrentPushProvider()
return pushProviders.find { it.name == currentPushProvider }
Expand All @@ -51,9 +46,6 @@ class DefaultPushService @Inject constructor(
.sortedBy { it.index }
}

/**
* Get current push provider, compare with provided one, then unregister and register if different, and store change.
*/
override suspend fun registerWith(
matrixClient: MatrixClient,
pushProvider: PushProvider,
Expand All @@ -80,7 +72,7 @@ class DefaultPushService @Inject constructor(
override suspend fun testPush(): Boolean {
val pushProvider = getCurrentPushProvider() ?: return false
val config = pushProvider.getCurrentUserPushConfig() ?: return false
pushersManager.testPush(config)
testPush.execute(config)
return true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,9 @@ import io.element.android.libraries.core.log.logger.LoggerTag
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.pusher.SetHttpPusherData
import io.element.android.libraries.matrix.api.pusher.UnsetHttpPusherData
import io.element.android.libraries.push.impl.pushgateway.PushGatewayNotifyRequest
import io.element.android.libraries.pushproviders.api.CurrentUserPushConfig
import io.element.android.libraries.pushproviders.api.PusherSubscriber
import io.element.android.libraries.pushstore.api.UserPushStoreFactory
import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret
Expand All @@ -37,29 +33,14 @@ import javax.inject.Inject

internal const val DEFAULT_PUSHER_FILE_TAG = "mobile"

private val loggerTag = LoggerTag("PushersManager", LoggerTag.PushLoggerTag)
private val loggerTag = LoggerTag("DefaultPusherSubscriber", LoggerTag.PushLoggerTag)

@ContributesBinding(AppScope::class)
class PushersManager @Inject constructor(
// private val localeProvider: LocaleProvider,
class DefaultPusherSubscriber @Inject constructor(
private val buildMeta: BuildMeta,
// private val getDeviceInfoUseCase: GetDeviceInfoUseCase,
private val pushGatewayNotifyRequest: PushGatewayNotifyRequest,
private val pushClientSecret: PushClientSecret,
private val userPushStoreFactory: UserPushStoreFactory,
) : PusherSubscriber {
suspend fun testPush(config: CurrentUserPushConfig) {
pushGatewayNotifyRequest.execute(
PushGatewayNotifyRequest.Params(
url = config.url,
appId = PushConfig.PUSHER_APP_ID,
pushKey = config.pushKey,
eventId = TEST_EVENT_ID,
roomId = TEST_ROOM_ID,
)
)
}

/**
* Register a pusher to the server if not done yet.
*/
Expand Down Expand Up @@ -131,9 +112,4 @@ class PushersManager @Inject constructor(
Timber.tag(loggerTag.value).e(throwable, "Unable to unregister the pusher")
}
}

companion object {
val TEST_EVENT_ID = EventId("\$THIS_IS_A_FAKE_EVENT_ID")
val TEST_ROOM_ID = RoomId("!room:domain")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ package io.element.android.libraries.push.impl.notifications
import android.content.Context
import android.net.Uri
import androidx.core.content.FileProvider
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.core.log.logger.LoggerTag
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.MatrixClientProvider
Expand Down Expand Up @@ -55,23 +57,28 @@ import io.element.android.services.toolbox.api.systemclock.SystemClock
import timber.log.Timber
import javax.inject.Inject

private val loggerTag = LoggerTag("NotifiableEventResolver", LoggerTag.NotificationLoggerTag)
private val loggerTag = LoggerTag("DefaultNotifiableEventResolver", LoggerTag.NotificationLoggerTag)

/**
* The notifiable event resolver is able to create a NotifiableEvent (view model for notifications) from an sdk Event.
* It is used as a bridge between the Event Thread and the NotificationDrawerManager.
* The NotifiableEventResolver is the only aware of session/store, the NotificationDrawerManager has no knowledge of that,
* this pattern allow decoupling between the object responsible of displaying notifications and the matrix sdk.
*/
class NotifiableEventResolver @Inject constructor(
interface NotifiableEventResolver {
suspend fun resolveEvent(sessionId: SessionId, roomId: RoomId, eventId: EventId): NotifiableEvent?
}

@ContributesBinding(AppScope::class)
class DefaultNotifiableEventResolver @Inject constructor(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe move this to a separate file in the api module?

private val stringProvider: StringProvider,
private val clock: SystemClock,
private val matrixClientProvider: MatrixClientProvider,
private val notificationMediaRepoFactory: NotificationMediaRepo.Factory,
@ApplicationContext private val context: Context,
private val permalinkParser: PermalinkParser,
) {
suspend fun resolveEvent(sessionId: SessionId, roomId: RoomId, eventId: EventId): NotifiableEvent? {
) : NotifiableEventResolver {
override suspend fun resolveEvent(sessionId: SessionId, roomId: RoomId, eventId: EventId): NotifiableEvent? {
// Restore session
val client = matrixClientProvider.getOrRestore(sessionId).getOrNull() ?: return null
val notificationService = client.notificationService()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,18 +221,6 @@ class DefaultNotificationDrawerManager @Inject constructor(
}
}

// TODO EAx Must be per account
fun notificationStyleChanged() {
updateEvents(doRender = true) {
val newSettings = true // pushDataStore.useCompleteNotificationFormat()
if (newSettings != useCompleteNotificationFormat) {
// Settings has changed, remove all current notifications
notificationRenderer.cancelAllNotifications()
useCompleteNotificationFormat = newSettings
}
}
}

private fun updateEvents(
doRender: Boolean,
action: (NotificationEventQueue) -> Unit,
Expand Down
Loading
Loading