Skip to content

Commit ae833e3

Browse files
authored
[Woo POS][Surveys] Schedule notification trigger on opening app, rather than on opening POS (#16261)
2 parents 9507472 + 3571be9 commit ae833e3

File tree

4 files changed

+79
-5
lines changed

4 files changed

+79
-5
lines changed

WooCommerce/Classes/POS/TabBar/POSTabCoordinator.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,16 +116,14 @@ final class POSTabCoordinator {
116116
}
117117

118118
func onTabSelected() {
119-
schedulePOSSurveyNotificationIfNeeded()
119+
setPOSHasBeenOpened()
120120
presentPOSView(siteID: siteID)
121121
}
122122
}
123123

124124
private extension POSTabCoordinator {
125-
func schedulePOSSurveyNotificationIfNeeded() {
125+
func setPOSHasBeenOpened() {
126126
Task { @MainActor in
127-
await POSNotificationScheduler().scheduleLocalNotificationIfEligible(for: .currentMerchant)
128-
129127
let action = AppSettingsAction.setHasPOSBeenOpenedAtLeastOnce { _ in }
130128
storesManager.dispatch(action)
131129
}

WooCommerce/Classes/ViewRelated/AppCoordinator.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ final class AppCoordinator {
6565

6666
// Configures authenticator first in case `WordPressAuthenticator` is used in other `AppDelegate` launch events.
6767
configureAuthenticator()
68+
69+
schedulePOSSurveyNotificationIfNeeded()
6870
}
6971

7072
func start() {
@@ -101,6 +103,14 @@ final class AppCoordinator {
101103
}
102104
}
103105

106+
private extension AppCoordinator {
107+
func schedulePOSSurveyNotificationIfNeeded() {
108+
Task { @MainActor in
109+
await POSNotificationScheduler(stores: stores).scheduleLocalNotificationIfEligible(for: .currentMerchant)
110+
}
111+
}
112+
}
113+
104114
private extension AppCoordinator {
105115
// Fetch latest site properties and update the default store if anything has changed:
106116
//

WooCommerce/Classes/ViewRelated/Orders/Order Creation/EditableOrderViewModel.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ final class EditableOrderViewModel: ObservableObject {
1919
private let currencyFormatter: CurrencyFormatter
2020
private let featureFlagService: FeatureFlagService
2121
private let permissionChecker: CaptureDevicePermissionChecker
22+
private let posNotificationScheduler: POSNotificationScheduling
2223

2324
@Published var syncRequired: Bool = false
2425

@@ -460,6 +461,7 @@ final class EditableOrderViewModel: ObservableObject {
460461
featureFlagService: FeatureFlagService = ServiceLocator.featureFlagService,
461462
orderDurationRecorder: OrderDurationRecorderProtocol = OrderDurationRecorder.shared,
462463
permissionChecker: CaptureDevicePermissionChecker = AVCaptureDevicePermissionChecker(),
464+
posNotificationScheduler: POSNotificationScheduling = POSNotificationScheduler(),
463465
initialItem: OrderBaseItem? = nil,
464466
initialCustomer: (id: Int64, billing: Address?, shipping: Address?)? = nil,
465467
quantityDebounceDuration: Double = Constants.quantityDebounceDuration) {
@@ -473,6 +475,7 @@ final class EditableOrderViewModel: ObservableObject {
473475
self.featureFlagService = featureFlagService
474476
self.orderDurationRecorder = orderDurationRecorder
475477
self.permissionChecker = permissionChecker
478+
self.posNotificationScheduler = posNotificationScheduler
476479
self.initialItem = initialItem
477480
self.initialCustomer = initialCustomer
478481
self.barcodeScannerItemFinder = BarcodeScannerItemFinder(stores: stores)
@@ -1026,7 +1029,7 @@ final class EditableOrderViewModel: ObservableObject {
10261029
self.onFinished(order)
10271030
self.trackCreateOrderSuccess(usesGiftCard: usesGiftCard)
10281031
Task {
1029-
await POSNotificationScheduler().scheduleLocalNotificationIfEligible(for: .potentialMerchant)
1032+
await self.posNotificationScheduler.scheduleLocalNotificationIfEligible(for: .potentialMerchant)
10301033
}
10311034
} onFailure: { [weak self] error, usesGiftCard in
10321035
guard let self else { return }

WooCommerce/WooCommerceTests/ViewRelated/Orders/Order Creation/EditableOrderViewModelTests.swift

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3362,6 +3362,56 @@ final class EditableOrderViewModelTests: XCTestCase {
33623362
// Then
33633363
XCTAssertTrue(viewModel.canBeDismissed)
33643364
}
3365+
3366+
func test_onCreateOrderTapped_schedules_potential_merchant_notification() {
3367+
// Given
3368+
let mockScheduler = MockPOSNotificationScheduler()
3369+
let viewModel = EditableOrderViewModel(siteID: sampleSiteID,
3370+
stores: stores,
3371+
posNotificationScheduler: mockScheduler)
3372+
3373+
// When
3374+
stores.whenReceivingAction(ofType: OrderAction.self) { action in
3375+
switch action {
3376+
case let .createOrder(_, order, _, onCompletion):
3377+
onCompletion(.success(order))
3378+
default:
3379+
XCTFail("Received unsupported action: \(action)")
3380+
}
3381+
}
3382+
viewModel.onCreateOrderTapped()
3383+
3384+
// Then
3385+
waitUntil {
3386+
mockScheduler.scheduleCallCount > 0
3387+
}
3388+
XCTAssertEqual(mockScheduler.scheduleCallCount, 1)
3389+
XCTAssertEqual(mockScheduler.lastMerchantType, .potentialMerchant)
3390+
}
3391+
3392+
func test_onCreateOrderTapped_does_not_schedule_notification_on_failure() {
3393+
// Given
3394+
let mockScheduler = MockPOSNotificationScheduler()
3395+
let viewModel = EditableOrderViewModel(siteID: sampleSiteID,
3396+
stores: stores,
3397+
posNotificationScheduler: mockScheduler)
3398+
let error = NSError(domain: "Error", code: 0)
3399+
3400+
// When
3401+
stores.whenReceivingAction(ofType: OrderAction.self) { action in
3402+
switch action {
3403+
case let .createOrder(_, _, _, onCompletion):
3404+
onCompletion(.failure(error))
3405+
default:
3406+
XCTFail("Received unsupported action: \(action)")
3407+
}
3408+
}
3409+
viewModel.onCreateOrderTapped()
3410+
3411+
// Then
3412+
XCTAssertEqual(mockScheduler.scheduleCallCount, 0)
3413+
XCTAssertNil(mockScheduler.lastMerchantType)
3414+
}
33653415
}
33663416

33673417
private extension EditableOrderViewModelTests {
@@ -3458,3 +3508,16 @@ private extension EditableOrderViewModelTests {
34583508
email: "")
34593509
}
34603510
}
3511+
3512+
// MARK: - POS Notification Tests & MockPOSNotificationScheduler
3513+
private extension EditableOrderViewModelTests {
3514+
final class MockPOSNotificationScheduler: POSNotificationScheduling {
3515+
private(set) var scheduleCallCount = 0
3516+
private(set) var lastMerchantType: POSNotificationScheduler.MerchantType?
3517+
3518+
func scheduleLocalNotificationIfEligible(for merchantType: POSNotificationScheduler.MerchantType) async {
3519+
scheduleCallCount += 1
3520+
lastMerchantType = merchantType
3521+
}
3522+
}
3523+
}

0 commit comments

Comments
 (0)