Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSD - Today's Stats Card - Metrics #15965

Merged
merged 11 commits into from
Feb 18, 2022
2 changes: 1 addition & 1 deletion WordPress/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ android {
buildConfigField "boolean", "RECOMMEND_THE_APP", "false"
buildConfigField "boolean", "UNIFIED_COMMENTS_COMMENT_EDIT", "false"
buildConfigField "boolean", "MY_SITE_DASHBOARD_PHASE_2", "false"
buildConfigField "boolean", "MY_SITE_DASHBOARD_STATS_CARD", "false"
buildConfigField "boolean", "MY_SITE_DASHBOARD_TODAYS_STATS_CARD", "false"
buildConfigField "boolean", "UNIFIED_COMMENTS_DETAILS", "false"
buildConfigField "boolean", "UNIFIED_ABOUT", "false"
buildConfigField "boolean", "COMMENTS_SNIPPET", "false"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper;
import org.wordpress.android.util.analytics.AnalyticsUtils;
import org.wordpress.android.util.analytics.service.InstallationReferrerServiceStarter;
import org.wordpress.android.util.config.MySiteDashboardTodaysStatsCardFeatureConfig;
import org.wordpress.android.viewmodel.main.WPMainActivityViewModel;
import org.wordpress.android.viewmodel.main.WPMainActivityViewModel.FocusPointInfo;
import org.wordpress.android.viewmodel.mlp.ModalLayoutPickerViewModel;
Expand Down Expand Up @@ -225,6 +226,7 @@ public class WPMainActivity extends LocaleAwareActivity implements
@Inject AnalyticsTrackerWrapper mAnalyticsTrackerWrapper;
@Inject CreateSiteNotificationScheduler mCreateSiteNotificationScheduler;
@Inject WeeklyRoundupScheduler mWeeklyRoundupScheduler;
@Inject MySiteDashboardTodaysStatsCardFeatureConfig mTodaysStatsCardFeatureConfig;

@Inject BuildConfigWrapper mBuildConfigWrapper;

Expand Down Expand Up @@ -975,7 +977,12 @@ private void trackLastVisiblePage(PageType pageType, boolean trackAnalytics) {
case MY_SITE:
ActivityId.trackLastActivity(ActivityId.MY_SITE);
if (trackAnalytics) {
mAnalyticsTrackerWrapper.track(AnalyticsTracker.Stat.MY_SITE_ACCESSED, getSelectedSite());
// Added today's stats feature config to check if my site tab is accessed more often in AB testing
mAnalyticsTrackerWrapper.track(
AnalyticsTracker.Stat.MY_SITE_ACCESSED,
getSelectedSite(),
mTodaysStatsCardFeatureConfig
);
}
break;
case READER:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import org.wordpress.android.analytics.AnalyticsTracker.Stat.MY_SITE_PULL_TO_REF
import org.wordpress.android.fluxc.model.DynamicCardType
import org.wordpress.android.fluxc.model.MediaModel
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.model.experiments.Variation.Control
import org.wordpress.android.fluxc.model.dashboard.CardModel.PostsCardModel
import org.wordpress.android.fluxc.model.dashboard.CardModel.TodaysStatsCardModel
import org.wordpress.android.fluxc.model.experiments.Variation.Control
import org.wordpress.android.fluxc.store.AccountStore
import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartTask
import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartTaskType
Expand Down Expand Up @@ -328,9 +328,15 @@ class MySiteViewModel @Inject constructor(
return orderForDisplay(infoItem, cardsResult, dynamicCards, siteItems)
}

private fun onTodaysStatsCardFooterLinkClick() = navigateToTodaysStats()
private fun onTodaysStatsCardFooterLinkClick() {
cardsTracker.trackTodaysStatsCardFooterLinkClicked()
navigateToTodaysStats()
}

private fun onTodaysStatsCardClick() = navigateToTodaysStats()
private fun onTodaysStatsCardClick() {
cardsTracker.trackTodaysStatsCardClicked()
navigateToTodaysStats()
}

private fun navigateToTodaysStats() {
val selectedSite = requireNotNull(selectedSiteRepository.getSelectedSite())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.DashboardCards.Das
import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.DashboardCards.DashboardCard.PostCard.PostCardWithoutPostItems
import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.DashboardCards.DashboardCard.TodaysStatsCard
import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.DashboardCards.DashboardCard.TodaysStatsCard.TodaysStatsCardWithData
import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker.StatsSubtype
import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker.Type
import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper
import javax.inject.Inject
Expand Down Expand Up @@ -38,13 +39,13 @@ class CardsShownTracker @Inject constructor(
is TodaysStatsCard.Error -> trackCardShown(
Pair(
card.dashboardCardType.toTypeValue().label,
Type.TODAYS_STATS.label
StatsSubtype.TODAYS_STATS.label
)
)
is TodaysStatsCardWithData -> trackCardShown(
Pair(
card.dashboardCardType.toTypeValue().label,
Type.TODAYS_STATS.label
StatsSubtype.TODAYS_STATS.label
)
)
is PostCard.Error -> trackCardShown(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import org.wordpress.android.ui.mysite.MySiteSource.MySiteRefreshSource
import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.CardsUpdate
import org.wordpress.android.ui.mysite.SelectedSiteRepository
import org.wordpress.android.ui.mysite.cards.dashboard.mockdata.MockedDataJsonUtils
import org.wordpress.android.util.config.MySiteDashboardStatsCardFeatureConfig
import org.wordpress.android.util.config.MySiteDashboardTodaysStatsCardFeatureConfig
import javax.inject.Inject
import javax.inject.Named

Expand All @@ -25,7 +25,7 @@ const val REFRESH_DELAY = 500L
class CardsSource @Inject constructor(
private val selectedSiteRepository: SelectedSiteRepository,
private val cardsStore: CardsStore,
private val statsCardFeatureConfig: MySiteDashboardStatsCardFeatureConfig,
private val todaysStatsCardFeatureConfig: MySiteDashboardTodaysStatsCardFeatureConfig,
mockedDataJsonUtils: MockedDataJsonUtils,
@param:Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher
) : MySiteRefreshSource<CardsUpdate> {
Expand All @@ -48,7 +48,7 @@ class CardsSource @Inject constructor(
val selectedSite = selectedSiteRepository.getSelectedSite()
if (selectedSite != null && selectedSite.id == siteLocalId) {
coroutineScope.launch(bgDispatcher) {
if (statsCardFeatureConfig.isEnabled()) {
if (todaysStatsCardFeatureConfig.isEnabled()) {
postValue(CardsUpdate(mockedCardsData))
} else {
cardsStore.getCards(selectedSite).collect { result ->
Expand Down Expand Up @@ -90,7 +90,7 @@ class CardsSource @Inject constructor(
) {
coroutineScope.launch(bgDispatcher) {
delay(REFRESH_DELAY)
if (statsCardFeatureConfig.isEnabled()) {
if (todaysStatsCardFeatureConfig.isEnabled()) {
postState(CardsUpdate(mockedCardsData))
} else {
val result = cardsStore.fetchCards(selectedSite)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,35 @@ class CardsTracker @Inject constructor(
) {
enum class Type(val label: String) {
ERROR("error"),
TODAYS_STATS("todays_stats"),
STATS("stats"),
POST("post")
}

enum class StatsSubtype(val label: String) {
TODAYS_STATS("todays_stats")
}

enum class PostSubtype(val label: String) {
CREATE_FIRST("create_first"),
CREATE_NEXT("create_next"),
DRAFT("draft"),
SCHEDULED("scheduled")
}

fun trackTodaysStatsCardFooterLinkClicked() {
trackCardFooterLinkClicked(Type.STATS.label, StatsSubtype.TODAYS_STATS.label)
}

fun trackTodaysStatsCardClicked() {
trackCardItemClicked(Type.STATS.label, StatsSubtype.TODAYS_STATS.label)
}

fun trackPostCardFooterLinkClicked(postCardType: PostCardType) {
trackCardFooterLinkClicked(Type.POST.label, postCardType.toSubtypeValue().label)
}

fun trackPostItemClicked(postCardType: PostCardType) {
trackCardPostItemClicked(Type.POST.label, postCardType.toSubtypeValue().label)
trackCardItemClicked(Type.POST.label, postCardType.toSubtypeValue().label)
}

private fun trackCardFooterLinkClicked(type: String, subtype: String) {
Expand All @@ -44,7 +56,7 @@ class CardsTracker @Inject constructor(
)
}

private fun trackCardPostItemClicked(type: String, subtype: String) {
private fun trackCardItemClicked(type: String, subtype: String) {
ashiagr marked this conversation as resolved.
Show resolved Hide resolved
analyticsTrackerWrapper.track(
Stat.MY_SITE_DASHBOARD_CARD_ITEM_TAPPED,
mapOf(
Expand All @@ -65,14 +77,15 @@ class CardsTracker @Inject constructor(
companion object {
const val TYPE = "type"
const val SUBTYPE = "subtype"
const val STATS = "stats"
}
}

fun DashboardCardType.toTypeValue(): Type {
return when (this) {
DashboardCardType.ERROR_CARD -> Type.ERROR
DashboardCardType.TODAYS_STATS_CARD_ERROR -> Type.ERROR
DashboardCardType.TODAYS_STATS_CARD -> Type.TODAYS_STATS
DashboardCardType.TODAYS_STATS_CARD -> Type.STATS
DashboardCardType.POST_CARD_ERROR -> Type.ERROR
DashboardCardType.POST_CARD_WITHOUT_POST_ITEMS -> Type.POST
DashboardCardType.POST_CARD_WITH_POST_ITEMS -> Type.POST
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ class SiteItemsTracker @Inject constructor(
private val analyticsTrackerWrapper: AnalyticsTrackerWrapper
) {
enum class Type(val label: String) {
POSTS("posts")
POSTS("posts"),
STATS("stats")
}

fun trackSiteItemClicked(listItemAction: ListItemAction) = trackSiteItemClicked(listItemAction.toTypeValue())
Expand All @@ -23,6 +24,7 @@ class SiteItemsTracker @Inject constructor(
private fun ListItemAction.toTypeValue(): Type? {
return when (this) {
ListItemAction.POSTS -> Type.POSTS
ListItemAction.STATS -> Type.STATS
else -> null
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import org.wordpress.android.ui.stats.refresh.utils.trackGranular
import org.wordpress.android.ui.utils.UiString.UiStringRes
import org.wordpress.android.util.NetworkUtilsWrapper
import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper
import org.wordpress.android.util.config.MySiteDashboardTodaysStatsCardFeatureConfig
import org.wordpress.android.util.mapNullable
import org.wordpress.android.util.mergeNotNull
import org.wordpress.android.viewmodel.Event
Expand All @@ -66,7 +67,8 @@ class StatsViewModel
private val statsSiteProvider: StatsSiteProvider,
newsCardHandler: NewsCardHandler,
private val statsModuleActivateUseCase: StatsModuleActivateUseCase,
private val notificationsTracker: SystemNotificationsTracker
private val notificationsTracker: SystemNotificationsTracker,
private val todaysStatsCardFeatureConfig: MySiteDashboardTodaysStatsCardFeatureConfig
) : ScopedViewModel(mainDispatcher) {
private val _isRefreshing = MutableLiveData<Boolean>()
val isRefreshing: LiveData<Boolean> = _isRefreshing
Expand Down Expand Up @@ -148,7 +150,12 @@ class StatsViewModel
selectedDateProvider.setInitialSelectedPeriod(initialGranularity, initialSelectedPeriod)
}

analyticsTracker.track(AnalyticsTracker.Stat.STATS_ACCESSED, statsSiteProvider.siteModel)
// Added today's stats feature config to check whether that card is enabled when stats screen is accessed
analyticsTracker.track(
stat = AnalyticsTracker.Stat.STATS_ACCESSED,
site = statsSiteProvider.siteModel,
feature = todaysStatsCardFeatureConfig
)

if (launchedFromWidget) {
analyticsTracker.track(AnalyticsTracker.Stat.STATS_WIDGET_TAPPED, statsSiteProvider.siteModel)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ class AnalyticsTrackerWrapper
AnalyticsUtils.trackWithSiteDetails(this, stat, site, properties)
}

fun track(stat: Stat, site: SiteModel?, feature: FeatureConfig) {
AnalyticsUtils.trackWithSiteDetails(this, stat, site, feature.toParams().toMutableMap<String, Any>())
}

/**
* A convenience method for logging an error event with some additional meta data.
* @param stat The stat to track.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import javax.inject.Inject
* Configuration of the 'My Site Dashboard - Stats Card' that will add Stats Card on the 'My Site' screen.
*/
@FeatureInDevelopment
class MySiteDashboardStatsCardFeatureConfig @Inject constructor(
class MySiteDashboardTodaysStatsCardFeatureConfig @Inject constructor(
appConfig: AppConfig
) : FeatureConfig(
appConfig,
BuildConfig.MY_SITE_DASHBOARD_STATS_CARD
BuildConfig.MY_SITE_DASHBOARD_TODAYS_STATS_CARD
)
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import org.wordpress.android.testScope
import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.CardsUpdate
import org.wordpress.android.ui.mysite.SelectedSiteRepository
import org.wordpress.android.ui.mysite.cards.dashboard.mockdata.MockedDataJsonUtils
import org.wordpress.android.util.config.MySiteDashboardStatsCardFeatureConfig
import org.wordpress.android.util.config.MySiteDashboardTodaysStatsCardFeatureConfig

/* SITE */

Expand Down Expand Up @@ -80,7 +80,7 @@ class CardsSourceTest : BaseUnitTest() {
@Mock private lateinit var selectedSiteRepository: SelectedSiteRepository
@Mock private lateinit var cardsStore: CardsStore
@Mock private lateinit var siteModel: SiteModel
@Mock private lateinit var statsCardFeatureConfig: MySiteDashboardStatsCardFeatureConfig
@Mock private lateinit var todaysStatsCardFeatureConfig: MySiteDashboardTodaysStatsCardFeatureConfig
@Mock private lateinit var mockedDataJsonUtils: MockedDataJsonUtils
private lateinit var cardSource: CardsSource

Expand All @@ -100,7 +100,7 @@ class CardsSourceTest : BaseUnitTest() {
cardSource = CardsSource(
selectedSiteRepository,
cardsStore,
statsCardFeatureConfig,
todaysStatsCardFeatureConfig,
mockedDataJsonUtils,
TEST_DISPATCHER
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner
import org.wordpress.android.analytics.AnalyticsTracker.Stat
import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker.PostSubtype
import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker.StatsSubtype
import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker.Type
import org.wordpress.android.ui.mysite.cards.dashboard.posts.PostCardType
import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper
Expand All @@ -26,65 +27,79 @@ class CardsTrackerTest {
cardsTracker = CardsTracker(cardsShownTracker, analyticsTracker)
}

@Test
fun `when today's stats card footer link is clicked, then today's stats card footer click event is tracked`() {
cardsTracker.trackTodaysStatsCardFooterLinkClicked()

verifyFooterLinkClickedTracked(Type.STATS, StatsSubtype.TODAYS_STATS.label)
}

@Test
fun `when today's stats card is clicked, then today's stats card item click event is tracked`() {
cardsTracker.trackTodaysStatsCardClicked()

verifyCardItemClickedTracked(Type.STATS, StatsSubtype.TODAYS_STATS.label)
}

@Test
fun `when post create first footer link is clicked, then post create first event is tracked`() {
cardsTracker.trackPostCardFooterLinkClicked(PostCardType.CREATE_FIRST)

verifyFooterLinkClickedTracked(Type.POST, PostSubtype.CREATE_FIRST)
verifyFooterLinkClickedTracked(Type.POST, PostSubtype.CREATE_FIRST.label)
}

@Test
fun `when post create next footer link is clicked, then post create next event is tracked`() {
cardsTracker.trackPostCardFooterLinkClicked(PostCardType.CREATE_NEXT)

verifyFooterLinkClickedTracked(Type.POST, PostSubtype.CREATE_NEXT)
verifyFooterLinkClickedTracked(Type.POST, PostSubtype.CREATE_NEXT.label)
}

@Test
fun `when post draft footer link is clicked, then post draft event is tracked`() {
cardsTracker.trackPostCardFooterLinkClicked(PostCardType.DRAFT)

verifyFooterLinkClickedTracked(Type.POST, PostSubtype.DRAFT)
verifyFooterLinkClickedTracked(Type.POST, PostSubtype.DRAFT.label)
}

@Test
fun `when post scheduled footer link is clicked, then post scheduled event is tracked`() {
cardsTracker.trackPostCardFooterLinkClicked(PostCardType.SCHEDULED)

verifyFooterLinkClickedTracked(Type.POST, PostSubtype.SCHEDULED)
verifyFooterLinkClickedTracked(Type.POST, PostSubtype.SCHEDULED.label)
}

@Test
fun `when post draft item is clicked, then post item event is tracked`() {
cardsTracker.trackPostItemClicked(PostCardType.DRAFT)

verifyPostItemClickedTracked(Type.POST, PostSubtype.DRAFT)
verifyCardItemClickedTracked(Type.POST, PostSubtype.DRAFT.label)
}

@Test
fun `when post scheduled item is clicked, then post item event is tracked`() {
cardsTracker.trackPostItemClicked(PostCardType.SCHEDULED)

verifyPostItemClickedTracked(Type.POST, PostSubtype.SCHEDULED)
verifyCardItemClickedTracked(Type.POST, PostSubtype.SCHEDULED.label)
}

private fun verifyFooterLinkClickedTracked(
typeValue: Type,
subtypeValue: PostSubtype
subtypeValue: String
) {
verify(analyticsTracker).track(
Stat.MY_SITE_DASHBOARD_CARD_FOOTER_ACTION_TAPPED,
mapOf(TYPE to typeValue.label, SUBTYPE to subtypeValue.label)
mapOf(TYPE to typeValue.label, SUBTYPE to subtypeValue)
)
}

private fun verifyPostItemClickedTracked(
private fun verifyCardItemClickedTracked(
typeValue: Type,
subtypeValue: PostSubtype
subtypeValue: String
) {
verify(analyticsTracker).track(
Stat.MY_SITE_DASHBOARD_CARD_ITEM_TAPPED,
mapOf(TYPE to typeValue.label, SUBTYPE to subtypeValue.label)
mapOf(TYPE to typeValue.label, SUBTYPE to subtypeValue)
)
}
}
Loading