Skip to content

Commit 1932437

Browse files
committed
5300 Add card reader software update Tracks events
1 parent 22f860f commit 1932437

File tree

4 files changed

+161
-1
lines changed

4 files changed

+161
-1
lines changed

WooCommerce/Classes/Analytics/WooAnalyticsStat.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,15 @@ public enum WooAnalyticsStat: String {
155155
case cardReaderConnectionSuccess = "card_reader_connection_success"
156156
case cardReaderDisconnectTapped = "card_reader_disconnect_tapped"
157157

158+
// MARK: Card Reader Software Update Events
159+
//
160+
case cardReaderSoftwareUpdateTapped = "card_reader_software_update_tapped"
161+
case cardReaderSoftwareUpdateStarted = "card_reader_software_update_started"
162+
case cardReaderSoftwareUpdateSuccess = "card_reader_software_update_success"
163+
case cardReaderSoftwareUpdateFailed = "card_reader_software_update_failed"
164+
case cardReaderSoftwareUpdateCancelTapped = "card_reader_software_update_cancel_tapped"
165+
case cardReaderSoftwareUpdateCanceled = "card_reader_software_update_canceled"
166+
158167
// MARK: Card-Present Payments Onboarding
159168
case cardPresentOnboardingLearnMoreTapped = "card_present_onboarding_learn_more_tapped"
160169
case cardPresentOnboardingNotCompleted = "card_present_onboarding_not_completed"

WooCommerce/Classes/ViewRelated/Dashboard/Settings/CardReadersV2/CardReaderSettingsConnectedViewModel.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,17 @@ final class CardReaderSettingsConnectedViewModel: CardReaderSettingsPresentedVie
5959
self.readerUpdateError = nil
6060
self.softwareUpdateCancelable = cancelable
6161
self.readerUpdateProgress = 0
62+
ServiceLocator.analytics.track(.cardReaderSoftwareUpdateStarted)
6263
case .installing(progress: let progress):
6364
self.readerUpdateProgress = progress
6465
case .failed(error: let error):
6566
self.readerUpdateError = error
6667
self.completeCardReaderUpdate(success: false)
68+
ServiceLocator.analytics.track(.cardReaderSoftwareUpdateFailed)
6769
case .completed:
6870
self.readerUpdateProgress = 1
6971
self.softwareUpdateCancelable = nil
72+
ServiceLocator.analytics.track(.cardReaderSoftwareUpdateSuccess)
7073
// If we were installing a software update, introduce a small delay so the user can
7174
// actually see a success message showing the installation was complete
7275
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) { [weak self] in
@@ -117,16 +120,19 @@ final class CardReaderSettingsConnectedViewModel: CardReaderSettingsPresentedVie
117120
/// Allows the view controller to kick off a card reader update
118121
///
119122
func startCardReaderUpdate() {
123+
ServiceLocator.analytics.track(.cardReaderSoftwareUpdateTapped)
120124
let action = CardPresentPaymentAction.startCardReaderUpdate
121125
ServiceLocator.stores.dispatch(action)
122126
}
123127

124128
func cancelCardReaderUpdate() {
129+
ServiceLocator.analytics.track(.cardReaderSoftwareUpdateCancelTapped)
125130
softwareUpdateCancelable?.cancel(completion: { [weak self] result in
126131
if case .failure(let error) = result {
127132
print("=== error canceling software update: \(error)")
128133
} else {
129134
self?.completeCardReaderUpdate(success: false)
135+
ServiceLocator.analytics.track(.cardReaderSoftwareUpdateCanceled)
130136
}
131137
})
132138
}

WooCommerce/WooCommerceTests/Mocks/MockCardPresentPaymentsStoresManager.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,21 @@ extension MockCardPresentPaymentsStoresManager {
8686
case connectionFailure
8787
}
8888
}
89+
90+
extension MockCardPresentPaymentsStoresManager {
91+
func simulateSuccessfulUpdate() {
92+
softwareUpdateSubject.send(.completed)
93+
}
94+
95+
func simulateFailedUpdate(error: Error) {
96+
softwareUpdateSubject.send(.failed(error: error))
97+
}
98+
99+
func simulateCancelableUpdate(onCancel: @escaping () -> Void) {
100+
softwareUpdateSubject.send(.started(cancelable: MockFallibleCancelable(onCancel: onCancel)))
101+
}
102+
103+
func simulateUpdateStarted() {
104+
softwareUpdateSubject.send(.started(cancelable: nil))
105+
}
106+
}

WooCommerce/WooCommerceTests/ViewRelated/Dashboard/CardReaderSettings/CardReaderSettingsConnectedViewModelTests.swift

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import XCTest
33
@testable import WooCommerce
44

55
final class CardReaderSettingsConnectedViewModelTests: XCTestCase {
6-
76
func test_did_change_should_show_returns_false_if_no_connected_readers() {
87
let mockStoresManager = MockCardPresentPaymentsStoresManager(
98
connectedReaders: [],
@@ -160,4 +159,132 @@ final class CardReaderSettingsConnectedViewModelTests: XCTestCase {
160159
// Then
161160
wait(for: [expectation], timeout: Constants.expectationTimeout)
162161
}
162+
163+
func test_startCardReaderUpdate_ViewModel_LogsTracksEvent_cardReaderSoftwareUpdateTapped() {
164+
// Given
165+
let mockStoresManager = MockCardPresentPaymentsStoresManager(
166+
connectedReaders: [MockCardReader.bbposChipper2XBT()],
167+
discoveredReaders: [],
168+
sessionManager: SessionManager.testingInstance
169+
)
170+
ServiceLocator.setStores(mockStoresManager)
171+
172+
let analytics = MockAnalyticsProvider()
173+
ServiceLocator.setAnalytics(WooAnalytics(analyticsProvider: analytics))
174+
let viewModel = CardReaderSettingsConnectedViewModel(didChangeShouldShow: nil)
175+
176+
// When
177+
viewModel.startCardReaderUpdate()
178+
179+
// Then
180+
XCTAssert(analytics.receivedEvents.contains(WooAnalyticsStat.cardReaderSoftwareUpdateTapped.rawValue))
181+
}
182+
183+
func test_startCardReaderUpdate_ViewModel_LogsTracksEvent_cardReaderSoftwareUpdateStarted() {
184+
// Given
185+
let mockStoresManager = MockCardPresentPaymentsStoresManager(
186+
connectedReaders: [MockCardReader.bbposChipper2XBT()],
187+
discoveredReaders: [],
188+
sessionManager: SessionManager.testingInstance
189+
)
190+
ServiceLocator.setStores(mockStoresManager)
191+
192+
let analytics = MockAnalyticsProvider()
193+
ServiceLocator.setAnalytics(WooAnalytics(analyticsProvider: analytics))
194+
let viewModel = CardReaderSettingsConnectedViewModel(didChangeShouldShow: nil)
195+
196+
// When
197+
mockStoresManager.simulateUpdateStarted()
198+
199+
// Then
200+
XCTAssert(analytics.receivedEvents.contains(WooAnalyticsStat.cardReaderSoftwareUpdateStarted.rawValue))
201+
}
202+
203+
func test_WhenStoreSendsUpdateComplete_ViewModel_LogsTracksEvent_cardReaderSoftwareUpdateSuccess() {
204+
// Given
205+
let mockStoresManager = MockCardPresentPaymentsStoresManager(
206+
connectedReaders: [MockCardReader.bbposChipper2XBT()],
207+
discoveredReaders: [],
208+
sessionManager: SessionManager.testingInstance
209+
)
210+
ServiceLocator.setStores(mockStoresManager)
211+
212+
let analytics = MockAnalyticsProvider()
213+
ServiceLocator.setAnalytics(WooAnalytics(analyticsProvider: analytics))
214+
let viewModel = CardReaderSettingsConnectedViewModel(didChangeShouldShow: nil)
215+
216+
// When
217+
mockStoresManager.simulateSuccessfulUpdate()
218+
219+
// Then
220+
XCTAssert(analytics.receivedEvents.contains(WooAnalyticsStat.cardReaderSoftwareUpdateSuccess.rawValue))
221+
}
222+
223+
func test_WhenStoreSendsUpdateFailed_ViewModel_LogsTracksEvent_cardReaderSoftwareUpdateFailed() {
224+
// Given
225+
let mockStoresManager = MockCardPresentPaymentsStoresManager(
226+
connectedReaders: [MockCardReader.bbposChipper2XBT()],
227+
discoveredReaders: [],
228+
sessionManager: SessionManager.testingInstance
229+
)
230+
ServiceLocator.setStores(mockStoresManager)
231+
232+
let analytics = MockAnalyticsProvider()
233+
ServiceLocator.setAnalytics(WooAnalytics(analyticsProvider: analytics))
234+
let viewModel = CardReaderSettingsConnectedViewModel(didChangeShouldShow: nil)
235+
236+
// When
237+
let expectedError = CardReaderServiceError.softwareUpdate(underlyingError: .readerSoftwareUpdateFailedBatteryLow,
238+
batteryLevel: 0.4)
239+
mockStoresManager.simulateFailedUpdate(error: expectedError)
240+
241+
// Then
242+
XCTAssert(analytics.receivedEvents.contains(WooAnalyticsStat.cardReaderSoftwareUpdateFailed.rawValue))
243+
}
244+
245+
func test_WhenUserCancelsUpdate_ViewModel_LogsTracksEvent_cardReaderSoftwareUpdateCancelTapped() {
246+
// Given
247+
let mockStoresManager = MockCardPresentPaymentsStoresManager(
248+
connectedReaders: [MockCardReader.bbposChipper2XBT()],
249+
discoveredReaders: [],
250+
sessionManager: SessionManager.testingInstance
251+
)
252+
ServiceLocator.setStores(mockStoresManager)
253+
254+
let analytics = MockAnalyticsProvider()
255+
ServiceLocator.setAnalytics(WooAnalytics(analyticsProvider: analytics))
256+
let viewModel = CardReaderSettingsConnectedViewModel(didChangeShouldShow: nil)
257+
258+
// When
259+
viewModel.cancelCardReaderUpdate()
260+
261+
// Then
262+
XCTAssert(analytics.receivedEvents.contains(WooAnalyticsStat.cardReaderSoftwareUpdateCancelTapped.rawValue))
263+
}
264+
265+
func test_WhenUpdateIsSuccessfullyCanceled_ViewModel_LogsTracksEvent_cardReaderSoftwareUpdateCanceled() {
266+
// Given
267+
let mockStoresManager = MockCardPresentPaymentsStoresManager(
268+
connectedReaders: [MockCardReader.bbposChipper2XBT()],
269+
discoveredReaders: [],
270+
sessionManager: SessionManager.testingInstance
271+
)
272+
ServiceLocator.setStores(mockStoresManager)
273+
274+
let analytics = MockAnalyticsProvider()
275+
ServiceLocator.setAnalytics(WooAnalytics(analyticsProvider: analytics))
276+
let viewModel = CardReaderSettingsConnectedViewModel(didChangeShouldShow: nil)
277+
let expectation = self.expectation(description: #function)
278+
279+
mockStoresManager.simulateCancelableUpdate {
280+
expectation.fulfill()
281+
}
282+
283+
// When
284+
viewModel.cancelCardReaderUpdate()
285+
286+
// Then
287+
wait(for: [expectation], timeout: Constants.expectationTimeout)
288+
XCTAssert(analytics.receivedEvents.contains(WooAnalyticsStat.cardReaderSoftwareUpdateCanceled.rawValue))
289+
}
163290
}

0 commit comments

Comments
 (0)