Merge pull request #2416 from element-hq/feature/fga/add_some_analytics

Analytics : add analytics on read status and favorite toggles
This commit is contained in:
ganfra 2024-02-20 13:51:33 +01:00 committed by GitHub
commit dbc442e239
10 changed files with 93 additions and 29 deletions

View file

@ -27,6 +27,7 @@ import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.lifecycle.Lifecycle
import im.vector.app.features.analytics.plan.Interaction
import io.element.android.features.leaveroom.api.LeaveRoomEvent
import io.element.android.features.leaveroom.api.LeaveRoomPresenter
import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsPresenter
@ -46,6 +47,8 @@ import io.element.android.libraries.matrix.api.room.powerlevels.canInvite
import io.element.android.libraries.matrix.api.room.powerlevels.canSendState
import io.element.android.libraries.matrix.api.room.roomNotificationSettings
import io.element.android.libraries.matrix.ui.room.getDirectRoomMember
import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.analyticsproviders.api.trackers.captureInteraction
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@ -60,6 +63,7 @@ class RoomDetailsPresenter @Inject constructor(
private val roomMembersDetailsPresenterFactory: RoomMemberDetailsPresenter.Factory,
private val leaveRoomPresenter: LeaveRoomPresenter,
private val dispatchers: CoroutineDispatchers,
private val analyticsService: AnalyticsService,
) : Presenter<RoomDetailsState> {
@Composable
override fun present(): RoomDetailsState {
@ -124,11 +128,7 @@ class RoomDetailsPresenter @Inject constructor(
client.notificationSettingsService().unmuteRoom(room.roomId, room.isEncrypted, room.isOneToOne)
}
}
is RoomDetailsEvent.SetFavorite -> {
scope.launch {
room.setIsFavorite(event.isFavorite)
}
}
is RoomDetailsEvent.SetFavorite -> scope.setFavorite(event.isFavorite)
}
}
@ -187,4 +187,11 @@ class RoomDetailsPresenter @Inject constructor(
room.updateRoomNotificationSettings()
}.launchIn(this)
}
private fun CoroutineScope.setFavorite(isFavorite: Boolean) = launch {
room.setIsFavorite(isFavorite)
.onSuccess {
analyticsService.captureInteraction(Interaction.Name.MobileRoomFavouriteToggle)
}
}
}

View file

@ -22,6 +22,7 @@ import app.cash.molecule.moleculeFlow
import app.cash.turbine.TurbineTestContext
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import im.vector.app.features.analytics.plan.Interaction
import io.element.android.features.createroom.test.FakeStartDMAction
import io.element.android.features.leaveroom.api.LeaveRoomEvent
import io.element.android.features.leaveroom.api.LeaveRoomPresenter
@ -50,6 +51,8 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.tests.testutils.FakeLifecycleOwner
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.consumeItemsUntilPredicate
@ -77,6 +80,7 @@ class RoomDetailsPresenterTests {
leaveRoomPresenter: LeaveRoomPresenter = FakeLeaveRoomPresenter(),
dispatchers: CoroutineDispatchers = testCoroutineDispatchers(),
notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(),
analyticsService: AnalyticsService = FakeAnalyticsService(),
): RoomDetailsPresenter {
val matrixClient = FakeMatrixClient(notificationSettingsService = notificationSettingsService)
val roomMemberDetailsPresenterFactory = object : RoomMemberDetailsPresenter.Factory {
@ -95,6 +99,7 @@ class RoomDetailsPresenterTests {
roomMembersDetailsPresenterFactory = roomMemberDetailsPresenterFactory,
leaveRoomPresenter = leaveRoomPresenter,
dispatchers = dispatchers,
analyticsService = analyticsService,
)
}
@ -435,13 +440,18 @@ class RoomDetailsPresenterTests {
@Test
fun `present - when set is favorite event is emitted, then the action is called`() = runTest {
val room = FakeMatrixRoom()
val presenter = createRoomDetailsPresenter(room = room)
val analyticsService = FakeAnalyticsService()
val presenter = createRoomDetailsPresenter(room = room, analyticsService = analyticsService)
presenter.test {
val initialState = awaitItem()
initialState.eventSink(RoomDetailsEvent.SetFavorite(true))
assertThat(room.setIsFavoriteCalls).isEqualTo(listOf(true))
initialState.eventSink(RoomDetailsEvent.SetFavorite(false))
assertThat(room.setIsFavoriteCalls).isEqualTo(listOf(true, false))
assertThat(analyticsService.capturedEvents).containsExactly(
Interaction(name = Interaction.Name.MobileRoomFavouriteToggle),
Interaction(name = Interaction.Name.MobileRoomFavouriteToggle)
)
cancelAndIgnoreRemainingEvents()
}
}