From cffbde3e35d506bd7eb030a5f7baf8d095cd0941 Mon Sep 17 00:00:00 2001 From: Omer Habib <30689349+omerhabib26@users.noreply.github.com> Date: Mon, 1 Apr 2024 15:05:36 +0500 Subject: [PATCH] fix: Analytics Improvements + Update test cases (#277) - Updated the analytics with iOS parity - Updated test cases --- .../course/presentation/CourseAnalytics.kt | 4 +- .../container/CourseContainerViewModelTest.kt | 14 ++--- .../detail/CourseDetailsViewModelTest.kt | 42 +++++++++++++-- .../outline/CourseOutlineViewModelTest.kt | 16 ++++-- .../unit/video/VideoUnitViewModelTest.kt | 35 ++++++++++-- .../unit/video/VideoViewModelTest.kt | 53 ++++++++++++++----- 6 files changed, 129 insertions(+), 35 deletions(-) diff --git a/course/src/main/java/org/openedx/course/presentation/CourseAnalytics.kt b/course/src/main/java/org/openedx/course/presentation/CourseAnalytics.kt index ce0dafef5..53291c460 100644 --- a/course/src/main/java/org/openedx/course/presentation/CourseAnalytics.kt +++ b/course/src/main/java/org/openedx/course/presentation/CourseAnalytics.kt @@ -139,7 +139,7 @@ enum class CourseAnalyticsEvent(val eventName: String, val biValue: String) { ), PLS_BANNER_VIEWED( "PLS:Banner Viewed", - "edx.bi.app.coursedates.pls_banner.viewed" + "edx.bi.app.dates.pls_banner.viewed" ), PLS_SHIFT_BUTTON_CLICKED( "PLS:Shift Button Clicked", @@ -147,7 +147,7 @@ enum class CourseAnalyticsEvent(val eventName: String, val biValue: String) { ), PLS_SHIFT_DATES( "PLS:Shift Dates", - "edx.bi.app.coursedates.pls_banner.shift_dates" + "edx.bi.app.dates.pls_banner.shift_dates" ), DATES_CALENDAR_SYNC_TOGGLE( "Dates:CalendarSync Toggle", diff --git a/course/src/test/java/org/openedx/course/presentation/container/CourseContainerViewModelTest.kt b/course/src/test/java/org/openedx/course/presentation/container/CourseContainerViewModelTest.kt index 0e94b5cc3..0dc214f81 100644 --- a/course/src/test/java/org/openedx/course/presentation/container/CourseContainerViewModelTest.kt +++ b/course/src/test/java/org/openedx/course/presentation/container/CourseContainerViewModelTest.kt @@ -36,6 +36,7 @@ import org.openedx.core.system.notifier.CourseStructureUpdated import org.openedx.course.data.storage.CoursePreferences import org.openedx.course.domain.interactor.CourseInteractor import org.openedx.course.presentation.CourseAnalytics +import org.openedx.course.presentation.CourseAnalyticsEvent import org.openedx.course.presentation.calendarsync.CalendarManager import java.net.UnknownHostException import java.util.Date @@ -136,12 +137,12 @@ class CourseContainerViewModelTest { ) every { networkConnection.isOnline() } returns true coEvery { interactor.preloadCourseStructure(any()) } throws UnknownHostException() - every { analytics.logEvent(any(), any()) } returns Unit + every { analytics.logEvent(CourseAnalyticsEvent.DASHBOARD.eventName, any()) } returns Unit viewModel.preloadCourseStructure() advanceUntilIdle() coVerify(exactly = 1) { interactor.preloadCourseStructure(any()) } - verify(exactly = 1) { analytics.logEvent(any(), any()) } + verify(exactly = 1) { analytics.logEvent(CourseAnalyticsEvent.DASHBOARD.eventName, any()) } val message = viewModel.errorMessage.value assertEquals(noInternet, message) @@ -167,12 +168,12 @@ class CourseContainerViewModelTest { ) every { networkConnection.isOnline() } returns true coEvery { interactor.preloadCourseStructure(any()) } throws Exception() - every { analytics.logEvent(any(), any()) } returns Unit + every { analytics.logEvent(CourseAnalyticsEvent.DASHBOARD.eventName, any()) } returns Unit viewModel.preloadCourseStructure() advanceUntilIdle() coVerify(exactly = 1) { interactor.preloadCourseStructure(any()) } - verify(exactly = 1) { analytics.logEvent(any(), any()) } + verify(exactly = 1) { analytics.logEvent(CourseAnalyticsEvent.DASHBOARD.eventName, any()) } val message = viewModel.errorMessage.value assertEquals(somethingWrong, message) @@ -199,12 +200,12 @@ class CourseContainerViewModelTest { every { networkConnection.isOnline() } returns true coEvery { interactor.preloadCourseStructure(any()) } returns Unit every { interactor.getCourseStructureFromCache() } returns courseStructure - every { analytics.logEvent(any(), any()) } returns Unit + every { analytics.logEvent(CourseAnalyticsEvent.DASHBOARD.eventName, any()) } returns Unit viewModel.preloadCourseStructure() advanceUntilIdle() coVerify(exactly = 1) { interactor.preloadCourseStructure(any()) } - verify(exactly = 1) { analytics.logEvent(any(), any()) } + verify(exactly = 1) { analytics.logEvent(CourseAnalyticsEvent.DASHBOARD.eventName, any()) } assert(viewModel.errorMessage.value == null) assert(viewModel.showProgress.value == false) @@ -325,5 +326,4 @@ class CourseContainerViewModelTest { assert(viewModel.errorMessage.value == null) assert(viewModel.showProgress.value == false) } - } diff --git a/course/src/test/java/org/openedx/course/presentation/detail/CourseDetailsViewModelTest.kt b/course/src/test/java/org/openedx/course/presentation/detail/CourseDetailsViewModelTest.kt index 458d7b7bf..c5dbd2696 100644 --- a/course/src/test/java/org/openedx/course/presentation/detail/CourseDetailsViewModelTest.kt +++ b/course/src/test/java/org/openedx/course/presentation/detail/CourseDetailsViewModelTest.kt @@ -33,6 +33,7 @@ import org.openedx.core.system.notifier.CourseDashboardUpdate import org.openedx.core.system.notifier.CourseNotifier import org.openedx.course.domain.interactor.CourseInteractor import org.openedx.course.presentation.CourseAnalytics +import org.openedx.course.presentation.CourseAnalyticsEvent import java.net.UnknownHostException @OptIn(ExperimentalCoroutinesApi::class) @@ -239,14 +240,24 @@ class CourseDetailsViewModelTest { coEvery { notifier.send(CourseDashboardUpdate()) } returns Unit every { networkConnection.isOnline() } returns true coEvery { interactor.getCourseDetails(any()) } returns mockCourse - every { analytics.logEvent(any(), any()) } returns Unit + every { + analytics.logEvent( + CourseAnalyticsEvent.COURSE_ENROLL_CLICKED.eventName, + any() + ) + } returns Unit viewModel.enrollInACourse("", "") advanceUntilIdle() coVerify(exactly = 1) { interactor.enrollInACourse(any()) } - verify(exactly = 1) { analytics.logEvent(any(), any()) } + verify(exactly = 1) { + analytics.logEvent( + CourseAnalyticsEvent.COURSE_ENROLL_CLICKED.eventName, + any() + ) + } val message = viewModel.uiMessage.value as? UIMessage.SnackBarMessage assertEquals(somethingWrong, message?.message) @@ -267,7 +278,18 @@ class CourseDetailsViewModelTest { ) every { config.isPreLoginExperienceEnabled() } returns false every { preferencesManager.user } returns null - every { analytics.logEvent(any(), any()) } returns Unit + every { + analytics.logEvent( + CourseAnalyticsEvent.COURSE_ENROLL_CLICKED.eventName, + any() + ) + } returns Unit + every { + analytics.logEvent( + CourseAnalyticsEvent.COURSE_ENROLL_SUCCESS.eventName, + any() + ) + } returns Unit coEvery { interactor.enrollInACourse(any()) } returns Unit coEvery { notifier.send(CourseDashboardUpdate()) } returns Unit every { networkConnection.isOnline() } returns true @@ -279,7 +301,18 @@ class CourseDetailsViewModelTest { advanceUntilIdle() coVerify(exactly = 1) { interactor.enrollInACourse(any()) } - verify(exactly = 2) { analytics.logEvent(any(), any()) } + verify(exactly = 1) { + analytics.logEvent( + CourseAnalyticsEvent.COURSE_ENROLL_CLICKED.eventName, + any() + ) + } + verify(exactly = 1) { + analytics.logEvent( + CourseAnalyticsEvent.COURSE_ENROLL_SUCCESS.eventName, + any() + ) + } assert(viewModel.uiMessage.value == null) assert(viewModel.uiState.value is CourseDetailsUIState.CourseData) @@ -318,5 +351,4 @@ class CourseDetailsViewModelTest { val count = overview.contains("black") assert(!count) } - } diff --git a/course/src/test/java/org/openedx/course/presentation/outline/CourseOutlineViewModelTest.kt b/course/src/test/java/org/openedx/course/presentation/outline/CourseOutlineViewModelTest.kt index e72101887..174e8ea4f 100644 --- a/course/src/test/java/org/openedx/course/presentation/outline/CourseOutlineViewModelTest.kt +++ b/course/src/test/java/org/openedx/course/presentation/outline/CourseOutlineViewModelTest.kt @@ -47,6 +47,7 @@ import org.openedx.core.module.db.DownloadModelEntity import org.openedx.core.module.db.DownloadedState import org.openedx.core.module.db.FileType import org.openedx.core.presentation.CoreAnalytics +import org.openedx.core.presentation.CoreAnalyticsEvent import org.openedx.core.system.ResourceManager import org.openedx.core.system.connection.NetworkConnection import org.openedx.core.system.notifier.CourseNotifier @@ -439,7 +440,12 @@ class CourseOutlineViewModelTest { every { interactor.getCourseStructureFromCache() } returns courseStructure every { networkConnection.isWifiConnected() } returns true every { networkConnection.isOnline() } returns true - every { coreAnalytics.logEvent(any(), any()) } returns Unit + every { + coreAnalytics.logEvent( + CoreAnalyticsEvent.VIDEO_DOWNLOAD_SUBSECTION.eventName, + any() + ) + } returns Unit coEvery { workerController.saveModels(any()) } returns Unit coEvery { interactor.getCourseStatus(any()) } returns CourseComponentStatus("id") coEvery { downloadDao.readAllData() } returns flow { emit(emptyList()) } @@ -461,7 +467,12 @@ class CourseOutlineViewModelTest { viewModel.saveDownloadModels("", "") advanceUntilIdle() - verify(exactly = 1) { coreAnalytics.logEvent(any(), any()) } + verify(exactly = 1) { + coreAnalytics.logEvent( + CoreAnalyticsEvent.VIDEO_DOWNLOAD_SUBSECTION.eventName, + any() + ) + } assert(viewModel.uiMessage.value == null) } @@ -530,5 +541,4 @@ class CourseOutlineViewModelTest { assert(viewModel.uiMessage.value != null) assert(!viewModel.hasInternetConnection) } - } diff --git a/course/src/test/java/org/openedx/course/presentation/unit/video/VideoUnitViewModelTest.kt b/course/src/test/java/org/openedx/course/presentation/unit/video/VideoUnitViewModelTest.kt index 498094d03..4270dba82 100644 --- a/course/src/test/java/org/openedx/course/presentation/unit/video/VideoUnitViewModelTest.kt +++ b/course/src/test/java/org/openedx/course/presentation/unit/video/VideoUnitViewModelTest.kt @@ -12,7 +12,11 @@ import io.mockk.verify import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.test.* +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.advanceUntilIdle +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain import org.junit.After import org.junit.Before import org.junit.Rule @@ -24,6 +28,7 @@ import org.openedx.core.system.notifier.CourseNotifier import org.openedx.core.system.notifier.CourseVideoPositionChanged import org.openedx.course.data.repository.CourseRepository import org.openedx.course.presentation.CourseAnalytics +import org.openedx.course.presentation.CourseAnalyticsEvent @OptIn(ExperimentalCoroutinesApi::class) class VideoUnitViewModelTest { @@ -66,7 +71,12 @@ class VideoUnitViewModelTest { any() ) } throws Exception() - every { courseAnalytics.logEvent(any(), any()) } returns Unit + every { + courseAnalytics.logEvent( + CourseAnalyticsEvent.VIDEO_COMPLETED.eventName, + any() + ) + } returns Unit viewModel.markBlockCompleted("", "") advanceUntilIdle() @@ -76,7 +86,12 @@ class VideoUnitViewModelTest { any() ) } - verify(exactly = 1) { courseAnalytics.logEvent(any(), any()) } + verify(exactly = 1) { + courseAnalytics.logEvent( + CourseAnalyticsEvent.VIDEO_COMPLETED.eventName, + any() + ) + } } @Test @@ -95,7 +110,12 @@ class VideoUnitViewModelTest { any() ) } returns Unit - every { courseAnalytics.logEvent(any(), any()) } returns Unit + every { + courseAnalytics.logEvent( + CourseAnalyticsEvent.VIDEO_COMPLETED.eventName, + any() + ) + } returns Unit viewModel.markBlockCompleted("", "") advanceUntilIdle() @@ -105,7 +125,12 @@ class VideoUnitViewModelTest { any() ) } - verify(exactly = 1) { courseAnalytics.logEvent(any(), any()) } + verify(exactly = 1) { + courseAnalytics.logEvent( + CourseAnalyticsEvent.VIDEO_COMPLETED.eventName, + any() + ) + } } @Test diff --git a/course/src/test/java/org/openedx/course/presentation/unit/video/VideoViewModelTest.kt b/course/src/test/java/org/openedx/course/presentation/unit/video/VideoViewModelTest.kt index 278e24380..3f476fe29 100644 --- a/course/src/test/java/org/openedx/course/presentation/unit/video/VideoViewModelTest.kt +++ b/course/src/test/java/org/openedx/course/presentation/unit/video/VideoViewModelTest.kt @@ -1,9 +1,6 @@ package org.openedx.course.presentation.unit.video import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import org.openedx.core.system.notifier.CourseNotifier -import org.openedx.core.system.notifier.CourseVideoPositionChanged -import org.openedx.course.data.repository.CourseRepository import io.mockk.coEvery import io.mockk.coVerify import io.mockk.every @@ -11,14 +8,22 @@ import io.mockk.mockk import io.mockk.verify import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.* +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.advanceUntilIdle +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule import org.openedx.core.data.storage.CorePreferences +import org.openedx.core.system.notifier.CourseNotifier +import org.openedx.core.system.notifier.CourseVideoPositionChanged +import org.openedx.course.data.repository.CourseRepository import org.openedx.course.presentation.CourseAnalytics +import org.openedx.course.presentation.CourseAnalyticsEvent @OptIn(ExperimentalCoroutinesApi::class) class VideoViewModelTest { @@ -45,7 +50,8 @@ class VideoViewModelTest { @Test fun `sendTime test`() = runTest { - val viewModel = VideoViewModel("", courseRepository, notifier, preferenceManager, courseAnalytics) + val viewModel = + VideoViewModel("", courseRepository, notifier, preferenceManager, courseAnalytics) coEvery { notifier.send(CourseVideoPositionChanged("", 0, false)) } returns Unit viewModel.sendTime() advanceUntilIdle() @@ -55,14 +61,20 @@ class VideoViewModelTest { @Test fun `markBlockCompleted exception`() = runTest { - val viewModel = VideoViewModel("", courseRepository, notifier, preferenceManager, courseAnalytics) + val viewModel = + VideoViewModel("", courseRepository, notifier, preferenceManager, courseAnalytics) coEvery { courseRepository.markBlocksCompletion( any(), any() ) } throws Exception() - every { courseAnalytics.logEvent(any(), any()) } returns Unit + every { + courseAnalytics.logEvent( + CourseAnalyticsEvent.VIDEO_COMPLETED.eventName, + any() + ) + } returns Unit viewModel.markBlockCompleted("", "") advanceUntilIdle() @@ -72,20 +84,31 @@ class VideoViewModelTest { any() ) } - verify(exactly = 1) { courseAnalytics.logEvent(any(), any()) } + verify(exactly = 1) { + courseAnalytics.logEvent( + CourseAnalyticsEvent.VIDEO_COMPLETED.eventName, + any() + ) + } } @Test fun `markBlockCompleted success`() = runTest { - val viewModel = VideoViewModel("", courseRepository, notifier, preferenceManager, courseAnalytics) + val viewModel = + VideoViewModel("", courseRepository, notifier, preferenceManager, courseAnalytics) coEvery { courseRepository.markBlocksCompletion( any(), any() ) } returns Unit - every { courseAnalytics.logEvent(any(), any()) } returns Unit + every { + courseAnalytics.logEvent( + CourseAnalyticsEvent.VIDEO_COMPLETED.eventName, + any() + ) + } returns Unit viewModel.markBlockCompleted("", "") advanceUntilIdle() @@ -95,7 +118,11 @@ class VideoViewModelTest { any() ) } - verify(exactly = 1) { courseAnalytics.logEvent(any(), any()) } + verify(exactly = 1) { + courseAnalytics.logEvent( + CourseAnalyticsEvent.VIDEO_COMPLETED.eventName, + any() + ) + } } - -} \ No newline at end of file +}