Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adopt new way of getting notification data in PushNotificationBackgroundSynchronizer #13917

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Yosemite

/// Type that fetches the necessary resources when a push notification arrives in the background.
/// Current it fetches:
/// - Notifications
/// - Notifications (If needed)
/// - Orders List (If needed)
/// - Notification Order (If needed)
///
Expand All @@ -27,22 +27,27 @@ struct PushNotificationBackgroundSynchronizer {
///
@MainActor
func sync() async -> UIBackgroundFetchResult {

guard let pushNotification = PushNotification.from(userInfo: userInfo) else {
return .noData
}

do {

let startTime = Date.now

// I'm not sure why we need to sync all notifications instead of only the current one.
// This is legacy code copied from PushNotificationsManager
try await synchronizeNotifications()

// Find the orderID from the previously synced notification.
guard let orderID = getOrderID(noteID: pushNotification.noteID) else {
return .newData
let orderID: Int64

if let note = pushNotification.note,
let noteOrderID = note.meta.identifier(forKey: .order) {
orderID = Int64(noteOrderID)
} else {
Comment on lines +38 to +41
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This the only change, checking if we already have the orderID in the notification note property.

// I'm not sure why we need to sync all notifications instead of only the current one.
// This is legacy code copied from PushNotificationsManager
try await synchronizeNotifications()

// Find the orderID from the previously synced notification.
guard let pushNotificationOrderID = getOrderID(noteID: pushNotification.noteID) else {
return .newData
}
orderID = pushNotificationOrderID
}

// Sync the order list data
Expand All @@ -58,7 +63,6 @@ struct PushNotificationBackgroundSynchronizer {
ServiceLocator.analytics.track(event: .BackgroundUpdates.orderPushNotificationSynced(timeTaken: timeTaken))

return .newData

} catch {
DDLogError("⛔️ Error synchronizing notification dependencies: \(error)")
ServiceLocator.analytics.track(event: .BackgroundUpdates.orderPushNotificationSyncError(error))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ final class PushNotificationBackgroundSynchronizerTests: XCTestCase {
@MainActor
func test_synchronizer_stores_order_notification_when_exists_in_order_list() async {
// Given
mockOrderInOrderListResponses()
mockOrderInOrderListResponses(order: Self.sampleOrder)

// When
let synchronizer = PushNotificationBackgroundSynchronizer(userInfo: Self.sampleUserInfo, stores: stores, storage: storage.viewStorage)
Expand All @@ -33,7 +33,7 @@ final class PushNotificationBackgroundSynchronizerTests: XCTestCase {
@MainActor
func test_synchronizer_stores_order_notification_when_does_not_exists_in_order_list() async {
// Given
mockOrderNotInOrdersList()
mockOrderNotInOrdersList(order: Self.sampleOrder)

// When
let synchronizer = PushNotificationBackgroundSynchronizer(userInfo: Self.sampleUserInfo, stores: stores, storage: storage.viewStorage)
Expand All @@ -44,29 +44,49 @@ final class PushNotificationBackgroundSynchronizerTests: XCTestCase {
XCTAssertNotNil(storedOrder)
XCTAssertEqual(syncResult, .newData)
}

@MainActor
func test_synchronizer_stores_order_notification_when_order_comes_inside_notification() async {
// Given
mockOrderNotInOrdersForSampleWithNoteFullData()

// When
let synchronizer = PushNotificationBackgroundSynchronizer(userInfo: Self.sampleUserInfoWithNoteFullData, stores: stores, storage: storage.viewStorage)
let syncResult = await synchronizer.sync()

// Then
let storedOrder = storage.viewStorage.loadOrder(siteID: Self.sampleSiteIDFromNotificationWithNoteFullData,
orderID: Self.sampleOrderIDFromNotificationWithNoteFullData)
XCTAssertNotNil(storedOrder)
XCTAssertEqual(syncResult, .newData)
XCTAssertEqual(storedOrder?.orderID, Self.sampleOrderIDFromNotificationWithNoteFullData)
XCTAssertEqual(storedOrder?.siteID, Self.sampleSiteIDFromNotificationWithNoteFullData)
}
}

// MARK: Helpers
private extension PushNotificationBackgroundSynchronizerTests {
/// Responses when the order exists in the order list
///
func mockOrderInOrderListResponses() {
// Mock sync notifications
stores.whenReceivingAction(ofType: NotificationAction.self) { action in
switch action {
case let .synchronizeNotifications(onCompletion):
self.storage.insertSampleNote(readOnlyNote: Self.sampleNote)
onCompletion(nil)
default:
break
func mockOrderInOrderListResponses(order: Networking.Order, synchronizeNotifications: Bool = true) {
if synchronizeNotifications {
// Mock sync notifications
stores.whenReceivingAction(ofType: NotificationAction.self) { action in
switch action {
case let .synchronizeNotifications(onCompletion):
self.storage.insertSampleNote(readOnlyNote: Self.sampleNote)
onCompletion(nil)
default:
break
}
}
}

// Mock fetch order filters
stores.whenReceivingAction(ofType: AppSettingsAction.self) { action in
switch action {
case let .loadOrdersSettings(_, onCompletion):
onCompletion(.success(.init(siteID: 123, orderStatusesFilter: nil, dateRangeFilter: nil, productFilter: nil, customerFilter: nil)))
onCompletion(.success(.init(siteID: order.siteID, orderStatusesFilter: nil, dateRangeFilter: nil, productFilter: nil, customerFilter: nil)))
default:
break
}
Expand All @@ -76,8 +96,8 @@ private extension PushNotificationBackgroundSynchronizerTests {
stores.whenReceivingAction(ofType: OrderAction.self) { action in
switch action {
case let .fetchFilteredOrders(_, _, _, _, _, _, _, _, _, onCompletion):
self.storage.insertSampleOrder(readOnlyOrder: Self.sampleOrder)
onCompletion(0, .success([Self.sampleOrder]))
self.storage.insertSampleOrder(readOnlyOrder: order)
onCompletion(0, .success([order]))
default:
break
}
Expand All @@ -86,17 +106,34 @@ private extension PushNotificationBackgroundSynchronizerTests {

/// Responses when the order does not exists the order list.
///
func mockOrderNotInOrdersList() {
mockOrderInOrderListResponses()
func mockOrderNotInOrdersList(order: Networking.Order) {
mockOrderInOrderListResponses(order: order)

// Mock sync order list & single order
stores.whenReceivingAction(ofType: OrderAction.self) { action in
switch action {
case let .fetchFilteredOrders(_, _, _, _, _, _, _, _, _, onCompletion):
onCompletion(0, .success([]))
case let .retrieveOrderRemotely(_, _, onCompletion):
self.storage.insertSampleOrder(readOnlyOrder: Self.sampleOrder)
onCompletion(.success(Self.sampleOrder))
self.storage.insertSampleOrder(readOnlyOrder: order)
onCompletion(.success(order))
default:
break
}
}
}

func mockOrderNotInOrdersForSampleWithNoteFullData() {
mockOrderInOrderListResponses(order: Self.sampleOrderWithNoteFullDataOrderID, synchronizeNotifications: false)

// Mock sync order list & single order
stores.whenReceivingAction(ofType: OrderAction.self) { action in
switch action {
case let .fetchFilteredOrders(_, _, _, _, _, _, _, _, _, onCompletion):
onCompletion(0, .success([]))
case let .retrieveOrderRemotely(_, _, onCompletion):
self.storage.insertSampleOrder(readOnlyOrder: Self.sampleOrderWithNoteFullDataOrderID)
onCompletion(.success(Self.sampleOrderWithNoteFullDataOrderID))
default:
break
}
Expand Down Expand Up @@ -134,4 +171,20 @@ private extension PushNotificationBackgroundSynchronizerTests {
}()

static var sampleOrder = Order.fake().copy(siteID: sampleSiteID, orderID: sampleOrderID)

// Samples with note_full_data
static var sampleUserInfoWithNoteFullData: [String: Any] = [
APNSKey.siteID: 205617935,
APNSKey.identifier: 8300031174,
APNSKey.aps: [APNSKey.alert: [
APNSKey.alertTitle: ""
]],
// swiftlint:disable line_length
APNSKey.noteFullData: "eNqVkc1O6zAQhV/FjNiRH+enTZqHgA0bdI0qN522hsSx4jEFobz7nYRSwZJN7MjnfDpn5hPsQOih+fcJZg9NXUgpiyyrygjowyE04GkYcTuMexwhgmBH1Cy0oesi8NY4h/T92yNpaGaSnw9viAG5XK2zalOsIviCNIVcTxF0xr7+kMGJyPlGpSp1YdeZNtbOJGe2uBG9T9qhVynfSKVvmUpnk1fpFQ5X+h9Bi4tJHAomjuVJU/DXgmH3gi0t8yF85ws8DUGc9BsKLSyexeK/ESrs66Ll76HewBRd1fffEnEYRnGbJ1KKwQo6oVgGC9MzT9r0nEf3jg25zMtYVnG+fswkj6opizspGylh1lGHF+jDZSGmHeyv0j45u6+SZxfzI6Hlqn2IXReOxnLVZeUqNb0+zmdwe00YO/3RszTO3xNnj0xm2QWuwqEsqyVqpz1tPaLdzqH5Lavysi7qzaqYLaHfzTvIpv+sG8QM",
APNSKey.type: sampleOrderType
]
static let sampleSiteIDFromNotificationWithNoteFullData: Int64 = 205617935
static let sampleOrderIDFromNotificationWithNoteFullData: Int64 = 306
static var sampleOrderWithNoteFullDataOrderID = Order.fake().copy(siteID: sampleSiteIDFromNotificationWithNoteFullData,
orderID: sampleOrderIDFromNotificationWithNoteFullData)
}
Loading