Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -147,22 +147,6 @@ enum class AnalyticsEvent(override val siteless: Boolean = false) : IAnalyticsEv
LOGIN_JETPACK_SITE_CREDENTIAL_RESET_PASSWORD_BUTTON_TAPPED(siteless = true),
LOGIN_JETPACK_SITE_CREDENTIAL_DID_SHOW_ERROR_ALERT(siteless = true),
LOGIN_JETPACK_SITE_CREDENTIAL_DID_FINISH_LOGIN(siteless = true),
LOGIN_JETPACK_SETUP_SCREEN_VIEWED(siteless = true),
LOGIN_JETPACK_SETUP_SCREEN_DISMISSED(siteless = true),
LOGIN_JETPACK_SETUP_INSTALL_SUCCESSFUL(siteless = true),
LOGIN_JETPACK_SETUP_INSTALL_FAILED(siteless = true),
LOGIN_JETPACK_SETUP_ACTIVATION_SUCCESSFUL(siteless = true),
LOGIN_JETPACK_SETUP_ACTIVATION_FAILED(siteless = true),
LOGIN_JETPACK_SETUP_FETCH_JETPACK_CONNECTION_URL_SUCCESSFUL(siteless = true),
LOGIN_JETPACK_SETUP_FETCH_JETPACK_CONNECTION_URL_FAILED(siteless = true),
LOGIN_JETPACK_SETUP_CANNOT_FIND_WPCOM_USER(siteless = true),
LOGIN_JETPACK_SETUP_AUTHORIZED_USING_DIFFERENT_WPCOM_ACCOUNT(siteless = true),
LOGIN_JETPACK_SETUP_ALL_STEPS_MARKED_DONE(siteless = true),
LOGIN_JETPACK_SETUP_ERROR_CHECKING_JETPACK_CONNECTION(siteless = true),
LOGIN_JETPACK_SETUP_GO_TO_STORE_BUTTON_TAPPED(siteless = true),
LOGIN_JETPACK_FETCHING_WPCOM_SITES_FAILED(siteless = true),
LOGIN_JETPACK_SETUP_GET_SUPPORT_BUTTON_TAPPED(siteless = true),
LOGIN_JETPACK_SETUP_TRY_AGAIN_BUTTON_TAPPED(siteless = true),

// -- Dashboard
DASHBOARD_PULLED_TO_REFRESH,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ class AnalyticsTracker private constructor(
const val VALUE_JETPACK_SETUP_TAP_GO_TO_STORE = "go_to_store"
const val VALUE_JETPACK_SETUP_TAP_SUPPORT = "support"
const val VALUE_JETPACK_SETUP_TAP_TRY_AGAIN = "try_again"
const val VALUE_JETPACK_SETUP_TAP_CONTINUE_SETUP = "continue_setup"
const val KEY_CONNECTION_TYPE = "connection_type"
const val VALUE_CONNECTION_TYPE_NATIVE = "native"
const val VALUE_CONNECTION_TYPE_WEB = "web"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package com.woocommerce.android.ui.login.jetpack

import com.woocommerce.android.OnChangedException
import com.woocommerce.android.WooException
import com.woocommerce.android.analytics.AnalyticsEvent
import com.woocommerce.android.analytics.AnalyticsTrackerWrapper
import com.woocommerce.android.model.JetpackConnectionStatus
import com.woocommerce.android.model.JetpackSiteRegistrationStatus
import com.woocommerce.android.tools.SelectedSite
Expand All @@ -26,8 +24,7 @@ class JetpackActivationRepository @Inject constructor(
private val siteStore: SiteStore,
private val jetpackStore: JetpackStore,
private val wooCommerceStore: WooCommerceStore,
private val selectedSite: SelectedSite,
private val analyticsTrackerWrapper: AnalyticsTrackerWrapper
private val selectedSite: SelectedSite
) {
companion object {
private const val DEFAULT_MAX_RETRY = 2
Expand Down Expand Up @@ -134,9 +131,6 @@ class JetpackActivationRepository @Inject constructor(
}

result.data?.currentUser?.wpcomEmail.isNullOrEmpty() -> {
analyticsTrackerWrapper.track(
stat = AnalyticsEvent.LOGIN_JETPACK_SETUP_CANNOT_FIND_WPCOM_USER
)
WooLog.w(WooLog.T.LOGIN, "Cannot find Jetpack Email in response")
Result.failure(JetpackMissingConnectionEmailException())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,36 +145,18 @@ class JetpackActivationMainViewModel @Inject constructor(
}.asLiveData()

init {
if (!useApplicationPasswords) {
analyticsTrackerWrapper.track(AnalyticsEvent.LOGIN_JETPACK_SETUP_SCREEN_VIEWED)
}

monitorCurrentStep()
handleErrorStates()
startNextStep()
}

fun onCloseClick() {
if (useApplicationPasswords) {
trackSetupFlow(tap = AnalyticsTracker.VALUE_DISMISS)
} else {
analyticsTrackerWrapper.track(
stat = AnalyticsEvent.LOGIN_JETPACK_SETUP_SCREEN_DISMISSED,
properties = mapOf(
AnalyticsTracker.KEY_JETPACK_INSTALLATION_STEP to
currentStep.value.type.analyticsName
)
)
}
trackSetupFlow(tap = AnalyticsTracker.VALUE_DISMISS)
triggerEvent(Exit)
}

fun onContinueClick() = launch {
if (useApplicationPasswords) {
trackSetupFlow(tap = AnalyticsTracker.VALUE_JETPACK_SETUP_TAP_GO_TO_STORE)
} else {
analyticsTrackerWrapper.track(stat = AnalyticsEvent.LOGIN_JETPACK_SETUP_GO_TO_STORE_BUTTON_TAPPED)
}
trackSetupFlow(tap = AnalyticsTracker.VALUE_JETPACK_SETUP_TAP_GO_TO_STORE)

val loggedInEmail = accountRepository.getUserAccount()?.email
if (jetpackConnectedEmail == loggedInEmail) {
Expand All @@ -184,9 +166,7 @@ class JetpackActivationMainViewModel @Inject constructor(
jetpackActivationRepository.setSelectedSiteAndCleanOldSites(site)
triggerEvent(GoToStore)

if (useApplicationPasswords) {
analyticsTrackerWrapper.track(stat = AnalyticsEvent.JETPACK_SETUP_SYNCHRONIZATION_COMPLETED)
}
analyticsTrackerWrapper.track(stat = AnalyticsEvent.JETPACK_SETUP_SYNCHRONIZATION_COMPLETED)
} else {
triggerEvent(ShowWooNotInstalledScreen(navArgs.siteUrl))
}
Expand All @@ -210,32 +190,14 @@ class JetpackActivationMainViewModel @Inject constructor(
}

fun onRetryClick() {
if (useApplicationPasswords) {
trackSetupFlow(tap = AnalyticsTracker.VALUE_JETPACK_SETUP_TAP_TRY_AGAIN)
} else {
analyticsTrackerWrapper.track(
stat = AnalyticsEvent.LOGIN_JETPACK_SETUP_TRY_AGAIN_BUTTON_TAPPED,
properties = mapOf(
AnalyticsTracker.KEY_JETPACK_INSTALLATION_STEP to
currentStep.value.type.analyticsName
)
)
}
trackSetupFlow(tap = AnalyticsTracker.VALUE_JETPACK_SETUP_TAP_TRY_AGAIN)

startNextStep()
}

fun onGetHelpClick() {
if (useApplicationPasswords) {
trackSetupFlow(tap = AnalyticsTracker.VALUE_JETPACK_SETUP_TAP_SUPPORT)
} else {
analyticsTrackerWrapper.track(
stat = AnalyticsEvent.LOGIN_JETPACK_SETUP_GET_SUPPORT_BUTTON_TAPPED,
properties = mapOf(
AnalyticsTracker.KEY_JETPACK_INSTALLATION_STEP to
currentStep.value.type.analyticsName
),
)
}
trackSetupFlow(tap = AnalyticsTracker.VALUE_JETPACK_SETUP_TAP_SUPPORT)

triggerEvent(NavigateToHelpScreen(JETPACK_INSTALLATION))
}

Expand Down Expand Up @@ -263,9 +225,7 @@ class JetpackActivationMainViewModel @Inject constructor(
val stepType = step.type
WooLog.d(WooLog.T.LOGIN, "Jetpack Activation: handle step: $stepType")

if (useApplicationPasswords) {
trackSetupFlow()
}
trackSetupFlow()

when (stepType) {
StepType.Installation -> {
Expand Down Expand Up @@ -294,13 +254,7 @@ class JetpackActivationMainViewModel @Inject constructor(
}

StepType.Done -> {
if (useApplicationPasswords) {
analyticsTrackerWrapper.track(stat = AnalyticsEvent.JETPACK_SETUP_COMPLETED)
} else {
analyticsTrackerWrapper.track(
stat = AnalyticsEvent.LOGIN_JETPACK_SETUP_ALL_STEPS_MARKED_DONE
)
}
analyticsTrackerWrapper.track(stat = AnalyticsEvent.JETPACK_SETUP_COMPLETED)

currentStep.value = Step(
type = StepType.Done,
Expand Down Expand Up @@ -335,76 +289,32 @@ class JetpackActivationMainViewModel @Inject constructor(
).collect { status ->
when (status) {
is PluginInstalled -> {
if (!useApplicationPasswords) {
analyticsTrackerWrapper.track(AnalyticsEvent.LOGIN_JETPACK_SETUP_INSTALL_SUCCESSFUL)
}
currentStep.value = Step(type = StepType.Activation, state = StepState.Ongoing)
}

is PluginInstallFailed -> {
trackPluginInstallationError(status)
trackSetupFlow(failure = "Jetpack installation failed: $status")
currentStep.update { state -> state.copy(state = StepState.Error(status.errorCode)) }
}

is PluginActivated -> {
if (!useApplicationPasswords) {
analyticsTrackerWrapper.track(AnalyticsEvent.LOGIN_JETPACK_SETUP_ACTIVATION_SUCCESSFUL)
}
currentStep.value = Step(type = StepType.Connection, state = StepState.Ongoing)
}

is PluginActivationFailed -> {
trackPluginActivationError(status)
trackSetupFlow(failure = "Jetpack activation failed: $status")
currentStep.update { state -> state.copy(state = StepState.Error(status.errorCode)) }
}
}
}
}

private fun trackPluginActivationError(status: PluginActivationFailed) {
if (useApplicationPasswords) {
trackSetupFlow(failure = "Jetpack activation failed: $status")
} else {
analyticsTrackerWrapper.track(
stat = AnalyticsEvent.LOGIN_JETPACK_SETUP_ACTIVATION_FAILED,
properties = mapOf(AnalyticsTracker.KEY_ERROR_CODE to status.errorCode.toString()),
errorContext = this@JetpackActivationMainViewModel::class.simpleName,
errorType = status.errorType,
errorDescription = status.errorDescription
)
}
}

private fun trackPluginInstallationError(status: PluginInstallFailed) {
if (useApplicationPasswords) {
trackSetupFlow(failure = "Jetpack installation failed: $status")
} else {
analyticsTrackerWrapper.track(
stat = AnalyticsEvent.LOGIN_JETPACK_SETUP_INSTALL_FAILED,
properties = mapOf(AnalyticsTracker.KEY_ERROR_CODE to status.errorCode.toString()),
errorContext = this@JetpackActivationMainViewModel::class.simpleName,
errorType = status.errorType,
errorDescription = status.errorDescription
)
}
}

@Suppress("LongMethod")
private suspend fun startJetpackConnection() {
val onFailure: (Throwable) -> Unit = {
val error = (it as? OnChangedException)?.error as? JetpackStore.JetpackError

if (useApplicationPasswords) {
trackSetupFlow(failure = "Jetpack connection failed: ${it.message}")
} else {
analyticsTrackerWrapper.track(
stat = AnalyticsEvent.LOGIN_JETPACK_SETUP_FETCH_JETPACK_CONNECTION_URL_FAILED,
properties = mapOf(AnalyticsTracker.KEY_ERROR_CODE to error?.errorCode.toString()),
errorContext = this@JetpackActivationMainViewModel::class.simpleName,
errorType = it::class.simpleName,
errorDescription = it.message.orEmpty()
)
}
trackSetupFlow(failure = "Jetpack connection failed: ${it.message}")
currentStep.update { state -> state.copy(state = StepState.Error(error?.errorCode)) }
}

Expand Down Expand Up @@ -436,12 +346,6 @@ class JetpackActivationMainViewModel @Inject constructor(
val currentSite = site.await()
jetpackActivationRepository.fetchJetpackConnectionUrl(currentSite, useApplicationPasswords).fold(
onSuccess = { connectionUrl ->
if (!useApplicationPasswords) {
analyticsTrackerWrapper.track(
stat = AnalyticsEvent.LOGIN_JETPACK_SETUP_FETCH_JETPACK_CONNECTION_URL_SUCCESSFUL
)
}

if (useApplicationPasswords) {
// Depending on the site's connection status, we should provide different URLs to the webview.
// If the site is already registered with WordPress.com, we can use the API-given URL as-is. We
Expand Down Expand Up @@ -493,11 +397,6 @@ class JetpackActivationMainViewModel @Inject constructor(
onSuccess = { email ->
jetpackConnectedEmail = email
if (accountRepository.getUserAccount()?.email != email) {
if (!useApplicationPasswords) {
analyticsTrackerWrapper.track(
stat = AnalyticsEvent.LOGIN_JETPACK_SETUP_AUTHORIZED_USING_DIFFERENT_WPCOM_ACCOUNT
)
}
WooLog.d(
WooLog.T.LOGIN,
"Jetpack Activation: connection made using a different email than the logged in one"
Expand All @@ -510,17 +409,7 @@ class JetpackActivationMainViewModel @Inject constructor(
onFailure = {
val error = (it as? OnChangedException)?.error as? JetpackStore.JetpackError

if (useApplicationPasswords) {
trackSetupFlow(failure = "Jetpack connection validation failed: ${it.message}")
} else {
analyticsTrackerWrapper.track(
stat = AnalyticsEvent.LOGIN_JETPACK_SETUP_ERROR_CHECKING_JETPACK_CONNECTION,
properties = mapOf(AnalyticsTracker.KEY_ERROR_CODE to error?.errorCode.toString()),
errorContext = this@JetpackActivationMainViewModel::class.simpleName,
errorType = it::class.simpleName,
errorDescription = it.message.orEmpty()
)
}
trackSetupFlow(failure = "Jetpack connection validation failed: ${it.message}")
currentStep.update { state -> state.copy(state = StepState.Error(error?.errorCode)) }
if (it is JetpackActivationRepository.JetpackMissingConnectionEmailException) {
// If we can't find a connected email, we can't confirm the site connection. Let's
Expand All @@ -538,16 +427,8 @@ class JetpackActivationMainViewModel @Inject constructor(
connectionStep.value = ConnectionStep.Approved
},
onFailure = {
if (useApplicationPasswords) {
trackSetupFlow(failure = "Site connection confirmation failed: ${it.message}")
} else {
analyticsTrackerWrapper.track(
stat = AnalyticsEvent.LOGIN_JETPACK_FETCHING_WPCOM_SITES_FAILED,
errorContext = this@JetpackActivationMainViewModel::class.simpleName,
errorType = it::class.simpleName,
errorDescription = it.message.orEmpty()
)
}
trackSetupFlow(failure = "Site connection confirmation failed: ${it.message}")

currentStep.update { state -> state.copy(state = StepState.Error(null)) }
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,15 @@ class JetpackActivationStartViewModel @Inject constructor(

fun onHelpButtonClick() {
analyticsTrackerWrapper.track(
stat = AnalyticsEvent.LOGIN_JETPACK_SETUP_GET_SUPPORT_BUTTON_TAPPED,
stat = AnalyticsEvent.JETPACK_SETUP_FLOW,
properties = mapOf(
AnalyticsTracker.KEY_JETPACK_INSTALLATION_STEP to
AnalyticsTracker.KEY_STEP to if (navArgs.jetpackStatus.isJetpackInstalled) {
JetpackActivationMainViewModel.StepType.Connection.analyticsName
),
} else {
JetpackActivationMainViewModel.StepType.Installation.analyticsName
},
AnalyticsTracker.KEY_TAP to AnalyticsTracker.VALUE_JETPACK_SETUP_TAP_SUPPORT,
)
)
triggerEvent(NavigateToHelpScreen(JETPACK_INSTALLATION))
}
Expand All @@ -80,12 +84,13 @@ class JetpackActivationStartViewModel @Inject constructor(
fun onContinueButtonClick() {
if (isConnectionDismissed.value) {
analyticsTrackerWrapper.track(
stat = AnalyticsEvent.LOGIN_JETPACK_SETUP_TRY_AGAIN_BUTTON_TAPPED,
stat = AnalyticsEvent.JETPACK_SETUP_FLOW,
properties = mapOf(
AnalyticsTracker.KEY_JETPACK_INSTALLATION_STEP to
JetpackActivationMainViewModel.StepType.Connection.analyticsName
AnalyticsTracker.KEY_STEP to JetpackActivationMainViewModel.StepType.Connection.analyticsName,
AnalyticsTracker.KEY_TAP to AnalyticsTracker.VALUE_JETPACK_SETUP_TAP_CONTINUE_SETUP,
)
)

isConnectionDismissed.value = false
triggerEvent(
ContinueJetpackConnection(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.woocommerce.android.ui.login.jetpack

import com.woocommerce.android.analytics.AnalyticsTrackerWrapper
import com.woocommerce.android.model.JetpackConnectionStatus
import com.woocommerce.android.model.JetpackSiteRegistrationStatus
import com.woocommerce.android.tools.SelectedSite
Expand Down Expand Up @@ -29,15 +28,13 @@ class JetpackActivationRepositoryTest : BaseUnitTest() {
}
private val wooCommerceStore: WooCommerceStore = mock()
private val selectedSite: SelectedSite = mock()
private val analyticsTracker: AnalyticsTrackerWrapper = mock()

private val repository = JetpackActivationRepository(
dispatcher = dispatcher,
siteStore = siteStore,
jetpackStore = jetpackStore,
wooCommerceStore = wooCommerceStore,
selectedSite = selectedSite,
analyticsTrackerWrapper = analyticsTracker
selectedSite = selectedSite
)

@Test
Expand Down