Skip to content

Commit

Permalink
fix: Analytics events improvements & Add missing ones (#46)
Browse files Browse the repository at this point in the history
* fix: Payment Analytics
I have removed the extra space after the colon in Payment Events, ensuring consistency with the other analytics.

- refactor: Add the learn tab event
- fix: `MainDashboard:Learn` & `Learn:My Courses` were sent multiple times on `LearnFragment` resume.
- fix: trigger missing home tab event with course dashboard event
- fix: unit test cases

Fixes: LEARNER-10192

---------

Co-authored-by: Farhan Arshad <[email protected]>
  • Loading branch information
HamzaIsrar12 and farhan-arshad-dev authored Sep 12, 2024
1 parent b67f6f8 commit 4220f1e
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 65 deletions.
4 changes: 4 additions & 0 deletions app/src/main/java/org/openedx/app/AppAnalytics.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ enum class AppAnalyticsEvent(val eventName: String, val biValue: String) {
"Launch",
"edx.bi.app.launch"
),
LEARN(
"MainDashboard:Learn",
"edx.bi.app.main_dashboard.learn"
),
DISCOVER(
"MainDashboard:Discover",
"edx.bi.app.main_dashboard.discover"
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/java/org/openedx/app/MainFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class MainFragment : Fragment(R.layout.fragment_main) {
binding.bottomNavView.setOnItemSelectedListener {
when (it.itemId) {
R.id.fragmentLearn -> {
viewModel.logLearnTabClickedEvent()
binding.viewPager.setCurrentItem(0, false)
}

Expand Down Expand Up @@ -89,7 +90,7 @@ class MainFragment : Fragment(R.layout.fragment_main) {
putString(ARG_INFO_TYPE, "")
}

when (requireArguments().getString(ARG_OPEN_TAB, HomeTab.LEARN.name)) {
when (requireArguments().getString(ARG_OPEN_TAB, "")) {
HomeTab.LEARN.name,
HomeTab.PROGRAMS.name -> {
binding.bottomNavView.selectedItemId = R.id.fragmentLearn
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/org/openedx/app/MainViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ class MainViewModel(
_isBottomBarEnabled.value = enable
}

fun logLearnTabClickedEvent() {
logScreenEvent(AppAnalyticsEvent.LEARN)
}

fun logDiscoveryTabClickedEvent() {
logScreenEvent(AppAnalyticsEvent.DISCOVER)
}
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/java/org/openedx/app/di/ScreenModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,9 @@ val screenModule = module {
)
}
viewModel { AllEnrolledCoursesViewModel(get(), get(), get(), get(), get(), get(), get()) }
viewModel { LearnViewModel(get(), get(), get()) }
viewModel { (openTab: String) ->
LearnViewModel(openTab, get(), get(), get())
}

factory { DiscoveryRepository(get(), get(), get()) }
factory { DiscoveryInteractor(get()) }
Expand Down
20 changes: 10 additions & 10 deletions core/src/main/java/org/openedx/core/presentation/IAPAnalytics.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,43 +13,43 @@ interface IAPAnalytics {
enum class IAPAnalyticsEvent(val eventName: String, val biValue: String) {
// In App Purchases Events
IAP_UPGRADE_NOW_CLICKED(
"Payments: Upgrade Now Clicked",
"Payments:Upgrade Now Clicked",
"edx.bi.app.payments.upgrade_now.clicked"
),
IAP_COURSE_UPGRADE_SUCCESS(
"Payments: Course Upgrade Success",
"Payments:Course Upgrade Success",
"edx.bi.app.payments.course_upgrade_success"
),
IAP_PAYMENT_ERROR(
"Payments: Payment Error",
"Payments:Payment Error",
"edx.bi.app.payments.payment_error"
),
IAP_PAYMENT_CANCELED(
"Payments: Canceled by User",
"Payments:Canceled by User",
"edx.bi.app.payments.canceled_by_user"
),
IAP_COURSE_UPGRADE_ERROR(
"Payments: Course Upgrade Error",
"Payments:Course Upgrade Error",
"edx.bi.app.payments.course_upgrade_error"
),
IAP_PRICE_LOAD_ERROR(
"Payments: Price Load Error",
"Payments:Price Load Error",
"edx.bi.app.payments.price_load_error"
),
IAP_ERROR_ALERT_ACTION(
"Payments: Error Alert Action",
"Payments:Error Alert Action",
"edx.bi.app.payments.error_alert_action"
),
IAP_UNFULFILLED_PURCHASE_INITIATED(
"Payments: Unfulfilled Purchase Initiated",
"Payments:Unfulfilled Purchase Initiated",
"edx.bi.app.payments.unfulfilled_purchase.initiated"
),
IAP_RESTORE_PURCHASE_CLICKED(
"Payments: Restore Purchases Clicked",
"Payments:Restore Purchases Clicked",
"edx.bi.app.payments.restore_purchases.clicked"
),
IAP_VALUE_PROP_VIEWED(
"Payments: Value Prop Viewed",
"Payments:Value Prop Viewed",
"edx.bi.app.payments.value_prop.viewed"
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,7 @@ class CourseContainerViewModel(

private fun courseDashboardViewed() {
logCourseContainerEvent(CourseAnalyticsEvent.DASHBOARD)
courseTabClickedEvent()
}

private fun courseTabClickedEvent() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@ class CourseContainerViewModelTest {
any()
)
} returns Unit
every {
analytics.logScreenEvent(
CourseAnalyticsEvent.HOME_TAB.eventName,
any()
)
} returns Unit
viewModel.fetchCourseDetails()
advanceUntilIdle()

Expand All @@ -277,6 +283,12 @@ class CourseContainerViewModelTest {
any()
)
}
verify(exactly = 1) {
analytics.logScreenEvent(
CourseAnalyticsEvent.HOME_TAB.eventName,
any()
)
}
assert(!viewModel.refreshing.value)
assert(viewModel.courseAccessStatus.value == CourseAccessError.UNKNOWN)
}
Expand Down Expand Up @@ -309,6 +321,12 @@ class CourseContainerViewModelTest {
any()
)
} returns Unit
every {
analytics.logScreenEvent(
CourseAnalyticsEvent.HOME_TAB.eventName,
any()
)
} returns Unit
viewModel.fetchCourseDetails()
advanceUntilIdle()

Expand All @@ -319,6 +337,12 @@ class CourseContainerViewModelTest {
any()
)
}
verify(exactly = 1) {
analytics.logScreenEvent(
CourseAnalyticsEvent.HOME_TAB.eventName,
any()
)
}
assert(viewModel.errorMessage.value == null)
assert(!viewModel.refreshing.value)
assert(viewModel.courseAccessStatus.value != null)
Expand Down Expand Up @@ -352,6 +376,12 @@ class CourseContainerViewModelTest {
any()
)
} returns Unit
every {
analytics.logScreenEvent(
CourseAnalyticsEvent.HOME_TAB.eventName,
any()
)
} returns Unit
viewModel.fetchCourseDetails()
advanceUntilIdle()
coVerify(exactly = 0) { courseApi.getEnrollmentDetails(any()) }
Expand All @@ -361,6 +391,12 @@ class CourseContainerViewModelTest {
any()
)
}
verify(exactly = 1) {
analytics.logScreenEvent(
CourseAnalyticsEvent.HOME_TAB.eventName,
any()
)
}

assert(viewModel.errorMessage.value == null)
assert(!viewModel.refreshing.value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ interface DashboardAnalytics {

enum class DashboardAnalyticsEvent(val eventName: String, val biValue: String) {
MY_COURSES(
"MainDashboard:My Courses",
"edx.bi.app.main_dashboard.my_course"
"Learn:My Courses",
"edx.bi.app.main_dashboard.learn.my_course"
),
MY_PROGRAMS(
"MainDashboard:My Programs",
"edx.bi.app.main_dashboard.my_program"
"Learn:My Programs",
"edx.bi.app.main_dashboard.learn.my_programs"
),
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ExpandMore
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
Expand All @@ -29,7 +29,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
Expand All @@ -39,6 +38,7 @@ import androidx.fragment.app.Fragment
import androidx.viewpager2.widget.ViewPager2
import org.koin.androidx.compose.koinViewModel
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
import org.openedx.core.adapter.NavigationFragmentAdapter
import org.openedx.core.presentation.global.viewBinding
import org.openedx.core.ui.crop
Expand All @@ -56,23 +56,28 @@ import org.openedx.learn.LearnType
class LearnFragment : Fragment(R.layout.fragment_learn) {

private val binding by viewBinding(FragmentLearnBinding::bind)
private val viewModel by viewModel<LearnViewModel>()
private val viewModel by viewModel<LearnViewModel> {
parametersOf(requireArguments().getString(ARG_OPEN_TAB, LearnTab.COURSES.name))
}
private lateinit var adapter: NavigationFragmentAdapter

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initViewPager()
val openTab = requireArguments().getString(ARG_OPEN_TAB, LearnTab.COURSES.name)
val defaultLearnType = if (openTab == LearnTab.PROGRAMS.name) {
LearnType.PROGRAMS
} else {
LearnType.COURSES
}
binding.header.setContent {
OpenEdXTheme {
val uiState by viewModel.uiState.collectAsState()
binding.viewPager.setCurrentItem(
when (uiState.learnType) {
LearnType.COURSES -> 0
LearnType.PROGRAMS -> 1
}, false
)
Header(
defaultLearnType = defaultLearnType,
viewPager = binding.viewPager
selectedLearnType = uiState.learnType,
onUpdateLearnType = { learnType ->
viewModel.updateLearnType(learnType)
},
)
}
}
Expand All @@ -88,17 +93,6 @@ class LearnFragment : Fragment(R.layout.fragment_learn) {
}
binding.viewPager.adapter = adapter
binding.viewPager.setUserInputEnabled(false)

binding.viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
if (LearnType.COURSES.ordinal == position) {
viewModel.logMyCoursesTabClickedEvent()
} else {
viewModel.logMyProgramsTabClickedEvent()
}
}
})
}

companion object {
Expand All @@ -117,8 +111,8 @@ class LearnFragment : Fragment(R.layout.fragment_learn) {

@Composable
private fun Header(
defaultLearnType: LearnType,
viewPager: ViewPager2,
selectedLearnType: LearnType,
onUpdateLearnType: (LearnType) -> Unit
) {
val viewModel: LearnViewModel = koinViewModel()
val windowSize = rememberWindowSize()
Expand Down Expand Up @@ -147,8 +141,8 @@ private fun Header(
modifier = Modifier
.align(Alignment.Start)
.padding(horizontal = 16.dp),
defaultLearnType = defaultLearnType,
viewPager = viewPager
selectedLearnType = selectedLearnType,
onUpdateLearnType = onUpdateLearnType
)
}
}
Expand Down Expand Up @@ -176,25 +170,15 @@ private fun Title(
@Composable
private fun LearnDropdownMenu(
modifier: Modifier = Modifier,
defaultLearnType: LearnType,
viewPager: ViewPager2,
selectedLearnType: LearnType,
onUpdateLearnType: (LearnType) -> Unit
) {
var expanded by remember { mutableStateOf(false) }
var currentValue by remember { mutableStateOf(defaultLearnType) }
val iconRotation by animateFloatAsState(
targetValue = if (expanded) 180f else 0f,
label = ""
)

LaunchedEffect(currentValue) {
viewPager.setCurrentItem(
when (currentValue) {
LearnType.COURSES -> 0
LearnType.PROGRAMS -> 1
}, false
)
}

Column(
modifier = modifier
) {
Expand All @@ -206,7 +190,7 @@ private fun LearnDropdownMenu(
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = stringResource(id = currentValue.title),
text = stringResource(id = selectedLearnType.title),
color = MaterialTheme.appColors.textDark,
style = MaterialTheme.appTypography.titleSmall
)
Expand Down Expand Up @@ -236,17 +220,16 @@ private fun LearnDropdownMenu(
onDismissRequest = { expanded = false }
) {
for (learnType in LearnType.entries) {
val background: Color
if (currentValue == learnType) {
background = MaterialTheme.appColors.surface
val background: Color = if (selectedLearnType == learnType) {
MaterialTheme.appColors.surface
} else {
background = MaterialTheme.appColors.background
MaterialTheme.appColors.background
}
DropdownMenuItem(
modifier = Modifier
.background(background),
onClick = {
currentValue = learnType
onUpdateLearnType(learnType)
expanded = false
}
) {
Expand Down Expand Up @@ -274,10 +257,9 @@ private fun HeaderPreview() {
@Composable
private fun LearnDropdownMenuPreview() {
OpenEdXTheme {
val context = LocalContext.current
LearnDropdownMenu(
defaultLearnType = LearnType.COURSES,
viewPager = ViewPager2(context)
selectedLearnType = LearnType.COURSES,
onUpdateLearnType = {}
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.openedx.learn.presentation

import org.openedx.learn.LearnType

data class LearnUIState(val learnType: LearnType)
Loading

0 comments on commit 4220f1e

Please sign in to comment.