diff --git a/RiotSwiftUI/Modules/Settings/Notifications/Service/Mock/MockNotificationSettingsService.swift b/RiotSwiftUI/Modules/Settings/Notifications/Service/Mock/MockNotificationSettingsService.swift index 32cc12c98..7d74f5288 100644 --- a/RiotSwiftUI/Modules/Settings/Notifications/Service/Mock/MockNotificationSettingsService.swift +++ b/RiotSwiftUI/Modules/Settings/Notifications/Service/Mock/MockNotificationSettingsService.swift @@ -46,7 +46,7 @@ class MockNotificationSettingsService: NotificationSettingsServiceType, Observab func updatePushRuleActions(for ruleId: String, enabled: Bool, actions: NotificationActions?, completion: ((Result) -> Void)?) { guard let ruleIndex = rules.firstIndex(where: { $0.ruleId == ruleId }) else { - completion?(.failure(NSError(domain: "fake", code: 0))) + completion?(.success(())) return } diff --git a/RiotSwiftUI/Modules/Settings/Notifications/Test/Unit/NotificationSettingsViewModelTests.swift b/RiotSwiftUI/Modules/Settings/Notifications/Test/Unit/NotificationSettingsViewModelTests.swift index b80e44c9a..ea698d9e0 100644 --- a/RiotSwiftUI/Modules/Settings/Notifications/Test/Unit/NotificationSettingsViewModelTests.swift +++ b/RiotSwiftUI/Modules/Settings/Notifications/Test/Unit/NotificationSettingsViewModelTests.swift @@ -45,9 +45,12 @@ final class NotificationSettingsViewModelTests: XCTestCase { let expectation = expectation(description: #function) setupWithPollRules() - viewModel.update(ruleID: .oneToOneRoom, isChecked: false) - - DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + viewModel.update(ruleID: .oneToOneRoom, isChecked: false) { result in + guard case .success = result else { + XCTFail() + return + } + XCTAssertEqual(self.viewModel.viewState.selectionState.count, 8) XCTAssertEqual(self.viewModel.viewState.selectionState[.oneToOneRoom], false) XCTAssertEqual(self.viewModel.viewState.selectionState[.oneToOnePollStart], false) @@ -68,9 +71,12 @@ final class NotificationSettingsViewModelTests: XCTestCase { let expectation = expectation(description: #function) setupWithPollRules() - viewModel.update(ruleID: .allOtherMessages, isChecked: false) - - DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + viewModel.update(ruleID: .allOtherMessages, isChecked: false) { result in + guard case .success = result else { + XCTFail() + return + } + XCTAssertEqual(self.viewModel.viewState.selectionState.count, 8) XCTAssertEqual(self.viewModel.viewState.selectionState[.allOtherMessages], false) XCTAssertEqual(self.viewModel.viewState.selectionState[.pollStart], false) @@ -91,9 +97,12 @@ final class NotificationSettingsViewModelTests: XCTestCase { let expectation = expectation(description: #function) setupWithPollRules() - viewModel.update(ruleID: .allOtherMessages, isChecked: false) - - DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + viewModel.update(ruleID: .allOtherMessages, isChecked: false) { result in + guard case .success = result else { + XCTFail() + return + } + // simulating a "mismatch" on the poll started rule self.viewModel.update(ruleID: .pollStart, isChecked: true) @@ -112,9 +121,12 @@ final class NotificationSettingsViewModelTests: XCTestCase { let expectation = expectation(description: #function) setupWithPollRules() - viewModel.update(ruleID: .oneToOneRoom, isChecked: false) - - DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + viewModel.update(ruleID: .oneToOneRoom, isChecked: false) { result in + guard case .success = result else { + XCTFail() + return + } + // simulating a "mismatch" on the one to one poll started rule self.viewModel.update(ruleID: .oneToOnePollStart, isChecked: true) diff --git a/RiotSwiftUI/Modules/Settings/Notifications/ViewModel/NotificationSettingsViewModel.swift b/RiotSwiftUI/Modules/Settings/Notifications/ViewModel/NotificationSettingsViewModel.swift index 73f11a931..208b8d2bb 100644 --- a/RiotSwiftUI/Modules/Settings/Notifications/ViewModel/NotificationSettingsViewModel.swift +++ b/RiotSwiftUI/Modules/Settings/Notifications/ViewModel/NotificationSettingsViewModel.swift @@ -105,7 +105,7 @@ final class NotificationSettingsViewModel: NotificationSettingsViewModelType, Ob // MARK: - Public - func update(ruleID: NotificationPushRuleId, isChecked: Bool) { + func update(ruleID: NotificationPushRuleId, isChecked: Bool, completion: ((Result) -> Void)? = nil) { let index = NotificationIndex.index(when: isChecked) let standardActions = ruleID.standardActions(for: index) let enabled = standardActions != .disabled @@ -119,7 +119,8 @@ final class NotificationSettingsViewModel: NotificationSettingsViewModelType, Ob id: ruleID, enabled: enabled, standardActions: standardActions, - then: ruleID.syncedRules + then: ruleID.syncedRules, + completion: completion ) default: @@ -127,7 +128,7 @@ final class NotificationSettingsViewModel: NotificationSettingsViewModelType, Ob for: ruleID.rawValue, enabled: enabled, actions: standardActions.actions, - completion: nil + completion: completion ) } } @@ -171,8 +172,8 @@ private extension NotificationSettingsViewModel { func updatePushAction(id: NotificationPushRuleId, enabled: Bool, standardActions: NotificationStandardActions, - then rules: [NotificationPushRuleId]) { - + then rules: [NotificationPushRuleId], + completion: ((Result) -> Void)?) { viewState.saving = true Task { @@ -187,18 +188,19 @@ private extension NotificationSettingsViewModel { } try await group.waitForAll() - await completeUpdate(error: nil) + await completeUpdate(completion: completion, result: .success(())) } } catch { - await completeUpdate(error: error) + await completeUpdate(completion: completion, result: .failure(error)) } } } @MainActor - func completeUpdate(error: Error?) { + func completeUpdate(completion: ((Result) -> Void)?, result: Result) { #warning("Handle error here in the next ticket") viewState.saving = false + completion?(result) } func rulesUpdated(newRules: [NotificationPushRuleType]) {