Skip to content

Commit 11fcaa6

Browse files
authored
Merge pull request #4998 from woocommerce/add/missing-jetpack-screen-events
Add Events for "Jetpack Required" Screen
2 parents 2afc61f + 50c4ad5 commit 11fcaa6

File tree

10 files changed

+280
-47
lines changed

10 files changed

+280
-47
lines changed

WooCommerce/Classes/Analytics/WooAnalyticsStat.swift

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -28,45 +28,50 @@ public enum WooAnalyticsStat: String {
2828

2929
// MARK: Authentication Events
3030
//
31-
case signedIn = "signed_in"
32-
case logout = "account_logout"
33-
case openedLogin = "login_accessed"
34-
case loginFailed = "login_failed_to_login"
35-
case loginAutoFillCredentialsFilled = "login_autofill_credentials_filled"
36-
case loginAutoFillCredentialsUpdated = "login_autofill_credentials_updated"
37-
case loginEmailFormViewed = "login_email_form_viewed"
38-
case loginMagicLinkOpenEmailClientViewed = "login_magic_link_open_email_client_viewed"
39-
case loginMagicLinkRequestFormViewed = "login_magic_link_request_form_viewed"
40-
case loginMagicLinkExited = "login_magic_link_exited"
41-
case loginMagicLinkFailed = "login_magic_link_failed"
42-
case loginMagicLinkOpened = "login_magic_link_opened"
43-
case loginMagicLinkRequested = "login_magic_link_requested"
44-
case loginMagicLinkSucceeded = "login_magic_link_succeeded"
45-
case loginPasswordFormViewed = "login_password_form_viewed"
46-
case loginURLFormViewed = "login_url_form_viewed"
47-
case loginURLHelpScreenViewed = "login_url_help_screen_viewed"
48-
case loginUsernamePasswordFormViewed = "login_username_password_form_viewed"
49-
case loginTwoFactorFormViewed = "login_two_factor_form_viewed"
50-
case loginEpilogueViewed = "login_epilogue_viewed"
51-
case loginProloguePaged = "login_prologue_paged"
52-
case loginPrologueViewed = "login_prologue_viewed"
53-
case loginPrologueContinueTapped = "login_prologue_jetpack_login_button_tapped"
54-
case loginPrologueJetpackInstructions = "login_prologue_jetpack_configuration_instructions_link_tapped"
55-
case loginForgotPasswordClicked = "login_forgot_password_clicked"
56-
case loginSocialButtonClick = "login_social_button_click"
57-
case loginSocialButtonFailure = "login_social_button_failure"
58-
case loginSocialConnectSuccess = "login_social_connect_success"
59-
case loginSocialConnectFailure = "login_social_connect_failure"
60-
case loginSocialSuccess = "login_social_login_success"
61-
case loginSocialFailure = "login_social_login_failure"
62-
case loginSocial2faNeeded = "login_social_2fa_needed"
63-
case loginSocialAccountsNeedConnecting = "login_social_accounts_need_connecting"
64-
case loginSocialErrorUnknownUser = "login_social_error_unknown_user"
65-
case onePasswordFailed = "one_password_failed"
66-
case onePasswordLogin = "one_password_login"
67-
case onePasswordSignup = "one_password_signup"
68-
case twoFactorCodeRequested = "two_factor_code_requested"
69-
case twoFactorSentSMS = "two_factor_sent_sms"
31+
case signedIn = "signed_in"
32+
case logout = "account_logout"
33+
case openedLogin = "login_accessed"
34+
case loginFailed = "login_failed_to_login"
35+
case loginAutoFillCredentialsFilled = "login_autofill_credentials_filled"
36+
case loginAutoFillCredentialsUpdated = "login_autofill_credentials_updated"
37+
case loginEmailFormViewed = "login_email_form_viewed"
38+
case loginJetpackRequiredScreenViewed = "login_jetpack_required_screen_viewed"
39+
case loginJetpackRequiredViewInstructionsButtonTapped = "login_jetpack_required_view_instructions_button_tapped"
40+
case loginWhatIsJetpackHelpScreenViewed = "login_what_is_jetpack_help_screen_viewed"
41+
case loginWhatIsJetpackHelpScreenOkButtonTapped = "login_what_is_jetpack_help_screen_ok_button_tapped"
42+
case loginWhatIsJetpackHelpScreenLearnMoreButtonTapped = "login_what_is_jetpack_help_screen_learn_more_button_tapped"
43+
case loginMagicLinkOpenEmailClientViewed = "login_magic_link_open_email_client_viewed"
44+
case loginMagicLinkRequestFormViewed = "login_magic_link_request_form_viewed"
45+
case loginMagicLinkExited = "login_magic_link_exited"
46+
case loginMagicLinkFailed = "login_magic_link_failed"
47+
case loginMagicLinkOpened = "login_magic_link_opened"
48+
case loginMagicLinkRequested = "login_magic_link_requested"
49+
case loginMagicLinkSucceeded = "login_magic_link_succeeded"
50+
case loginPasswordFormViewed = "login_password_form_viewed"
51+
case loginURLFormViewed = "login_url_form_viewed"
52+
case loginURLHelpScreenViewed = "login_url_help_screen_viewed"
53+
case loginUsernamePasswordFormViewed = "login_username_password_form_viewed"
54+
case loginTwoFactorFormViewed = "login_two_factor_form_viewed"
55+
case loginEpilogueViewed = "login_epilogue_viewed"
56+
case loginProloguePaged = "login_prologue_paged"
57+
case loginPrologueViewed = "login_prologue_viewed"
58+
case loginPrologueContinueTapped = "login_prologue_jetpack_login_button_tapped"
59+
case loginPrologueJetpackInstructions = "login_prologue_jetpack_configuration_instructions_link_tapped"
60+
case loginForgotPasswordClicked = "login_forgot_password_clicked"
61+
case loginSocialButtonClick = "login_social_button_click"
62+
case loginSocialButtonFailure = "login_social_button_failure"
63+
case loginSocialConnectSuccess = "login_social_connect_success"
64+
case loginSocialConnectFailure = "login_social_connect_failure"
65+
case loginSocialSuccess = "login_social_login_success"
66+
case loginSocialFailure = "login_social_login_failure"
67+
case loginSocial2faNeeded = "login_social_2fa_needed"
68+
case loginSocialAccountsNeedConnecting = "login_social_accounts_need_connecting"
69+
case loginSocialErrorUnknownUser = "login_social_error_unknown_user"
70+
case onePasswordFailed = "one_password_failed"
71+
case onePasswordLogin = "one_password_login"
72+
case onePasswordSignup = "one_password_signup"
73+
case twoFactorCodeRequested = "two_factor_code_requested"
74+
case twoFactorSentSMS = "two_factor_sent_sms"
7075

7176
// MARK: Dashboard View Events
7277
//
@@ -523,7 +528,10 @@ public extension WooAnalyticsStat {
523528
.loginPrologueContinueTapped, .loginPrologueJetpackInstructions, .loginForgotPasswordClicked, .loginSocialButtonClick,
524529
.loginSocialButtonFailure, .loginSocialConnectSuccess, .loginSocialConnectFailure, .loginSocialSuccess,
525530
.loginSocialFailure, .loginSocial2faNeeded, .loginSocialAccountsNeedConnecting, .loginSocialErrorUnknownUser,
526-
.onePasswordFailed, .onePasswordLogin, .onePasswordSignup, .twoFactorCodeRequested, .twoFactorSentSMS:
531+
.onePasswordFailed, .onePasswordLogin, .onePasswordSignup, .twoFactorCodeRequested, .twoFactorSentSMS,
532+
.loginJetpackRequiredScreenViewed, .loginJetpackRequiredViewInstructionsButtonTapped,
533+
.loginWhatIsJetpackHelpScreenViewed, .loginWhatIsJetpackHelpScreenOkButtonTapped,
534+
.loginWhatIsJetpackHelpScreenLearnMoreButtonTapped:
527535
return false
528536
default:
529537
return true

WooCommerce/Classes/Authentication/Navigation Exceptions/JetpackErrorViewModel.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ import WordPressUI
88
/// an error when Jetpack is not installed or is not connected
99
struct JetpackErrorViewModel: ULErrorViewModel {
1010
private let siteURL: String
11+
private let analytics: Analytics
1112

12-
init(siteURL: String?) {
13+
init(siteURL: String?, analytics: Analytics = ServiceLocator.analytics) {
1314
self.siteURL = siteURL ?? Localization.yourSite
15+
self.analytics = analytics
1416
}
1517

1618
// MARK: - Data and configuration
@@ -46,6 +48,8 @@ struct JetpackErrorViewModel: ULErrorViewModel {
4648
let safariViewController = SFSafariViewController(url: url)
4749
safariViewController.modalPresentationStyle = .pageSheet
4850
viewController?.present(safariViewController, animated: true)
51+
52+
analytics.track(.loginJetpackRequiredViewInstructionsButtonTapped)
4953
}
5054

5155
func didTapSecondaryButton(in viewController: UIViewController?) {
@@ -54,10 +58,16 @@ struct JetpackErrorViewModel: ULErrorViewModel {
5458
}
5559

5660
func didTapAuxiliaryButton(in viewController: UIViewController?) {
57-
let fancyAlert = FancyAlertViewController.makeWhatIsJetpackAlertController()
61+
let fancyAlert = FancyAlertViewController.makeWhatIsJetpackAlertController(analytics: analytics)
5862
fancyAlert.modalPresentationStyle = .custom
5963
fancyAlert.transitioningDelegate = AppDelegate.shared.tabBarController
6064
viewController?.present(fancyAlert, animated: true)
65+
66+
analytics.track(.loginWhatIsJetpackHelpScreenViewed)
67+
}
68+
69+
func viewDidLoad() {
70+
analytics.track(.loginJetpackRequiredScreenViewed)
6171
}
6272
}
6373

WooCommerce/Classes/Authentication/Navigation Exceptions/NoSecureConnectionErrorViewModel.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ struct NoSecureConnectionErrorViewModel: ULErrorViewModel {
3232
// NO-OP
3333
}
3434

35+
func viewDidLoad() {
36+
// NO-OP
37+
}
38+
3539
}
3640

3741
private extension NoSecureConnectionErrorViewModel {

WooCommerce/Classes/Authentication/Navigation Exceptions/NotWPAccountViewModel.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ struct NotWPAccountViewModel: ULErrorViewModel {
3737
fancyAlert.transitioningDelegate = AppDelegate.shared.tabBarController
3838
viewController?.present(fancyAlert, animated: true)
3939
}
40+
41+
func viewDidLoad() {
42+
// NO-OP
43+
}
4044
}
4145

4246

WooCommerce/Classes/Authentication/Navigation Exceptions/NotWPErrorViewModel.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ struct NotWPErrorViewModel: ULErrorViewModel {
3434
func didTapAuxiliaryButton(in viewController: UIViewController?) {
3535
// NO-OP
3636
}
37+
38+
func viewDidLoad() {
39+
// NO-OP
40+
}
3741
}
3842

3943

WooCommerce/Classes/Authentication/Navigation Exceptions/ULErrorViewController.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ final class ULErrorViewController: UIViewController {
4949
configureSecondaryButton()
5050

5151
setUnifiedMargins(forWidth: view.frame.width)
52+
53+
viewModel.viewDidLoad()
5254
}
5355

5456
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {

WooCommerce/Classes/Authentication/Navigation Exceptions/ULErrorViewModel.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ protocol ULErrorViewModel {
2121
/// Provides a title for a secondary action button
2222
var secondaryButtonTitle: String { get }
2323

24+
/// Executed by the view controller when its view was loaded.
25+
func viewDidLoad()
26+
2427
/// Executes action associated to a tap in the view controller primary button
2528
/// - Parameter viewController: usually the view controller sending the tap
2629
func didTapPrimaryButton(in viewController: UIViewController?)

WooCommerce/Classes/ViewRelated/Fancy Alerts/FancyAlertViewController+UnifiedLogin.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import WordPressUI
22
import SafariServices
33

4-
public extension FancyAlertViewController {
5-
static func makeWhatIsJetpackAlertController() -> FancyAlertViewController {
6-
let dismissButton = makeDismissButtonConfig()
7-
let moreInfoButton = makeMoreInfoButtonConfig()
4+
extension FancyAlertViewController {
5+
static func makeWhatIsJetpackAlertController(analytics: Analytics) -> FancyAlertViewController {
6+
let dismissButton = FancyAlertViewController.Config.ButtonConfig(Localization.dismissButton) { controller, _ in
7+
controller.dismiss(animated: true)
8+
analytics.track(.loginWhatIsJetpackHelpScreenOkButtonTapped)
9+
}
10+
let moreInfoButton = makeLearnMoreAboutJetpackButtonConfig(analytics: analytics)
811
let config = FancyAlertViewController.Config(titleText: Localization.whatIsJetpack,
912
bodyText: Localization.whatIsJetpackLongDescription,
1013
headerImage: .whatIsJetpackImage,
@@ -93,7 +96,7 @@ private extension FancyAlertViewController {
9396
}
9497
}
9598

96-
static func makeMoreInfoButtonConfig() -> FancyAlertViewController.Config.ButtonConfig {
99+
static func makeLearnMoreAboutJetpackButtonConfig(analytics: Analytics) -> FancyAlertViewController.Config.ButtonConfig {
97100
return FancyAlertViewController.Config.ButtonConfig(Localization.learnMore) { controller, _ in
98101
guard let url = URL(string: Strings.whatsJetpackURLString) else {
99102
return
@@ -102,6 +105,8 @@ private extension FancyAlertViewController {
102105
let safariViewController = SFSafariViewController(url: url)
103106
safariViewController.modalPresentationStyle = .pageSheet
104107
controller.present(safariViewController, animated: true)
108+
109+
analytics.track(.loginWhatIsJetpackHelpScreenLearnMoreButtonTapped)
105110
}
106111
}
107112

WooCommerce/WooCommerceTests/Authentication/JetpackErrorViewModelTests.swift

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,25 @@
11
import XCTest
2+
import Yosemite
3+
import TestKit
24
@testable import WooCommerce
35

46
final class JetpackErrorViewModelTests: XCTestCase {
57

8+
private var analyticsProvider: MockAnalyticsProvider!
9+
private var analytics: WooAnalytics!
10+
11+
override func setUp() {
12+
super.setUp()
13+
analyticsProvider = MockAnalyticsProvider()
14+
analytics = WooAnalytics(analyticsProvider: analyticsProvider)
15+
}
16+
17+
override func tearDown() {
18+
analytics = nil
19+
analyticsProvider = nil
20+
super.tearDown()
21+
}
22+
623
func test_viewmodel_provides_expected_image() {
724
// Given
825
let viewModel = JetpackErrorViewModel(siteURL: Expectations.url)
@@ -57,6 +74,48 @@ final class JetpackErrorViewModelTests: XCTestCase {
5774
// Then
5875
XCTAssertEqual(secondaryButtonTitle, Expectations.secondaryButtonTitle)
5976
}
77+
78+
func test_viewModel_logs_an_event_when_viewDidLoad_is_triggered() throws {
79+
// Given
80+
let viewModel = JetpackErrorViewModel(siteURL: Expectations.url, analytics: analytics)
81+
82+
assertEmpty(analyticsProvider.receivedEvents)
83+
84+
// When
85+
viewModel.viewDidLoad()
86+
87+
// Then
88+
let firstEvent = try XCTUnwrap(analyticsProvider.receivedEvents.first)
89+
XCTAssertEqual(firstEvent, "login_jetpack_required_screen_viewed")
90+
}
91+
92+
func test_viewModel_logs_an_event_when_see_instructions_button_is_tapped() throws {
93+
// Given
94+
let viewModel = JetpackErrorViewModel(siteURL: Expectations.url, analytics: analytics)
95+
96+
assertEmpty(analyticsProvider.receivedEvents)
97+
98+
// When
99+
viewModel.didTapPrimaryButton(in: nil)
100+
101+
// Then
102+
let firstEvent = try XCTUnwrap(analyticsProvider.receivedEvents.first)
103+
XCTAssertEqual(firstEvent, "login_jetpack_required_view_instructions_button_tapped")
104+
}
105+
106+
func test_viewModel_logs_an_event_when_the_what_is_jetpack_button_is_tapped() throws {
107+
// Given
108+
let viewModel = JetpackErrorViewModel(siteURL: Expectations.url, analytics: analytics)
109+
110+
assertEmpty(analyticsProvider.receivedEvents)
111+
112+
// When
113+
viewModel.didTapAuxiliaryButton(in: nil)
114+
115+
// Then
116+
let firstEvent = try XCTUnwrap(analyticsProvider.receivedEvents.first)
117+
XCTAssertEqual(firstEvent, "login_what_is_jetpack_help_screen_viewed")
118+
}
60119
}
61120

62121

0 commit comments

Comments
 (0)