Track when deep link notifications are opened

Change-Id: I223b1c8fbca36f9b7f2a35d9cb2fa901d6f5be91
pull/824/head
TJ Dahunsi 1 year ago
parent 89c4653115
commit c4686cfa54

@ -41,5 +41,6 @@ dependencies {
implementation(project(":core:domain")) implementation(project(":core:domain"))
implementation(project(":core:model")) implementation(project(":core:model"))
implementation(project(":core:notifications")) implementation(project(":core:notifications"))
implementation(project(":core:analytics"))
implementation(libs.kotlinx.datetime) implementation(libs.kotlinx.datetime)
} }

@ -0,0 +1,30 @@
/*
* Copyright 2023 The Android Open Source Project
*
* 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
*
* https://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 com.google.samples.apps.nowinandroid.core.testing.util
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper
class TestAnalyticsHelper : AnalyticsHelper {
private val events = mutableListOf<AnalyticsEvent>()
override fun logEvent(event: AnalyticsEvent) {
events.add(event)
}
fun hasLogged(event: AnalyticsEvent) = events.contains(event)
}

@ -19,6 +19,9 @@ package com.google.samples.apps.nowinandroid.feature.foryou
import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent.Param
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper
import com.google.samples.apps.nowinandroid.core.data.repository.NewsResourceQuery import com.google.samples.apps.nowinandroid.core.data.repository.NewsResourceQuery
import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository
import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository
@ -42,6 +45,7 @@ import javax.inject.Inject
class ForYouViewModel @Inject constructor( class ForYouViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle, private val savedStateHandle: SavedStateHandle,
syncManager: SyncManager, syncManager: SyncManager,
private val analyticsHelper: AnalyticsHelper,
private val userDataRepository: UserDataRepository, private val userDataRepository: UserDataRepository,
userNewsResourceRepository: UserNewsResourceRepository, userNewsResourceRepository: UserNewsResourceRepository,
getFollowableTopics: GetFollowableTopicsUseCase, getFollowableTopics: GetFollowableTopicsUseCase,
@ -127,6 +131,17 @@ class ForYouViewModel @Inject constructor(
if (newsResourceId == deepLinkedNewsResource.value?.id) { if (newsResourceId == deepLinkedNewsResource.value?.id) {
savedStateHandle[LINKED_NEWS_RESOURCE_ID] = null savedStateHandle[LINKED_NEWS_RESOURCE_ID] = null
} }
analyticsHelper.logEvent(
AnalyticsEvent(
type = "news_deep_link_opened",
extras = listOf(
Param(
key = LINKED_NEWS_RESOURCE_ID,
value = newsResourceId,
),
),
),
)
viewModelScope.launch { viewModelScope.launch {
userDataRepository.setNewsResourceViewed( userDataRepository.setNewsResourceViewed(
newsResourceId = newsResourceId, newsResourceId = newsResourceId,

@ -17,6 +17,8 @@
package com.google.samples.apps.nowinandroid.feature.foryou package com.google.samples.apps.nowinandroid.feature.foryou
import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.SavedStateHandle
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent.Param
import com.google.samples.apps.nowinandroid.core.data.repository.CompositeUserNewsResourceRepository import com.google.samples.apps.nowinandroid.core.data.repository.CompositeUserNewsResourceRepository
import com.google.samples.apps.nowinandroid.core.domain.GetFollowableTopicsUseCase import com.google.samples.apps.nowinandroid.core.domain.GetFollowableTopicsUseCase
import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic
@ -30,6 +32,7 @@ import com.google.samples.apps.nowinandroid.core.testing.repository.TestTopicsRe
import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository
import com.google.samples.apps.nowinandroid.core.testing.repository.emptyUserData import com.google.samples.apps.nowinandroid.core.testing.repository.emptyUserData
import com.google.samples.apps.nowinandroid.core.testing.util.MainDispatcherRule import com.google.samples.apps.nowinandroid.core.testing.util.MainDispatcherRule
import com.google.samples.apps.nowinandroid.core.testing.util.TestAnalyticsHelper
import com.google.samples.apps.nowinandroid.core.testing.util.TestSyncManager import com.google.samples.apps.nowinandroid.core.testing.util.TestSyncManager
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.LINKED_NEWS_RESOURCE_ID import com.google.samples.apps.nowinandroid.feature.foryou.navigation.LINKED_NEWS_RESOURCE_ID
@ -44,6 +47,7 @@ import org.junit.Rule
import org.junit.Test import org.junit.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertNull import kotlin.test.assertNull
import kotlin.test.assertTrue
/** /**
* To learn more about how this test handles Flows created with stateIn, see * To learn more about how this test handles Flows created with stateIn, see
@ -54,6 +58,7 @@ class ForYouViewModelTest {
val mainDispatcherRule = MainDispatcherRule() val mainDispatcherRule = MainDispatcherRule()
private val syncManager = TestSyncManager() private val syncManager = TestSyncManager()
private val analyticsHelper = TestAnalyticsHelper()
private val userDataRepository = TestUserDataRepository() private val userDataRepository = TestUserDataRepository()
private val topicsRepository = TestTopicsRepository() private val topicsRepository = TestTopicsRepository()
private val newsRepository = TestNewsRepository() private val newsRepository = TestNewsRepository()
@ -74,6 +79,7 @@ class ForYouViewModelTest {
viewModel = ForYouViewModel( viewModel = ForYouViewModel(
syncManager = syncManager, syncManager = syncManager,
savedStateHandle = savedStateHandle, savedStateHandle = savedStateHandle,
analyticsHelper = analyticsHelper,
userDataRepository = userDataRepository, userDataRepository = userDataRepository,
userNewsResourceRepository = userNewsResourceRepository, userNewsResourceRepository = userNewsResourceRepository,
getFollowableTopics = getFollowableTopicsUseCase, getFollowableTopics = getFollowableTopicsUseCase,
@ -253,7 +259,6 @@ class ForYouViewModelTest {
assertEquals( assertEquals(
NewsFeedUiState.Success( NewsFeedUiState.Success(
feed = emptyList(), feed = emptyList(),
), ),
viewModel.feedState.value, viewModel.feedState.value,
) )
@ -484,6 +489,20 @@ class ForYouViewModelTest {
viewModel.deepLinkedNewsResource.value, viewModel.deepLinkedNewsResource.value,
) )
assertTrue(
analyticsHelper.hasLogged(
AnalyticsEvent(
type = "news_deep_link_opened",
extras = listOf(
Param(
key = LINKED_NEWS_RESOURCE_ID,
value = sampleNewsResources.first().id,
),
),
),
),
)
collectJob.cancel() collectJob.cancel()
} }
} }

Loading…
Cancel
Save