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] 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