From c0220e52e51a0197cf8b857a4e67d109a98009eb Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 28 Sep 2022 13:12:06 +0200 Subject: [PATCH 01/14] Add backup callbacks registry --- .../Utils/BackupCallbackRegistry.swift | 36 ++++++++++++++++ .../Utils/BackupCallbackRegistryTests.swift | 43 +++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 Sources/XXMessengerClient/Utils/BackupCallbackRegistry.swift create mode 100644 Tests/XXMessengerClientTests/Utils/BackupCallbackRegistryTests.swift diff --git a/Sources/XXMessengerClient/Utils/BackupCallbackRegistry.swift b/Sources/XXMessengerClient/Utils/BackupCallbackRegistry.swift new file mode 100644 index 00000000..7c7fc9e8 --- /dev/null +++ b/Sources/XXMessengerClient/Utils/BackupCallbackRegistry.swift @@ -0,0 +1,36 @@ +import Foundation +import XCTestDynamicOverlay +import XXClient + +public struct BackupCallbacksRegistry { + public var register: (UpdateBackupFunc) -> Cancellable + public var registered: () -> UpdateBackupFunc +} + +extension BackupCallbacksRegistry { + public static func live() -> BackupCallbacksRegistry { + class Registry { + var callbacks: [UUID: UpdateBackupFunc] = [:] + } + let registry = Registry() + return BackupCallbacksRegistry( + register: { callback in + let id = UUID() + registry.callbacks[id] = callback + return Cancellable { registry.callbacks[id] = nil } + }, + registered: { + UpdateBackupFunc { data in + registry.callbacks.values.forEach { $0.handle(data) } + } + } + ) + } +} + +extension BackupCallbacksRegistry { + public static let unimplemented = BackupCallbacksRegistry( + register: XCTUnimplemented("\(Self.self).register", placeholder: Cancellable {}), + registered: XCTUnimplemented("\(Self.self).registered", placeholder: UpdateBackupFunc { _ in }) + ) +} diff --git a/Tests/XXMessengerClientTests/Utils/BackupCallbackRegistryTests.swift b/Tests/XXMessengerClientTests/Utils/BackupCallbackRegistryTests.swift new file mode 100644 index 00000000..d3cba50c --- /dev/null +++ b/Tests/XXMessengerClientTests/Utils/BackupCallbackRegistryTests.swift @@ -0,0 +1,43 @@ +import CustomDump +import XCTest +import XXClient +@testable import XXMessengerClient + +final class BackupCallbackRegistryTests: XCTestCase { + func testRegistry() { + var firstCallbackDidHandle: [Data] = [] + var secondCallbackDidHandle: [Data] = [] + + let firstCallback = UpdateBackupFunc { data in + firstCallbackDidHandle.append(data) + } + let secondCallback = UpdateBackupFunc { data in + secondCallbackDidHandle.append(data) + } + let callbackRegistry: BackupCallbacksRegistry = .live() + let registeredCallbacks = callbackRegistry.registered() + let firstCallbackCancellable = callbackRegistry.register(firstCallback) + let secondCallbackCancellable = callbackRegistry.register(secondCallback) + + let firstData = "1".data(using: .utf8)! + registeredCallbacks.handle(firstData) + + XCTAssertNoDifference(firstCallbackDidHandle, [firstData]) + XCTAssertNoDifference(secondCallbackDidHandle, [firstData]) + + firstCallbackCancellable.cancel() + let secondData = "2".data(using: .utf8)! + registeredCallbacks.handle(secondData) + + XCTAssertNoDifference(firstCallbackDidHandle, [firstData]) + XCTAssertNoDifference(secondCallbackDidHandle, [firstData, secondData]) + + secondCallbackCancellable.cancel() + + let thirdData = "3".data(using: .utf8)! + registeredCallbacks.handle(thirdData) + + XCTAssertNoDifference(firstCallbackDidHandle, [firstData]) + XCTAssertNoDifference(secondCallbackDidHandle, [firstData, secondData]) + } +} -- GitLab From 0f47f000e08722b6551b31cac3d8e09d14137332 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 28 Sep 2022 13:18:31 +0200 Subject: [PATCH 02/14] Add MessengerRegisterBackupCallback function --- .../MessengerRegisterBackupCallback.swift | 24 +++++++++++++ .../Messenger/Messenger.swift | 7 ++-- .../Messenger/MessengerEnvironment.swift | 3 ++ ...MessengerRegisterBackupCallbackTests.swift | 34 +++++++++++++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 Sources/XXMessengerClient/Messenger/Functions/MessengerRegisterBackupCallback.swift create mode 100644 Tests/XXMessengerClientTests/Messenger/Functions/MessengerRegisterBackupCallbackTests.swift diff --git a/Sources/XXMessengerClient/Messenger/Functions/MessengerRegisterBackupCallback.swift b/Sources/XXMessengerClient/Messenger/Functions/MessengerRegisterBackupCallback.swift new file mode 100644 index 00000000..f7c9a251 --- /dev/null +++ b/Sources/XXMessengerClient/Messenger/Functions/MessengerRegisterBackupCallback.swift @@ -0,0 +1,24 @@ +import XCTestDynamicOverlay +import XXClient + +public struct MessengerRegisterBackupCallback { + public var run: (UpdateBackupFunc) -> Cancellable + + public func callAsFunction(_ callback: UpdateBackupFunc) -> Cancellable { + run(callback) + } +} + +extension MessengerRegisterBackupCallback { + public static func live(_ env: MessengerEnvironment) -> MessengerRegisterBackupCallback { + MessengerRegisterBackupCallback { callback in + env.backupCallbacks.register(callback) + } + } +} + +extension MessengerRegisterBackupCallback { + public static let unimplemented = MessengerRegisterBackupCallback( + run: XCTUnimplemented("\(Self.self)", placeholder: Cancellable {}) + ) +} diff --git a/Sources/XXMessengerClient/Messenger/Messenger.swift b/Sources/XXMessengerClient/Messenger/Messenger.swift index ea85852c..030aefb5 100644 --- a/Sources/XXMessengerClient/Messenger/Messenger.swift +++ b/Sources/XXMessengerClient/Messenger/Messenger.swift @@ -29,6 +29,7 @@ public struct Messenger { public var registerForNotifications: MessengerRegisterForNotifications public var verifyContact: MessengerVerifyContact public var sendMessage: MessengerSendMessage + public var registerBackupCallback: MessengerRegisterBackupCallback } extension Messenger { @@ -61,7 +62,8 @@ extension Messenger { lookupContacts: .live(env), registerForNotifications: .live(env), verifyContact: .live(env), - sendMessage: .live(env) + sendMessage: .live(env), + registerBackupCallback: .live(env) ) } } @@ -95,6 +97,7 @@ extension Messenger { lookupContacts: .unimplemented, registerForNotifications: .unimplemented, verifyContact: .unimplemented, - sendMessage: .unimplemented + sendMessage: .unimplemented, + registerBackupCallback: .unimplemented ) } diff --git a/Sources/XXMessengerClient/Messenger/MessengerEnvironment.swift b/Sources/XXMessengerClient/Messenger/MessengerEnvironment.swift index 641a8062..f6f9a826 100644 --- a/Sources/XXMessengerClient/Messenger/MessengerEnvironment.swift +++ b/Sources/XXMessengerClient/Messenger/MessengerEnvironment.swift @@ -4,6 +4,7 @@ import XCTestDynamicOverlay public struct MessengerEnvironment { public var authCallbacks: AuthCallbacksRegistry + public var backupCallbacks: BackupCallbacksRegistry public var cMix: Stored<CMix?> public var downloadNDF: DownloadAndVerifySignedNdf public var e2e: Stored<E2E?> @@ -45,6 +46,7 @@ extension MessengerEnvironment { public static func live() -> MessengerEnvironment { MessengerEnvironment( authCallbacks: .live(), + backupCallbacks: .live(), cMix: .inMemory(), downloadNDF: .live, e2e: .inMemory(), @@ -81,6 +83,7 @@ extension MessengerEnvironment { extension MessengerEnvironment { public static let unimplemented = MessengerEnvironment( authCallbacks: .unimplemented, + backupCallbacks: .unimplemented, cMix: .unimplemented(), downloadNDF: .unimplemented, e2e: .unimplemented(), diff --git a/Tests/XXMessengerClientTests/Messenger/Functions/MessengerRegisterBackupCallbackTests.swift b/Tests/XXMessengerClientTests/Messenger/Functions/MessengerRegisterBackupCallbackTests.swift new file mode 100644 index 00000000..44e7e21c --- /dev/null +++ b/Tests/XXMessengerClientTests/Messenger/Functions/MessengerRegisterBackupCallbackTests.swift @@ -0,0 +1,34 @@ +import CustomDump +import XCTest +import XXClient +@testable import XXMessengerClient + +final class MessengerRegisterBackupCallbackTests: XCTestCase { + func testRegisterBackupCallback() { + var registeredCallbacks: [UpdateBackupFunc] = [] + var didHandleData: [Data] = [] + var didCancelRegisteredCallback = 0 + + var env: MessengerEnvironment = .unimplemented + env.backupCallbacks.register = { callback in + registeredCallbacks.append(callback) + return Cancellable { didCancelRegisteredCallback += 1 } + } + let registerBackupCallback: MessengerRegisterBackupCallback = .live(env) + let cancellable = registerBackupCallback(UpdateBackupFunc { data in + didHandleData.append(data) + }) + + XCTAssertEqual(registeredCallbacks.count, 1) + + registeredCallbacks.forEach { callback in + callback.handle("test".data(using: .utf8)!) + } + + XCTAssertNoDifference(didHandleData, ["test".data(using: .utf8)!]) + + cancellable.cancel() + + XCTAssertEqual(didCancelRegisteredCallback, 1) + } +} -- GitLab From ef6c6113d3543851abeb0debdb1f3efece20ab36 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 28 Sep 2022 13:23:30 +0200 Subject: [PATCH 03/14] Add MessengerIsBackupRunning function --- .../Functions/MessengerIsBackupRunning.swift | 24 ++++++++++++ .../Messenger/Messenger.swift | 7 +++- .../Messenger/MessengerEnvironment.swift | 3 ++ .../MessengerIsBackupRunningTests.swift | 37 +++++++++++++++++++ 4 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 Sources/XXMessengerClient/Messenger/Functions/MessengerIsBackupRunning.swift create mode 100644 Tests/XXMessengerClientTests/Messenger/Functions/MessengerIsBackupRunningTests.swift diff --git a/Sources/XXMessengerClient/Messenger/Functions/MessengerIsBackupRunning.swift b/Sources/XXMessengerClient/Messenger/Functions/MessengerIsBackupRunning.swift new file mode 100644 index 00000000..08453e23 --- /dev/null +++ b/Sources/XXMessengerClient/Messenger/Functions/MessengerIsBackupRunning.swift @@ -0,0 +1,24 @@ +import XCTestDynamicOverlay +import XXClient + +public struct MessengerIsBackupRunning { + public var run: () -> Bool + + public func callAsFunction() -> Bool { + run() + } +} + +extension MessengerIsBackupRunning { + public static func live(_ env: MessengerEnvironment) -> MessengerIsBackupRunning { + MessengerIsBackupRunning { + env.backup()?.isRunning() == true + } + } +} + +extension MessengerIsBackupRunning { + public static let unimplemented = MessengerIsBackupRunning( + run: XCTUnimplemented("\(Self.self)") + ) +} diff --git a/Sources/XXMessengerClient/Messenger/Messenger.swift b/Sources/XXMessengerClient/Messenger/Messenger.swift index 030aefb5..9e373e0b 100644 --- a/Sources/XXMessengerClient/Messenger/Messenger.swift +++ b/Sources/XXMessengerClient/Messenger/Messenger.swift @@ -30,6 +30,7 @@ public struct Messenger { public var verifyContact: MessengerVerifyContact public var sendMessage: MessengerSendMessage public var registerBackupCallback: MessengerRegisterBackupCallback + public var isBackupRunning: MessengerIsBackupRunning } extension Messenger { @@ -63,7 +64,8 @@ extension Messenger { registerForNotifications: .live(env), verifyContact: .live(env), sendMessage: .live(env), - registerBackupCallback: .live(env) + registerBackupCallback: .live(env), + isBackupRunning: .live(env) ) } } @@ -98,6 +100,7 @@ extension Messenger { registerForNotifications: .unimplemented, verifyContact: .unimplemented, sendMessage: .unimplemented, - registerBackupCallback: .unimplemented + registerBackupCallback: .unimplemented, + isBackupRunning: .unimplemented ) } diff --git a/Sources/XXMessengerClient/Messenger/MessengerEnvironment.swift b/Sources/XXMessengerClient/Messenger/MessengerEnvironment.swift index f6f9a826..d2ae4fac 100644 --- a/Sources/XXMessengerClient/Messenger/MessengerEnvironment.swift +++ b/Sources/XXMessengerClient/Messenger/MessengerEnvironment.swift @@ -4,6 +4,7 @@ import XCTestDynamicOverlay public struct MessengerEnvironment { public var authCallbacks: AuthCallbacksRegistry + public var backup: Stored<Backup?> public var backupCallbacks: BackupCallbacksRegistry public var cMix: Stored<CMix?> public var downloadNDF: DownloadAndVerifySignedNdf @@ -46,6 +47,7 @@ extension MessengerEnvironment { public static func live() -> MessengerEnvironment { MessengerEnvironment( authCallbacks: .live(), + backup: .inMemory(), backupCallbacks: .live(), cMix: .inMemory(), downloadNDF: .live, @@ -83,6 +85,7 @@ extension MessengerEnvironment { extension MessengerEnvironment { public static let unimplemented = MessengerEnvironment( authCallbacks: .unimplemented, + backup: .unimplemented(), backupCallbacks: .unimplemented, cMix: .unimplemented(), downloadNDF: .unimplemented, diff --git a/Tests/XXMessengerClientTests/Messenger/Functions/MessengerIsBackupRunningTests.swift b/Tests/XXMessengerClientTests/Messenger/Functions/MessengerIsBackupRunningTests.swift new file mode 100644 index 00000000..7076aa64 --- /dev/null +++ b/Tests/XXMessengerClientTests/Messenger/Functions/MessengerIsBackupRunningTests.swift @@ -0,0 +1,37 @@ +import XCTest +import XXClient +@testable import XXMessengerClient + +final class MessengerIsBackupRunningTests: XCTestCase { + func testWithoutBackup() { + var env: MessengerEnvironment = .unimplemented + env.backup.get = { nil } + let isRunning: MessengerIsBackupRunning = .live(env) + + XCTAssertFalse(isRunning()) + } + + func testWithBackupRunning() { + var env: MessengerEnvironment = .unimplemented + env.backup.get = { + var backup: Backup = .unimplemented + backup.isRunning.run = { true } + return backup + } + let isRunning: MessengerIsBackupRunning = .live(env) + + XCTAssertTrue(isRunning()) + } + + func testWithBackupNotRunning() { + var env: MessengerEnvironment = .unimplemented + env.backup.get = { + var backup: Backup = .unimplemented + backup.isRunning.run = { false } + return backup + } + let isRunning: MessengerIsBackupRunning = .live(env) + + XCTAssertFalse(isRunning()) + } +} -- GitLab From 5a258fcd289fb6a75c0ec5b585841cc09075c7b6 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 28 Sep 2022 13:34:28 +0200 Subject: [PATCH 04/14] Add MessengerStopBackup function --- .../Functions/MessengerStopBackup.swift | 26 +++++++++ .../Messenger/Messenger.swift | 7 ++- .../Functions/MessengerStopBackupTests.swift | 53 +++++++++++++++++++ 3 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 Sources/XXMessengerClient/Messenger/Functions/MessengerStopBackup.swift create mode 100644 Tests/XXMessengerClientTests/Messenger/Functions/MessengerStopBackupTests.swift diff --git a/Sources/XXMessengerClient/Messenger/Functions/MessengerStopBackup.swift b/Sources/XXMessengerClient/Messenger/Functions/MessengerStopBackup.swift new file mode 100644 index 00000000..f5471166 --- /dev/null +++ b/Sources/XXMessengerClient/Messenger/Functions/MessengerStopBackup.swift @@ -0,0 +1,26 @@ +import Bindings +import XCTestDynamicOverlay + +public struct MessengerStopBackup { + public var run: () throws -> Void + + public func callAsFunction() throws { + try run() + } +} + +extension MessengerStopBackup { + public static func live(_ env: MessengerEnvironment) -> MessengerStopBackup { + MessengerStopBackup { + guard let backup = env.backup() else { return } + try backup.stop() + env.backup.set(nil) + } + } +} + +extension MessengerStopBackup { + public static let unimplemented = MessengerStopBackup( + run: XCTUnimplemented("\(Self.self)") + ) +} diff --git a/Sources/XXMessengerClient/Messenger/Messenger.swift b/Sources/XXMessengerClient/Messenger/Messenger.swift index 9e373e0b..bc1c8bde 100644 --- a/Sources/XXMessengerClient/Messenger/Messenger.swift +++ b/Sources/XXMessengerClient/Messenger/Messenger.swift @@ -31,6 +31,7 @@ public struct Messenger { public var sendMessage: MessengerSendMessage public var registerBackupCallback: MessengerRegisterBackupCallback public var isBackupRunning: MessengerIsBackupRunning + public var stopBackup: MessengerStopBackup } extension Messenger { @@ -65,7 +66,8 @@ extension Messenger { verifyContact: .live(env), sendMessage: .live(env), registerBackupCallback: .live(env), - isBackupRunning: .live(env) + isBackupRunning: .live(env), + stopBackup: .live(env) ) } } @@ -101,6 +103,7 @@ extension Messenger { verifyContact: .unimplemented, sendMessage: .unimplemented, registerBackupCallback: .unimplemented, - isBackupRunning: .unimplemented + isBackupRunning: .unimplemented, + stopBackup: .unimplemented ) } diff --git a/Tests/XXMessengerClientTests/Messenger/Functions/MessengerStopBackupTests.swift b/Tests/XXMessengerClientTests/Messenger/Functions/MessengerStopBackupTests.swift new file mode 100644 index 00000000..306b6c2d --- /dev/null +++ b/Tests/XXMessengerClientTests/Messenger/Functions/MessengerStopBackupTests.swift @@ -0,0 +1,53 @@ +import CustomDump +import XCTest +import XXClient +@testable import XXMessengerClient + +final class MessengerStopBackupTests: XCTestCase { + func testStop() throws { + var didStopBackup = 0 + var didSetBackup: [Backup?] = [] + + var env: MessengerEnvironment = .unimplemented + env.backup.get = { + var backup: Backup = .unimplemented + backup.stop.run = { didStopBackup += 1 } + return backup + } + env.backup.set = { backup in + didSetBackup.append(backup) + } + let stop: MessengerStopBackup = .live(env) + + try stop() + + XCTAssertEqual(didStopBackup, 1) + XCTAssertEqual(didSetBackup.count, 1) + XCTAssertNil(didSetBackup.first as? Backup) + } + + func testStopFailure() { + struct Failure: Error, Equatable {} + let failure = Failure() + + var env: MessengerEnvironment = .unimplemented + env.backup.get = { + var backup: Backup = .unimplemented + backup.stop.run = { throw failure } + return backup + } + let stop: MessengerStopBackup = .live(env) + + XCTAssertThrowsError(try stop()) { error in + XCTAssertNoDifference(error as NSError, failure as NSError) + } + } + + func testStopWithoutBackup() throws { + var env: MessengerEnvironment = .unimplemented + env.backup.get = { nil } + let stop: MessengerStopBackup = .live(env) + + try stop() + } +} -- GitLab From fa71cb6e08e84bfc5e107a0794653894ede15646 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 28 Sep 2022 13:53:24 +0200 Subject: [PATCH 05/14] Add MessengerStartBackup function --- .../Functions/MessengerStartBakcup.swift | 45 ++++++ .../Messenger/Messenger.swift | 3 + .../Messenger/MessengerEnvironment.swift | 3 + .../Functions/MessengerStartBackupTests.swift | 128 ++++++++++++++++++ 4 files changed, 179 insertions(+) create mode 100644 Sources/XXMessengerClient/Messenger/Functions/MessengerStartBakcup.swift create mode 100644 Tests/XXMessengerClientTests/Messenger/Functions/MessengerStartBackupTests.swift diff --git a/Sources/XXMessengerClient/Messenger/Functions/MessengerStartBakcup.swift b/Sources/XXMessengerClient/Messenger/Functions/MessengerStartBakcup.swift new file mode 100644 index 00000000..366d87fc --- /dev/null +++ b/Sources/XXMessengerClient/Messenger/Functions/MessengerStartBakcup.swift @@ -0,0 +1,45 @@ +import XCTestDynamicOverlay +import XXClient + +public struct MessengerStartBackup { + public enum Error: Swift.Error, Equatable { + case isRunning + case notConnected + case notLoggedIn + } + + public var run: (String) throws -> Void + + public func callAsFunction(password: String) throws { + try run(password) + } +} + +extension MessengerStartBackup { + public static func live(_ env: MessengerEnvironment) -> MessengerStartBackup { + MessengerStartBackup { password in + guard env.backup()?.isRunning() != true else { + throw Error.isRunning + } + guard let e2e = env.e2e() else { + throw Error.notConnected + } + guard let ud = env.ud() else { + throw Error.notLoggedIn + } + let backup = try env.initializeBackup( + e2eId: e2e.getId(), + udId: ud.getId(), + password: password, + callback: env.backupCallbacks.registered() + ) + env.backup.set(backup) + } + } +} + +extension MessengerStartBackup { + public static let unimplemented = MessengerStartBackup( + run: XCTUnimplemented("\(Self.self)") + ) +} diff --git a/Sources/XXMessengerClient/Messenger/Messenger.swift b/Sources/XXMessengerClient/Messenger/Messenger.swift index bc1c8bde..7bccebdf 100644 --- a/Sources/XXMessengerClient/Messenger/Messenger.swift +++ b/Sources/XXMessengerClient/Messenger/Messenger.swift @@ -31,6 +31,7 @@ public struct Messenger { public var sendMessage: MessengerSendMessage public var registerBackupCallback: MessengerRegisterBackupCallback public var isBackupRunning: MessengerIsBackupRunning + public var startBackup: MessengerStartBackup public var stopBackup: MessengerStopBackup } @@ -67,6 +68,7 @@ extension Messenger { sendMessage: .live(env), registerBackupCallback: .live(env), isBackupRunning: .live(env), + startBackup: .live(env), stopBackup: .live(env) ) } @@ -104,6 +106,7 @@ extension Messenger { sendMessage: .unimplemented, registerBackupCallback: .unimplemented, isBackupRunning: .unimplemented, + startBackup: .unimplemented, stopBackup: .unimplemented ) } diff --git a/Sources/XXMessengerClient/Messenger/MessengerEnvironment.swift b/Sources/XXMessengerClient/Messenger/MessengerEnvironment.swift index d2ae4fac..5d940270 100644 --- a/Sources/XXMessengerClient/Messenger/MessengerEnvironment.swift +++ b/Sources/XXMessengerClient/Messenger/MessengerEnvironment.swift @@ -14,6 +14,7 @@ public struct MessengerEnvironment { public var getCMixParams: GetCMixParams public var getE2EParams: GetE2EParams public var getSingleUseParams: GetSingleUseParams + public var initializeBackup: InitializeBackup public var isListeningForMessages: Stored<Bool> public var isRegisteredWithUD: IsRegisteredWithUD public var loadCMix: LoadCMix @@ -57,6 +58,7 @@ extension MessengerEnvironment { getCMixParams: .liveDefault, getE2EParams: .liveDefault, getSingleUseParams: .liveDefault, + initializeBackup: .live, isListeningForMessages: .inMemory(false), isRegisteredWithUD: .live, loadCMix: .live, @@ -95,6 +97,7 @@ extension MessengerEnvironment { getCMixParams: .unimplemented, getE2EParams: .unimplemented, getSingleUseParams: .unimplemented, + initializeBackup: .unimplemented, isListeningForMessages: .unimplemented(placeholder: false), isRegisteredWithUD: .unimplemented, loadCMix: .unimplemented, diff --git a/Tests/XXMessengerClientTests/Messenger/Functions/MessengerStartBackupTests.swift b/Tests/XXMessengerClientTests/Messenger/Functions/MessengerStartBackupTests.swift new file mode 100644 index 00000000..c1e703a6 --- /dev/null +++ b/Tests/XXMessengerClientTests/Messenger/Functions/MessengerStartBackupTests.swift @@ -0,0 +1,128 @@ +import CustomDump +import XCTest +import XXClient +@testable import XXMessengerClient + +final class MessengerStartBackupTests: XCTestCase { + func testStart() throws { + struct InitBackupParams: Equatable { + var e2eId: Int + var udId: Int + var password: String + } + var didInitializeBackup: [InitBackupParams] = [] + var backupCallbacks: [UpdateBackupFunc] = [] + var didHandleCallback: [Data] = [] + var didSetBackup: [Backup?] = [] + + let password = "test-password" + let e2eId = 123 + let udId = 321 + let data = "test-data".data(using: .utf8)! + + var env: MessengerEnvironment = .unimplemented + env.backup.get = { nil } + env.backup.set = { didSetBackup.append($0) } + env.e2e.get = { + var e2e: E2E = .unimplemented + e2e.getId.run = { e2eId } + return e2e + } + env.ud.get = { + var ud: UserDiscovery = .unimplemented + ud.getId.run = { udId } + return ud + } + env.backupCallbacks.registered = { + UpdateBackupFunc { didHandleCallback.append($0) } + } + env.initializeBackup.run = { e2eId, udId, password, callback in + didInitializeBackup.append(.init(e2eId: e2eId, udId: udId, password: password)) + backupCallbacks.append(callback) + return .unimplemented + } + let start: MessengerStartBackup = .live(env) + + try start(password: password) + + XCTAssertNoDifference(didInitializeBackup, [ + .init(e2eId: e2eId, udId: udId, password: password) + ]) + XCTAssertNoDifference(didSetBackup.map { $0 != nil }, [true]) + + backupCallbacks.forEach { $0.handle(data) } + + XCTAssertNoDifference(didHandleCallback, [data]) + } + + func testStartWhenRunning() { + var env: MessengerEnvironment = .unimplemented + env.backup.get = { + var backup: Backup = .unimplemented + backup.isRunning.run = { true } + return backup + } + let start: MessengerStartBackup = .live(env) + + XCTAssertThrowsError(try start(password: "")) { error in + XCTAssertNoDifference( + error as NSError, + MessengerStartBackup.Error.isRunning as NSError + ) + } + } + + func testStartWhenNotConnected() { + var env: MessengerEnvironment = .unimplemented + env.backup.get = { nil } + env.e2e.get = { nil } + let start: MessengerStartBackup = .live(env) + + XCTAssertThrowsError(try start(password: "")) { error in + XCTAssertNoDifference( + error as NSError, + MessengerStartBackup.Error.notConnected as NSError + ) + } + } + + func testStartWhenNotLoggedIn() { + var env: MessengerEnvironment = .unimplemented + env.backup.get = { nil } + env.e2e.get = { .unimplemented } + env.ud.get = { nil } + let start: MessengerStartBackup = .live(env) + + XCTAssertThrowsError(try start(password: "")) { error in + XCTAssertNoDifference( + error as NSError, + MessengerStartBackup.Error.notLoggedIn as NSError + ) + } + } + + func testStartFailure() { + struct Failure: Error, Equatable {} + let failure = Failure() + + var env: MessengerEnvironment = .unimplemented + env.backup.get = { nil } + env.e2e.get = { + var e2e: E2E = .unimplemented + e2e.getId.run = { 123 } + return e2e + } + env.ud.get = { + var ud: UserDiscovery = .unimplemented + ud.getId.run = { 321 } + return ud + } + env.backupCallbacks.registered = { UpdateBackupFunc { _ in } } + env.initializeBackup.run = { _, _, _, _ in throw failure } + let start: MessengerStartBackup = .live(env) + + XCTAssertThrowsError(try start(password: "abcd")) { error in + XCTAssertNoDifference(error as NSError, failure as NSError) + } + } +} -- GitLab From d932ed9ca21a543e3e8a6ad50c2c25f5893304ef Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 28 Sep 2022 13:59:33 +0200 Subject: [PATCH 06/14] Add MessengerResumeBackup function --- .../Functions/MessengerResumeBackup.swift | 44 ++++++ .../Messenger/Messenger.swift | 3 + .../Messenger/MessengerEnvironment.swift | 3 + .../MessengerResumeBackupTests.swift | 126 ++++++++++++++++++ 4 files changed, 176 insertions(+) create mode 100644 Sources/XXMessengerClient/Messenger/Functions/MessengerResumeBackup.swift create mode 100644 Tests/XXMessengerClientTests/Messenger/Functions/MessengerResumeBackupTests.swift diff --git a/Sources/XXMessengerClient/Messenger/Functions/MessengerResumeBackup.swift b/Sources/XXMessengerClient/Messenger/Functions/MessengerResumeBackup.swift new file mode 100644 index 00000000..9c4d62a0 --- /dev/null +++ b/Sources/XXMessengerClient/Messenger/Functions/MessengerResumeBackup.swift @@ -0,0 +1,44 @@ +import Bindings +import XCTestDynamicOverlay + +public struct MessengerResumeBackup { + public enum Error: Swift.Error, Equatable { + case isRunning + case notConnected + case notLoggedIn + } + + public var run: () throws -> Void + + public func callAsFunction() throws { + try run() + } +} + +extension MessengerResumeBackup { + public static func live(_ env: MessengerEnvironment) -> MessengerResumeBackup { + MessengerResumeBackup { + guard env.backup()?.isRunning() != true else { + throw Error.isRunning + } + guard let e2e = env.e2e() else { + throw Error.notConnected + } + guard let ud = env.ud() else { + throw Error.notLoggedIn + } + let backup = try env.resumeBackup( + e2eId: e2e.getId(), + udId: ud.getId(), + callback: env.backupCallbacks.registered() + ) + env.backup.set(backup) + } + } +} + +extension MessengerResumeBackup { + public static let unimplemented = MessengerResumeBackup( + run: XCTUnimplemented("\(Self.self)") + ) +} diff --git a/Sources/XXMessengerClient/Messenger/Messenger.swift b/Sources/XXMessengerClient/Messenger/Messenger.swift index 7bccebdf..087bc40d 100644 --- a/Sources/XXMessengerClient/Messenger/Messenger.swift +++ b/Sources/XXMessengerClient/Messenger/Messenger.swift @@ -32,6 +32,7 @@ public struct Messenger { public var registerBackupCallback: MessengerRegisterBackupCallback public var isBackupRunning: MessengerIsBackupRunning public var startBackup: MessengerStartBackup + public var resumeBackup: MessengerResumeBackup public var stopBackup: MessengerStopBackup } @@ -69,6 +70,7 @@ extension Messenger { registerBackupCallback: .live(env), isBackupRunning: .live(env), startBackup: .live(env), + resumeBackup: .live(env), stopBackup: .live(env) ) } @@ -107,6 +109,7 @@ extension Messenger { registerBackupCallback: .unimplemented, isBackupRunning: .unimplemented, startBackup: .unimplemented, + resumeBackup: .unimplemented, stopBackup: .unimplemented ) } diff --git a/Sources/XXMessengerClient/Messenger/MessengerEnvironment.swift b/Sources/XXMessengerClient/Messenger/MessengerEnvironment.swift index 5d940270..f019df16 100644 --- a/Sources/XXMessengerClient/Messenger/MessengerEnvironment.swift +++ b/Sources/XXMessengerClient/Messenger/MessengerEnvironment.swift @@ -29,6 +29,7 @@ public struct MessengerEnvironment { public var newUdManagerFromBackup: NewUdManagerFromBackup public var passwordStorage: PasswordStorage public var registerForNotifications: RegisterForNotifications + public var resumeBackup: ResumeBackup public var searchUD: SearchUD public var sleep: (TimeInterval) -> Void public var storageDir: String @@ -73,6 +74,7 @@ extension MessengerEnvironment { newUdManagerFromBackup: .live, passwordStorage: .keychain, registerForNotifications: .live, + resumeBackup: .live, searchUD: .live, sleep: { Thread.sleep(forTimeInterval: $0) }, storageDir: MessengerEnvironment.defaultStorageDir, @@ -112,6 +114,7 @@ extension MessengerEnvironment { newUdManagerFromBackup: .unimplemented, passwordStorage: .unimplemented, registerForNotifications: .unimplemented, + resumeBackup: .unimplemented, searchUD: .unimplemented, sleep: XCTUnimplemented("\(Self.self).sleep"), storageDir: "unimplemented", diff --git a/Tests/XXMessengerClientTests/Messenger/Functions/MessengerResumeBackupTests.swift b/Tests/XXMessengerClientTests/Messenger/Functions/MessengerResumeBackupTests.swift new file mode 100644 index 00000000..7979ffbd --- /dev/null +++ b/Tests/XXMessengerClientTests/Messenger/Functions/MessengerResumeBackupTests.swift @@ -0,0 +1,126 @@ +import CustomDump +import XCTest +import XXClient +@testable import XXMessengerClient + +final class MessengerResumeBackupTests: XCTestCase { + func testResume() throws { + struct ResumeBackupParams: Equatable { + var e2eId: Int + var udId: Int + } + var didResumeBackup: [ResumeBackupParams] = [] + var backupCallbacks: [UpdateBackupFunc] = [] + var didHandleCallback: [Data] = [] + var didSetBackup: [Backup?] = [] + + let e2eId = 123 + let udId = 321 + let data = "test-data".data(using: .utf8)! + + var env: MessengerEnvironment = .unimplemented + env.backup.get = { nil } + env.backup.set = { didSetBackup.append($0) } + env.e2e.get = { + var e2e: E2E = .unimplemented + e2e.getId.run = { e2eId } + return e2e + } + env.ud.get = { + var ud: UserDiscovery = .unimplemented + ud.getId.run = { udId } + return ud + } + env.backupCallbacks.registered = { + UpdateBackupFunc { didHandleCallback.append($0) } + } + env.resumeBackup.run = { e2eId, udId, callback in + didResumeBackup.append(.init(e2eId: e2eId, udId: udId)) + backupCallbacks.append(callback) + return .unimplemented + } + let resume: MessengerResumeBackup = .live(env) + + try resume() + + XCTAssertNoDifference(didResumeBackup, [ + .init(e2eId: e2eId, udId: udId) + ]) + XCTAssertNoDifference(didSetBackup.map { $0 != nil }, [true]) + + backupCallbacks.forEach { $0.handle(data) } + + XCTAssertNoDifference(didHandleCallback, [data]) + } + + func testResumeWhenRunning() { + var env: MessengerEnvironment = .unimplemented + env.backup.get = { + var backup: Backup = .unimplemented + backup.isRunning.run = { true } + return backup + } + let resume: MessengerResumeBackup = .live(env) + + XCTAssertThrowsError(try resume()) { error in + XCTAssertNoDifference( + error as NSError, + MessengerResumeBackup.Error.isRunning as NSError + ) + } + } + + func testResumeWhenNotConnected() { + var env: MessengerEnvironment = .unimplemented + env.backup.get = { nil } + env.e2e.get = { nil } + let resume: MessengerResumeBackup = .live(env) + + XCTAssertThrowsError(try resume()) { error in + XCTAssertNoDifference( + error as NSError, + MessengerResumeBackup.Error.notConnected as NSError + ) + } + } + + func testResumeWhenNotLoggedIn() { + var env: MessengerEnvironment = .unimplemented + env.backup.get = { nil } + env.e2e.get = { .unimplemented } + env.ud.get = { nil } + let resume: MessengerResumeBackup = .live(env) + + XCTAssertThrowsError(try resume()) { error in + XCTAssertNoDifference( + error as NSError, + MessengerResumeBackup.Error.notLoggedIn as NSError + ) + } + } + + func testResumeFailure() { + struct Failure: Error, Equatable {} + let failure = Failure() + + var env: MessengerEnvironment = .unimplemented + env.backup.get = { nil } + env.e2e.get = { + var e2e: E2E = .unimplemented + e2e.getId.run = { 123 } + return e2e + } + env.ud.get = { + var ud: UserDiscovery = .unimplemented + ud.getId.run = { 321 } + return ud + } + env.backupCallbacks.registered = { UpdateBackupFunc { _ in } } + env.resumeBackup.run = { _, _ , _ in throw failure } + let resume: MessengerResumeBackup = .live(env) + + XCTAssertThrowsError(try resume()) { error in + XCTAssertNoDifference(error as NSError, failure as NSError) + } + } +} -- GitLab From b4d89289e55ae90b8b8709987b5ad4a83d86abb9 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 28 Sep 2022 14:22:00 +0200 Subject: [PATCH 07/14] Refactor BackupParams coding --- .../Messenger/Functions/MessengerRestoreBackup.swift | 3 +-- Sources/XXMessengerClient/Utils/BackupParams.swift | 12 +++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Sources/XXMessengerClient/Messenger/Functions/MessengerRestoreBackup.swift b/Sources/XXMessengerClient/Messenger/Functions/MessengerRestoreBackup.swift index 66f50dd5..b196faca 100644 --- a/Sources/XXMessengerClient/Messenger/Functions/MessengerRestoreBackup.swift +++ b/Sources/XXMessengerClient/Messenger/Functions/MessengerRestoreBackup.swift @@ -42,9 +42,8 @@ extension MessengerRestoreBackup { sessionPassword: password, backupFileContents: backupData ) - let decoder = JSONDecoder() let paramsData = report.params.data(using: .utf8)! - let params = try decoder.decode(BackupParams.self, from: paramsData) + let params = try BackupParams.decode(paramsData) let cMix = try env.loadCMix( storageDir: storageDir, password: password, diff --git a/Sources/XXMessengerClient/Utils/BackupParams.swift b/Sources/XXMessengerClient/Utils/BackupParams.swift index 02fdc595..c3bd8fc0 100644 --- a/Sources/XXMessengerClient/Utils/BackupParams.swift +++ b/Sources/XXMessengerClient/Utils/BackupParams.swift @@ -1,6 +1,6 @@ import Foundation -public struct BackupParams: Equatable, Codable { +public struct BackupParams: Equatable { public init( username: String, email: String?, @@ -15,3 +15,13 @@ public struct BackupParams: Equatable, Codable { public var email: String? public var phone: String? } + +extension BackupParams: Codable { + public static func decode(_ data: Data) throws -> Self { + try JSONDecoder().decode(Self.self, from: data) + } + + public func encode() throws -> Data { + try JSONEncoder().encode(self) + } +} -- GitLab From 712a6c512a392d7e7c76f32274c2910f4ffedcd4 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 28 Sep 2022 14:28:41 +0200 Subject: [PATCH 08/14] Add MessengerBackupParams function --- .../Functions/MessengerBackupParams.swift | 33 ++++++++++ .../Messenger/Messenger.swift | 3 + .../MessengerBackupParamsTests.swift | 62 +++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 Sources/XXMessengerClient/Messenger/Functions/MessengerBackupParams.swift create mode 100644 Tests/XXMessengerClientTests/Messenger/Functions/MessengerBackupParamsTests.swift diff --git a/Sources/XXMessengerClient/Messenger/Functions/MessengerBackupParams.swift b/Sources/XXMessengerClient/Messenger/Functions/MessengerBackupParams.swift new file mode 100644 index 00000000..f5ac71f0 --- /dev/null +++ b/Sources/XXMessengerClient/Messenger/Functions/MessengerBackupParams.swift @@ -0,0 +1,33 @@ +import Bindings +import XCTestDynamicOverlay + +public struct MessengerBackupParams { + public enum Error: Swift.Error, Equatable { + case notRunning + } + + public var run: (BackupParams) throws -> Void + + public func callAsFunction(_ params: BackupParams) throws { + try run(params) + } +} + +extension MessengerBackupParams { + public static func live(_ env: MessengerEnvironment) -> MessengerBackupParams { + MessengerBackupParams { params in + guard let backup = env.backup(), backup.isRunning() else { + throw Error.notRunning + } + let paramsData = try params.encode() + let paramsString = String(data: paramsData, encoding: .utf8)! + backup.addJSON(paramsString) + } + } +} + +extension MessengerBackupParams { + public static let unimplemented = MessengerBackupParams( + run: XCTUnimplemented("\(Self.self)") + ) +} diff --git a/Sources/XXMessengerClient/Messenger/Messenger.swift b/Sources/XXMessengerClient/Messenger/Messenger.swift index 087bc40d..dab59a2f 100644 --- a/Sources/XXMessengerClient/Messenger/Messenger.swift +++ b/Sources/XXMessengerClient/Messenger/Messenger.swift @@ -33,6 +33,7 @@ public struct Messenger { public var isBackupRunning: MessengerIsBackupRunning public var startBackup: MessengerStartBackup public var resumeBackup: MessengerResumeBackup + public var backupParams: MessengerBackupParams public var stopBackup: MessengerStopBackup } @@ -71,6 +72,7 @@ extension Messenger { isBackupRunning: .live(env), startBackup: .live(env), resumeBackup: .live(env), + backupParams: .live(env), stopBackup: .live(env) ) } @@ -110,6 +112,7 @@ extension Messenger { isBackupRunning: .unimplemented, startBackup: .unimplemented, resumeBackup: .unimplemented, + backupParams: .unimplemented, stopBackup: .unimplemented ) } diff --git a/Tests/XXMessengerClientTests/Messenger/Functions/MessengerBackupParamsTests.swift b/Tests/XXMessengerClientTests/Messenger/Functions/MessengerBackupParamsTests.swift new file mode 100644 index 00000000..e0af7129 --- /dev/null +++ b/Tests/XXMessengerClientTests/Messenger/Functions/MessengerBackupParamsTests.swift @@ -0,0 +1,62 @@ +import CustomDump +import XCTest +import XXClient +@testable import XXMessengerClient + +final class MessengerBackupParamsTests: XCTestCase { + func testBackupParams() throws { + var didAddJSON: [String] = [] + + var env: MessengerEnvironment = .unimplemented + env.backup.get = { + var backup: Backup = .unimplemented + backup.isRunning.run = { true } + backup.addJSON.run = { didAddJSON.append($0) } + return backup + } + let backup: MessengerBackupParams = .live(env) + let params = BackupParams( + username: "test-username", + email: "test-email", + phone: "test-phone" + ) + + try backup(params) + + XCTAssertNoDifference(didAddJSON, [ + String(data: try params.encode(), encoding: .utf8)! + ]) + } + + func testBackupParamsWhenNoBackup() { + var env: MessengerEnvironment = .unimplemented + env.backup.get = { nil } + let backup: MessengerBackupParams = .live(env) + let params = BackupParams(username: "test", email: nil, phone: nil) + + XCTAssertThrowsError(try backup(params)) { error in + XCTAssertNoDifference( + error as NSError, + MessengerBackupParams.Error.notRunning as NSError + ) + } + } + + func testBackupParamsWhenBackupNotRunning() { + var env: MessengerEnvironment = .unimplemented + env.backup.get = { + var backup: Backup = .unimplemented + backup.isRunning.run = { false } + return backup + } + let backup: MessengerBackupParams = .live(env) + let params = BackupParams(username: "test", email: nil, phone: nil) + + XCTAssertThrowsError(try backup(params)) { error in + XCTAssertNoDifference( + error as NSError, + MessengerBackupParams.Error.notRunning as NSError + ) + } + } +} -- GitLab From c87b61ae6e869bb7d4db44701b89d96001bcc036 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 28 Sep 2022 14:54:20 +0200 Subject: [PATCH 09/14] Expose backup in Messenger interface --- Sources/XXMessengerClient/Messenger/Messenger.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sources/XXMessengerClient/Messenger/Messenger.swift b/Sources/XXMessengerClient/Messenger/Messenger.swift index dab59a2f..ce598c54 100644 --- a/Sources/XXMessengerClient/Messenger/Messenger.swift +++ b/Sources/XXMessengerClient/Messenger/Messenger.swift @@ -4,6 +4,7 @@ public struct Messenger { public var cMix: Stored<CMix?> public var e2e: Stored<E2E?> public var ud: Stored<UserDiscovery?> + public var backup: Stored<Backup?> public var isCreated: MessengerIsCreated public var create: MessengerCreate public var restoreBackup: MessengerRestoreBackup @@ -43,6 +44,7 @@ extension Messenger { cMix: env.cMix, e2e: env.e2e, ud: env.ud, + backup: env.backup, isCreated: .live(env), create: .live(env), restoreBackup: .live(env), @@ -83,6 +85,7 @@ extension Messenger { cMix: .unimplemented(), e2e: .unimplemented(), ud: .unimplemented(), + backup: .unimplemented(), isCreated: .unimplemented, create: .unimplemented, restoreBackup: .unimplemented, -- GitLab From 791ac12554c9dab9711e64dc6f7e2bb648391e6f Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 28 Sep 2022 15:00:29 +0200 Subject: [PATCH 10/14] Update docs --- Docs/XXMessengerClient.md | 52 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/Docs/XXMessengerClient.md b/Docs/XXMessengerClient.md index 05afa4aa..46ded0e7 100644 --- a/Docs/XXMessengerClient.md +++ b/Docs/XXMessengerClient.md @@ -95,4 +95,54 @@ let e2e = messenger.e2e() // get UserDicovery: let ud = messenger.ud() -``` \ No newline at end of file + +// get Backup: +let backup = messenger.backup() +``` + +## 💾 Backup + +Make backup: + +```swift +// start receiving backup data before starting or resuming backup: +let cancellable = messenger.registerBackupCallback(.init { data in + // handle backup data, save on disk, upload to cloud, etc. +}) + +// check if backup is already running: +if messenger.isBackupRunning() == false { + do { + // try to resume previous backup: + try messenger.resumeBackup() + } catch { + // try to start a new backup: + try messenger.startBackup(password: "backup-passphrase") + } +} + +// add backup params to the backup: +let params: BackupParams = ... +try messenger.backupParams(params) + +// stop the backup: +try messenger.stopBackup() + +// optionally stop receiving backup data +cancellable.cancel() +``` + +The registered backup callback can be reused later when a new backup is started. There is no need to cancel it and register a new callback in such a case. + +Restore from backup: + +```swift +let result = try messenger.restoreBackup( + backupData: ..., + backupPassphrase: "backup-passphrase" +) + +// handle restore result +``` + +If no error was thrown during restoration, the `Messenger` is already loaded, started, connected, and logged in. \ No newline at end of file -- GitLab From 30ad9d7315c0592c2ee16de5e14d8a72c0c39bd1 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 28 Sep 2022 15:07:06 +0200 Subject: [PATCH 11/14] Update docs --- Docs/XXMessengerClient.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/XXMessengerClient.md b/Docs/XXMessengerClient.md index 46ded0e7..17699f7a 100644 --- a/Docs/XXMessengerClient.md +++ b/Docs/XXMessengerClient.md @@ -142,7 +142,7 @@ let result = try messenger.restoreBackup( backupPassphrase: "backup-passphrase" ) -// handle restore result +// handle restoration result ``` If no error was thrown during restoration, the `Messenger` is already loaded, started, connected, and logged in. \ No newline at end of file -- GitLab From 6077fe469bb287efaaf8871e38b9655e08773220 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 28 Sep 2022 15:58:40 +0200 Subject: [PATCH 12/14] Fix typo --- .../{MessengerStartBakcup.swift => MessengerStartBackup.swift} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Sources/XXMessengerClient/Messenger/Functions/{MessengerStartBakcup.swift => MessengerStartBackup.swift} (100%) diff --git a/Sources/XXMessengerClient/Messenger/Functions/MessengerStartBakcup.swift b/Sources/XXMessengerClient/Messenger/Functions/MessengerStartBackup.swift similarity index 100% rename from Sources/XXMessengerClient/Messenger/Functions/MessengerStartBakcup.swift rename to Sources/XXMessengerClient/Messenger/Functions/MessengerStartBackup.swift -- GitLab From e985b2e16eba606284d39b1609d98ca71352ed1a Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 28 Sep 2022 16:58:16 +0200 Subject: [PATCH 13/14] Update MessengerStartBackup function - When first data arrive, ignore it and add params to the backup - When following data arrive (that included params), handle it --- Docs/XXMessengerClient.md | 10 ++++- .../Functions/MessengerStartBackup.swift | 27 ++++++++++--- .../Functions/MessengerStartBackupTests.swift | 39 ++++++++++++++----- .../TestHelpers/StringData.swift | 14 +++++++ ...{Message+stubs.swift => TestDoubles.swift} | 9 +++++ 5 files changed, 82 insertions(+), 17 deletions(-) create mode 100644 Tests/XXMessengerClientTests/TestHelpers/StringData.swift rename Tests/XXMessengerClientTests/TestHelpers/{Message+stubs.swift => TestDoubles.swift} (74%) diff --git a/Docs/XXMessengerClient.md b/Docs/XXMessengerClient.md index 17699f7a..6b599f7f 100644 --- a/Docs/XXMessengerClient.md +++ b/Docs/XXMessengerClient.md @@ -117,11 +117,15 @@ if messenger.isBackupRunning() == false { try messenger.resumeBackup() } catch { // try to start a new backup: - try messenger.startBackup(password: "backup-passphrase") + let params: BackupParams = ... + try messenger.startBackup( + password: "backup-passphrase", + params: params + ) } } -// add backup params to the backup: +// update params in the backup: let params: BackupParams = ... try messenger.backupParams(params) @@ -132,6 +136,8 @@ try messenger.stopBackup() cancellable.cancel() ``` +When starting a new backup you must provide `BackupParams` to prevent creating backups that does not contain it. + The registered backup callback can be reused later when a new backup is started. There is no need to cancel it and register a new callback in such a case. Restore from backup: diff --git a/Sources/XXMessengerClient/Messenger/Functions/MessengerStartBackup.swift b/Sources/XXMessengerClient/Messenger/Functions/MessengerStartBackup.swift index 366d87fc..254bc6b9 100644 --- a/Sources/XXMessengerClient/Messenger/Functions/MessengerStartBackup.swift +++ b/Sources/XXMessengerClient/Messenger/Functions/MessengerStartBackup.swift @@ -8,16 +8,19 @@ public struct MessengerStartBackup { case notLoggedIn } - public var run: (String) throws -> Void + public var run: (String, BackupParams) throws -> Void - public func callAsFunction(password: String) throws { - try run(password) + public func callAsFunction( + password: String, + params: BackupParams + ) throws { + try run(password, params) } } extension MessengerStartBackup { public static func live(_ env: MessengerEnvironment) -> MessengerStartBackup { - MessengerStartBackup { password in + MessengerStartBackup { password, params in guard env.backup()?.isRunning() != true else { throw Error.isRunning } @@ -27,11 +30,25 @@ extension MessengerStartBackup { guard let ud = env.ud() else { throw Error.notLoggedIn } + let paramsData = try params.encode() + let paramsString = String(data: paramsData, encoding: .utf8)! + var didAddParams = false + func addParams() { + guard let backup = env.backup() else { return } + backup.addJSON(paramsString) + didAddParams = true + } let backup = try env.initializeBackup( e2eId: e2e.getId(), udId: ud.getId(), password: password, - callback: env.backupCallbacks.registered() + callback: .init { data in + if !didAddParams { + addParams() + } else { + env.backupCallbacks.registered().handle(data) + } + } ) env.backup.set(backup) } diff --git a/Tests/XXMessengerClientTests/Messenger/Functions/MessengerStartBackupTests.swift b/Tests/XXMessengerClientTests/Messenger/Functions/MessengerStartBackupTests.swift index c1e703a6..b92bd1ee 100644 --- a/Tests/XXMessengerClientTests/Messenger/Functions/MessengerStartBackupTests.swift +++ b/Tests/XXMessengerClientTests/Messenger/Functions/MessengerStartBackupTests.swift @@ -14,14 +14,16 @@ final class MessengerStartBackupTests: XCTestCase { var backupCallbacks: [UpdateBackupFunc] = [] var didHandleCallback: [Data] = [] var didSetBackup: [Backup?] = [] + var didAddJSON: [String] = [] let password = "test-password" let e2eId = 123 let udId = 321 - let data = "test-data".data(using: .utf8)! + let dataWithoutParams = "backup-without-params".data(using: .utf8)! + let dataWithParams = "backup-with-params".data(using: .utf8)! var env: MessengerEnvironment = .unimplemented - env.backup.get = { nil } + env.backup.get = { didSetBackup.last as? Backup } env.backup.set = { didSetBackup.append($0) } env.e2e.get = { var e2e: E2E = .unimplemented @@ -39,20 +41,37 @@ final class MessengerStartBackupTests: XCTestCase { env.initializeBackup.run = { e2eId, udId, password, callback in didInitializeBackup.append(.init(e2eId: e2eId, udId: udId, password: password)) backupCallbacks.append(callback) - return .unimplemented + var backup: Backup = .unimplemented + backup.addJSON.run = { string in + didAddJSON.append(string) + } + return backup } let start: MessengerStartBackup = .live(env) - try start(password: password) + try start(password: password, params: .stub) XCTAssertNoDifference(didInitializeBackup, [ .init(e2eId: e2eId, udId: udId, password: password) ]) XCTAssertNoDifference(didSetBackup.map { $0 != nil }, [true]) - backupCallbacks.forEach { $0.handle(data) } + backupCallbacks.forEach { $0.handle(dataWithoutParams) } + + XCTAssertNoDifference( + didHandleCallback.map(StringData.init), + [].map(StringData.init) + ) + XCTAssertNoDifference(didAddJSON, [ + String(data: try BackupParams.stub.encode(), encoding: .utf8)! + ]) + + backupCallbacks.forEach { $0.handle(dataWithParams) } - XCTAssertNoDifference(didHandleCallback, [data]) + XCTAssertNoDifference( + didHandleCallback.map(StringData.init), + [dataWithParams].map(StringData.init) + ) } func testStartWhenRunning() { @@ -64,7 +83,7 @@ final class MessengerStartBackupTests: XCTestCase { } let start: MessengerStartBackup = .live(env) - XCTAssertThrowsError(try start(password: "")) { error in + XCTAssertThrowsError(try start(password: "", params: .stub)) { error in XCTAssertNoDifference( error as NSError, MessengerStartBackup.Error.isRunning as NSError @@ -78,7 +97,7 @@ final class MessengerStartBackupTests: XCTestCase { env.e2e.get = { nil } let start: MessengerStartBackup = .live(env) - XCTAssertThrowsError(try start(password: "")) { error in + XCTAssertThrowsError(try start(password: "", params: .stub)) { error in XCTAssertNoDifference( error as NSError, MessengerStartBackup.Error.notConnected as NSError @@ -93,7 +112,7 @@ final class MessengerStartBackupTests: XCTestCase { env.ud.get = { nil } let start: MessengerStartBackup = .live(env) - XCTAssertThrowsError(try start(password: "")) { error in + XCTAssertThrowsError(try start(password: "", params: .stub)) { error in XCTAssertNoDifference( error as NSError, MessengerStartBackup.Error.notLoggedIn as NSError @@ -121,7 +140,7 @@ final class MessengerStartBackupTests: XCTestCase { env.initializeBackup.run = { _, _, _, _ in throw failure } let start: MessengerStartBackup = .live(env) - XCTAssertThrowsError(try start(password: "abcd")) { error in + XCTAssertThrowsError(try start(password: "", params: .stub)) { error in XCTAssertNoDifference(error as NSError, failure as NSError) } } diff --git a/Tests/XXMessengerClientTests/TestHelpers/StringData.swift b/Tests/XXMessengerClientTests/TestHelpers/StringData.swift new file mode 100644 index 00000000..6987a4ea --- /dev/null +++ b/Tests/XXMessengerClientTests/TestHelpers/StringData.swift @@ -0,0 +1,14 @@ +import CustomDump +import Foundation + +struct StringData: Equatable, CustomDumpStringConvertible { + var data: Data + + var customDumpDescription: String { + if let string = String(data: data, encoding: .utf8) { + return #"Data(string: "\#(string)", encoding: .utf8)"# + } else { + return data.customDumpDescription + } + } +} diff --git a/Tests/XXMessengerClientTests/TestHelpers/Message+stubs.swift b/Tests/XXMessengerClientTests/TestHelpers/TestDoubles.swift similarity index 74% rename from Tests/XXMessengerClientTests/TestHelpers/Message+stubs.swift rename to Tests/XXMessengerClientTests/TestHelpers/TestDoubles.swift index e10bea4a..4d57e293 100644 --- a/Tests/XXMessengerClientTests/TestHelpers/Message+stubs.swift +++ b/Tests/XXMessengerClientTests/TestHelpers/TestDoubles.swift @@ -1,4 +1,5 @@ import XXClient +import XXMessengerClient extension Message { static func stub(_ stubId: Int) -> Message { @@ -16,3 +17,11 @@ extension Message { ) } } + +extension BackupParams { + static let stub = BackupParams( + username: "stub-username", + email: "stub-email", + phone: "stub-phone" + ) +} -- GitLab From 2a38d681b9e168c930ab0acd3bed11db5db294e9 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 28 Sep 2022 17:06:13 +0200 Subject: [PATCH 14/14] Update docs --- Docs/XXMessengerClient.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Docs/XXMessengerClient.md b/Docs/XXMessengerClient.md index 6b599f7f..971aefd9 100644 --- a/Docs/XXMessengerClient.md +++ b/Docs/XXMessengerClient.md @@ -4,7 +4,7 @@ ## â–¶ï¸ Instantiate messenger -Example: +### Example ```swift // setup environment: @@ -24,7 +24,7 @@ let messenger: Messenger = .live(environment) ## 🚀 Start messenger -Example: +### Example ```swift // allow cancellation of callbacks: @@ -84,7 +84,7 @@ func start(messenger: Messenger) throws { ## 🛠Use client components directly -Example: +### Example ```swift // get cMix: @@ -102,7 +102,7 @@ let backup = messenger.backup() ## 💾 Backup -Make backup: +### Make backup ```swift // start receiving backup data before starting or resuming backup: @@ -140,7 +140,7 @@ When starting a new backup you must provide `BackupParams` to prevent creating b The registered backup callback can be reused later when a new backup is started. There is no need to cancel it and register a new callback in such a case. -Restore from backup: +### Restore from backup ```swift let result = try messenger.restoreBackup( -- GitLab