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