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 @@ -7,21 +7,27 @@ struct ReceiptActionCoordinator {
countryCode: String,
cardReaderModel: String?,
stores: StoresManager,
analytics: Analytics) {
analytics: Analytics) async {
analytics.track(event: .InPersonPayments.receiptPrintTapped(countryCode: countryCode, cardReaderModel: cardReaderModel))

let action = ReceiptAction.print(order: order, parameters: params) { (result) in
switch result {
case .success:
analytics.track(event: .InPersonPayments.receiptPrintSuccess(countryCode: countryCode, cardReaderModel: cardReaderModel))
case .cancel:
analytics.track(event: .InPersonPayments.receiptPrintCanceled(countryCode: countryCode, cardReaderModel: cardReaderModel))
case .failure(let error):
analytics.track(event: .InPersonPayments.receiptPrintFailed(error: error, countryCode: countryCode, cardReaderModel: cardReaderModel))
DDLogError("⛔️ Failed to print receipt: \(error.localizedDescription)")
await withCheckedContinuation { continuation in
let action = ReceiptAction.print(order: order, parameters: params) { (result) in
switch result {
case .success:
analytics.track(event: .InPersonPayments.receiptPrintSuccess(countryCode: countryCode, cardReaderModel: cardReaderModel))
case .cancel:
analytics.track(event: .InPersonPayments.receiptPrintCanceled(countryCode: countryCode, cardReaderModel: cardReaderModel))
case .failure(let error):
analytics.track(event: .InPersonPayments.receiptPrintFailed(error: error, countryCode: countryCode, cardReaderModel: cardReaderModel))
DDLogError("⛔️ Failed to print receipt: \(error.localizedDescription)")
}

continuation.resume()
}
}

stores.dispatch(action)
Task { @MainActor in
stores.dispatch(action)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@ final class ReceiptViewModel {

/// Prints the receipt
func printReceipt() {
ReceiptActionCoordinator.printReceipt(for: order,
params: receipt,
countryCode: countryCode,
cardReaderModel: nil,
stores: stores,
analytics: ServiceLocator.analytics)
Task { @MainActor in
await ReceiptActionCoordinator.printReceipt(for: order,
params: receipt,
countryCode: countryCode,
cardReaderModel: nil,
stores: stores,
analytics: ServiceLocator.analytics)
}
}

/// Returns a boolean that indicates whether email is supported for the app and device so that email UI is only displayed when it is supported.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -442,17 +442,18 @@ private extension CollectOrderPaymentUseCase {
alertsPresenter.present(viewModel: paymentAlerts.success(printReceipt: { [order, configuration, weak self] in
guard let self = self else { return }

// Inform about flow completion.
onCompleted()

// Delegate print action
ReceiptActionCoordinator.printReceipt(for: order,
params: receiptParameters,
countryCode: configuration.countryCode,
cardReaderModel: self.connectedReader?.readerType.model,
stores: self.stores,
analytics: self.analytics)

Task { @MainActor in
await ReceiptActionCoordinator.printReceipt(for: order,
params: receiptParameters,
countryCode: configuration.countryCode,
cardReaderModel: self.connectedReader?.readerType.model,
stores: self.stores,
analytics: self.analytics)

// Inform about flow completion.
onCompleted()
}
}, emailReceipt: { [order, analytics, paymentOrchestrator, configuration, weak self] in
guard let self = self else { return }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,17 +400,17 @@ private extension LegacyCollectOrderPaymentUseCase {
alerts.success(printReceipt: { [order, configuration, weak self] in
guard let self = self else { return }

// Inform about flow completion.
onCompleted()

// Delegate print action
ReceiptActionCoordinator.printReceipt(for: order,
params: receiptParameters,
countryCode: configuration.countryCode,
cardReaderModel: self.connectedReader?.readerType.model,
stores: self.stores,
analytics: self.analytics)

Task { @MainActor in
await ReceiptActionCoordinator.printReceipt(for: order,
params: receiptParameters,
countryCode: configuration.countryCode,
cardReaderModel: self.connectedReader?.readerType.model,
stores: self.stores,
analytics: self.analytics)
// Inform about flow completion.
onCompleted()
}
}, emailReceipt: { [order, analytics, paymentOrchestrator, configuration, weak self] in
guard let self = self else { return }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,27 +110,6 @@ final class LegacyCollectOrderPaymentUseCaseTests: XCTestCase {
}

// MARK: Success alert actions

func test_printing_receipt_from_collectPayment_success_alert_tracks_receiptPrintTapped_event() throws {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I deleted this test case because we have it already implemented in ReceiptActionCoordinatorTests, where it feels more natural.

// Given
let intent = PaymentIntent.fake().copy(charges: [.fake().copy(paymentMethod: .cardPresent(details: .fake()))])
mockSuccessfulCardPresentPaymentActions(intent: intent)

// When
waitFor { promise in
self.useCase.collectPayment(onCollect: { _ in
promise(())
}, onCancel: {}, onCompleted: {})
}
alerts.printReceiptFromSuccessAlert?()

// Then
let indexOfEvent = try XCTUnwrap(analyticsProvider.receivedEvents.firstIndex(where: { $0 == "receipt_print_tapped"}))
let eventProperties = try XCTUnwrap(analyticsProvider.receivedProperties[indexOfEvent])
XCTAssertEqual(eventProperties["card_reader_model"] as? String, Mocks.cardReaderModel)
XCTAssertEqual(eventProperties["country"] as? String, "US")
}

func test_emailing_receipt_from_collectPayment_success_alert_tracks_receiptEmailTapped_event() throws {
// Given
let intent = PaymentIntent.fake().copy(charges: [.fake().copy(paymentMethod: .cardPresent(details: .fake()))])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,39 @@ import Hardware
@testable import WooCommerce

final class ReceiptActionCoordinatorTests: XCTestCase {
func test_printReceipt_logs_receiptPrintTapped_analyticEvent() throws {
private var storesManager: MockStoresManager!

override func setUp() {
super.setUp()

storesManager = MockStoresManager(sessionManager: .makeForTesting(authenticated: true))
}

override func tearDown() {
storesManager = nil
}

func test_printReceipt_logs_receiptPrintTapped_analyticEvent() async throws {
// Given
let analytics = MockAnalyticsProvider()
let order = MockOrders().makeOrder()
let params = CardPresentReceiptParameters.makeParams()

storesManager.whenReceivingAction(ofType: ReceiptAction.self) { action in
switch action {
case let .print(_, _, completion):
completion(.success)
default:
break
}
}

// When
ReceiptActionCoordinator.printReceipt(for: order,
await ReceiptActionCoordinator.printReceipt(for: order,
params: params,
countryCode: "CA",
cardReaderModel: "WISEPAD_3",
stores: ServiceLocator.stores,
stores: storesManager,
analytics: WooAnalytics(analyticsProvider: analytics))

// Then
Expand All @@ -27,18 +48,26 @@ final class ReceiptActionCoordinatorTests: XCTestCase {
XCTAssertEqual(eventProperties["country"] as? String, "CA")
}

func test_printReceipt_sends_print_receiptAction() throws {
func test_printReceipt_sends_print_receiptAction() async throws {
// Given
let order = MockOrders().makeOrder()
let params = CardPresentReceiptParameters.makeParams()

let storesManager = MockStoresManager(sessionManager: .makeForTesting(authenticated: true))
storesManager.reset()

assertEmpty(storesManager.receivedActions)

storesManager.whenReceivingAction(ofType: ReceiptAction.self) { action in
switch action {
case let .print(_, _, completion):
completion(.success)
default:
break
}
}

// When
ReceiptActionCoordinator.printReceipt(for: order,
await ReceiptActionCoordinator.printReceipt(for: order,
params: params,
countryCode: "CA",
cardReaderModel: nil,
Expand All @@ -57,48 +86,53 @@ final class ReceiptActionCoordinatorTests: XCTestCase {
}
}

func test_printReceipt_success_logs_receiptPrintSuccess_analyticEvent() throws {
try assertAnalyticLogged(.receiptPrintSuccess, for: .success)
func test_printReceipt_success_logs_receiptPrintSuccess_analyticEvent() async throws {
try await assertAnalyticLogged(.receiptPrintSuccess, for: .success)
}

func test_printReceipt_cancel_logs_receiptPrintCanceled_analyticEvent() throws {
try assertAnalyticLogged(.receiptPrintCanceled, for: .cancel)
func test_printReceipt_cancel_logs_receiptPrintCanceled_analyticEvent() async throws {
try await assertAnalyticLogged(.receiptPrintCanceled, for: .cancel)
}

func test_printReceipt_fail_logs_receiptPrintFailed_analyticEvent() throws {
func test_printReceipt_fail_logs_receiptPrintFailed_analyticEvent() async throws {
let error = NSError(domain: "errordomain", code: 123, userInfo: nil)
try assertAnalyticLogged(.receiptPrintFailed, for: .failure(error))
try await assertAnalyticLogged(.receiptPrintFailed, for: .failure(error))
}
}

extension ReceiptActionCoordinatorTests {
func assertAnalyticLogged(_ analytic: WooAnalyticsStat, for printingResult: PrintingResult) throws {
func assertAnalyticLogged(_ analytic: WooAnalyticsStat, for printingResult: PrintingResult) async throws {
// Given
let order = MockOrders().makeOrder()
let params = CardPresentReceiptParameters.makeParams()
let countryCode = "CA"
let cardReaderModel = "test_reader"


let storesManager = MockStoresManager(sessionManager: .makeForTesting(authenticated: true))
let analytics = MockAnalyticsProvider()

storesManager.whenReceivingAction(ofType: ReceiptAction.self) { action in
switch action {
case let .print(_, _, completion):
completion(printingResult)
default:
break
}
}

// When
ReceiptActionCoordinator.printReceipt(for: order,
await ReceiptActionCoordinator.printReceipt(for: order,
params: params,
countryCode: "CA",
cardReaderModel: nil,
cardReaderModel: cardReaderModel,
stores: storesManager,
analytics: WooAnalytics(analyticsProvider: analytics))

//Then
let action = try XCTUnwrap(storesManager.receivedActions.first as? ReceiptAction)
switch action {
case .print(order: _, parameters: _, let completion):
completion(printingResult)

let receivedEvents = analytics.receivedEvents
XCTAssert(receivedEvents.contains(analytic.rawValue))
default:
XCTFail("Print Receipt failed to dispatch .print action")
}
// Then
let indexOfEvent = try XCTUnwrap(analytics.receivedEvents.firstIndex(where: { $0 == analytic.rawValue}))
let eventProperties = try XCTUnwrap(analytics.receivedProperties[indexOfEvent])
XCTAssertEqual(eventProperties["card_reader_model"] as? String, cardReaderModel)
XCTAssertEqual(eventProperties["country"] as? String, countryCode)
}
}

Expand Down