Skip to content

Commit 5904810

Browse files
authored
Merge pull request #824 from android/tj/notification-analytics
Track when deep link notifications are opened
2 parents 04d3da3 + 4af8658 commit 5904810

File tree

4 files changed

+69
-1
lines changed

4 files changed

+69
-1
lines changed

core/testing/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,6 @@ dependencies {
4141
implementation(project(":core:domain"))
4242
implementation(project(":core:model"))
4343
implementation(project(":core:notifications"))
44+
implementation(project(":core:analytics"))
4445
implementation(libs.kotlinx.datetime)
4546
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright 2023 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.samples.apps.nowinandroid.core.testing.util
18+
19+
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent
20+
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper
21+
22+
class TestAnalyticsHelper : AnalyticsHelper {
23+
24+
private val events = mutableListOf<AnalyticsEvent>()
25+
override fun logEvent(event: AnalyticsEvent) {
26+
events.add(event)
27+
}
28+
29+
fun hasLogged(event: AnalyticsEvent) = events.contains(event)
30+
}

feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ package com.google.samples.apps.nowinandroid.feature.foryou
1919
import androidx.lifecycle.SavedStateHandle
2020
import androidx.lifecycle.ViewModel
2121
import androidx.lifecycle.viewModelScope
22+
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent
23+
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent.Param
24+
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper
2225
import com.google.samples.apps.nowinandroid.core.data.repository.NewsResourceQuery
2326
import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository
2427
import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository
@@ -42,6 +45,7 @@ import javax.inject.Inject
4245
class ForYouViewModel @Inject constructor(
4346
private val savedStateHandle: SavedStateHandle,
4447
syncManager: SyncManager,
48+
private val analyticsHelper: AnalyticsHelper,
4549
private val userDataRepository: UserDataRepository,
4650
userNewsResourceRepository: UserNewsResourceRepository,
4751
getFollowableTopics: GetFollowableTopicsUseCase,
@@ -127,6 +131,7 @@ class ForYouViewModel @Inject constructor(
127131
if (newsResourceId == deepLinkedNewsResource.value?.id) {
128132
savedStateHandle[LINKED_NEWS_RESOURCE_ID] = null
129133
}
134+
analyticsHelper.logNewsDeepLinkOpen(newsResourceId = newsResourceId)
130135
viewModelScope.launch {
131136
userDataRepository.setNewsResourceViewed(
132137
newsResourceId = newsResourceId,
@@ -141,3 +146,16 @@ class ForYouViewModel @Inject constructor(
141146
}
142147
}
143148
}
149+
150+
private fun AnalyticsHelper.logNewsDeepLinkOpen(newsResourceId: String) =
151+
logEvent(
152+
AnalyticsEvent(
153+
type = "news_deep_link_opened",
154+
extras = listOf(
155+
Param(
156+
key = LINKED_NEWS_RESOURCE_ID,
157+
value = newsResourceId,
158+
),
159+
),
160+
),
161+
)

feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
package com.google.samples.apps.nowinandroid.feature.foryou
1818

1919
import androidx.lifecycle.SavedStateHandle
20+
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent
21+
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent.Param
2022
import com.google.samples.apps.nowinandroid.core.data.repository.CompositeUserNewsResourceRepository
2123
import com.google.samples.apps.nowinandroid.core.domain.GetFollowableTopicsUseCase
2224
import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic
@@ -30,6 +32,7 @@ import com.google.samples.apps.nowinandroid.core.testing.repository.TestTopicsRe
3032
import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository
3133
import com.google.samples.apps.nowinandroid.core.testing.repository.emptyUserData
3234
import com.google.samples.apps.nowinandroid.core.testing.util.MainDispatcherRule
35+
import com.google.samples.apps.nowinandroid.core.testing.util.TestAnalyticsHelper
3336
import com.google.samples.apps.nowinandroid.core.testing.util.TestSyncManager
3437
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState
3538
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.LINKED_NEWS_RESOURCE_ID
@@ -44,6 +47,7 @@ import org.junit.Rule
4447
import org.junit.Test
4548
import kotlin.test.assertEquals
4649
import kotlin.test.assertNull
50+
import kotlin.test.assertTrue
4751

4852
/**
4953
* To learn more about how this test handles Flows created with stateIn, see
@@ -54,6 +58,7 @@ class ForYouViewModelTest {
5458
val mainDispatcherRule = MainDispatcherRule()
5559

5660
private val syncManager = TestSyncManager()
61+
private val analyticsHelper = TestAnalyticsHelper()
5762
private val userDataRepository = TestUserDataRepository()
5863
private val topicsRepository = TestTopicsRepository()
5964
private val newsRepository = TestNewsRepository()
@@ -74,6 +79,7 @@ class ForYouViewModelTest {
7479
viewModel = ForYouViewModel(
7580
syncManager = syncManager,
7681
savedStateHandle = savedStateHandle,
82+
analyticsHelper = analyticsHelper,
7783
userDataRepository = userDataRepository,
7884
userNewsResourceRepository = userNewsResourceRepository,
7985
getFollowableTopics = getFollowableTopicsUseCase,
@@ -253,7 +259,6 @@ class ForYouViewModelTest {
253259
assertEquals(
254260
NewsFeedUiState.Success(
255261
feed = emptyList(),
256-
257262
),
258263
viewModel.feedState.value,
259264
)
@@ -484,6 +489,20 @@ class ForYouViewModelTest {
484489
viewModel.deepLinkedNewsResource.value,
485490
)
486491

492+
assertTrue(
493+
analyticsHelper.hasLogged(
494+
AnalyticsEvent(
495+
type = "news_deep_link_opened",
496+
extras = listOf(
497+
Param(
498+
key = LINKED_NEWS_RESOURCE_ID,
499+
value = sampleNewsResources.first().id,
500+
),
501+
),
502+
),
503+
),
504+
)
505+
487506
collectJob.cancel()
488507
}
489508
}

0 commit comments

Comments
 (0)