From bcf22fb36b24ec9bbe657af5d9c41833e737ec03 Mon Sep 17 00:00:00 2001
From: Dariusz Rybicki <dariusz@elixxir.io>
Date: Fri, 16 Sep 2022 18:21:14 +0200
Subject: [PATCH] Add MessengerLookupContact function

---
 .../Functions/MessengerLookupContact.swift    |  51 ++++++++
 .../Messenger/Messenger.swift                 |   3 +
 .../MessengerLookupContactTests.swift         | 117 ++++++++++++++++++
 3 files changed, 171 insertions(+)
 create mode 100644 Sources/XXMessengerClient/Messenger/Functions/MessengerLookupContact.swift
 create mode 100644 Tests/XXMessengerClientTests/Messenger/Functions/MessengerLookupContactTests.swift

diff --git a/Sources/XXMessengerClient/Messenger/Functions/MessengerLookupContact.swift b/Sources/XXMessengerClient/Messenger/Functions/MessengerLookupContact.swift
new file mode 100644
index 00000000..de77da41
--- /dev/null
+++ b/Sources/XXMessengerClient/Messenger/Functions/MessengerLookupContact.swift
@@ -0,0 +1,51 @@
+import Foundation
+import XCTestDynamicOverlay
+import XXClient
+
+public struct MessengerLookupContact {
+  public enum Error: Swift.Error, Equatable {
+    case notConnected
+    case notLoggedIn
+  }
+
+  public var run: (Data) throws -> Contact
+
+  public func callAsFunction(id: Data) throws -> Contact {
+    try run(id)
+  }
+}
+
+extension MessengerLookupContact {
+  public static func live(_ env: MessengerEnvironment) -> MessengerLookupContact {
+    MessengerLookupContact { id in
+      guard let e2e = env.e2e() else {
+        throw Error.notConnected
+      }
+      guard let ud = env.ud() else {
+        throw Error.notLoggedIn
+      }
+      var result: Result<Contact, NSError>!
+      let semaphore = DispatchSemaphore(value: 0)
+      _ = try env.lookupUD(
+        params: LookupUD.Params(
+          e2eId: e2e.getId(),
+          udContact: try ud.getContact(),
+          lookupId: id,
+          singleRequestParamsJSON: env.getSingleUseParams()
+        ),
+        callback: UdLookupCallback { lookupResult in
+          result = lookupResult
+          semaphore.signal()
+        }
+      )
+      semaphore.wait()
+      return try result.get()
+    }
+  }
+}
+
+extension MessengerLookupContact {
+  public static let unimplemented = MessengerLookupContact(
+    run: XCTUnimplemented("\(Self.self)")
+  )
+}
diff --git a/Sources/XXMessengerClient/Messenger/Messenger.swift b/Sources/XXMessengerClient/Messenger/Messenger.swift
index 6a3c417b..7186b611 100644
--- a/Sources/XXMessengerClient/Messenger/Messenger.swift
+++ b/Sources/XXMessengerClient/Messenger/Messenger.swift
@@ -22,6 +22,7 @@ public struct Messenger {
   public var waitForNodes: MessengerWaitForNodes
   public var destroy: MessengerDestroy
   public var searchContacts: MessengerSearchContacts
+  public var lookupContact: MessengerLookupContact
   public var registerForNotifications: MessengerRegisterForNotifications
   public var verifyContact: MessengerVerifyContact
   public var sendMessage: MessengerSendMessage
@@ -51,6 +52,7 @@ extension Messenger {
       waitForNodes: .live(env),
       destroy: .live(env),
       searchContacts: .live(env),
+      lookupContact: .live(env),
       registerForNotifications: .live(env),
       verifyContact: .live(env),
       sendMessage: .live(env)
@@ -81,6 +83,7 @@ extension Messenger {
     waitForNodes: .unimplemented,
     destroy: .unimplemented,
     searchContacts: .unimplemented,
+    lookupContact: .unimplemented,
     registerForNotifications: .unimplemented,
     verifyContact: .unimplemented,
     sendMessage: .unimplemented
diff --git a/Tests/XXMessengerClientTests/Messenger/Functions/MessengerLookupContactTests.swift b/Tests/XXMessengerClientTests/Messenger/Functions/MessengerLookupContactTests.swift
new file mode 100644
index 00000000..3069e8c0
--- /dev/null
+++ b/Tests/XXMessengerClientTests/Messenger/Functions/MessengerLookupContactTests.swift
@@ -0,0 +1,117 @@
+import CustomDump
+import XCTest
+import XXClient
+@testable import XXMessengerClient
+
+final class MessengerLookupContactTests: XCTestCase {
+  func testLookup() throws {
+    let contactId = "contact-id".data(using: .utf8)!
+    let e2eId = 123
+    let udContact = Contact.unimplemented("ud-contact".data(using: .utf8)!)
+    let singleRequestParams = "single-request-params".data(using: .utf8)!
+    let contact = Contact.unimplemented("contact".data(using: .utf8)!)
+
+    var didLookupWithParams: [LookupUD.Params] = []
+
+    var env: MessengerEnvironment = .unimplemented
+    env.e2e.get = {
+      var e2e: E2E = .unimplemented
+      e2e.getId.run = { e2eId }
+      return e2e
+    }
+    env.ud.get = {
+      var ud: UserDiscovery = .unimplemented
+      ud.getContact.run = { udContact }
+      return ud
+    }
+    env.getSingleUseParams.run = { singleRequestParams }
+    env.lookupUD.run = { params, callback in
+      didLookupWithParams.append(params)
+      callback.handle(.success(contact))
+      return SingleUseSendReport(rounds: [], roundURL: "", ephId: 0, receptionId: Data())
+    }
+    let lookup: MessengerLookupContact = .live(env)
+
+    let result = try lookup(id: contactId)
+
+    XCTAssertNoDifference(didLookupWithParams, [.init(
+      e2eId: e2eId,
+      udContact: udContact,
+      lookupId: contactId,
+      singleRequestParamsJSON: singleRequestParams
+    )])
+    XCTAssertNoDifference(result, contact)
+  }
+
+  func testLookupWhenNotConnected() {
+    var env: MessengerEnvironment = .unimplemented
+    env.e2e.get = { nil }
+    let lookup: MessengerLookupContact = .live(env)
+
+    XCTAssertThrowsError(try lookup(id: Data())) { error in
+      XCTAssertEqual(error as? MessengerLookupContact.Error, .notConnected)
+    }
+  }
+
+  func testLookupWhenNotLoggedIn() {
+    var env: MessengerEnvironment = .unimplemented
+    env.e2e.get = { .unimplemented }
+    env.ud.get = { nil }
+    let lookup: MessengerLookupContact = .live(env)
+
+    XCTAssertThrowsError(try lookup(id: Data())) { error in
+      XCTAssertEqual(error as? MessengerLookupContact.Error, .notLoggedIn)
+    }
+  }
+
+  func testLookupFailure() {
+    struct Failure: Error, Equatable {}
+    let failure = Failure()
+
+    var env: MessengerEnvironment = .unimplemented
+    env.e2e.get = {
+      var e2e: E2E = .unimplemented
+      e2e.getId.run = { 0 }
+      return e2e
+    }
+    env.ud.get = {
+      var ud: UserDiscovery = .unimplemented
+      ud.getContact.run = { .unimplemented(Data()) }
+      return ud
+    }
+    env.getSingleUseParams.run = { Data() }
+    env.lookupUD.run = { _, _ in throw failure }
+    let lookup: MessengerLookupContact = .live(env)
+
+    XCTAssertThrowsError(try lookup(id: Data())) { error in
+      XCTAssertEqual(error as? Failure, failure)
+    }
+  }
+
+  func testLookupCallbackFailure() {
+    struct Failure: Error, Equatable {}
+    let failure = Failure()
+
+    var env: MessengerEnvironment = .unimplemented
+    env.e2e.get = {
+      var e2e: E2E = .unimplemented
+      e2e.getId.run = { 0 }
+      return e2e
+    }
+    env.ud.get = {
+      var ud: UserDiscovery = .unimplemented
+      ud.getContact.run = { .unimplemented(Data()) }
+      return ud
+    }
+    env.getSingleUseParams.run = { Data() }
+    env.lookupUD.run = { _, callback in
+      callback.handle(.failure(failure as NSError))
+      return SingleUseSendReport(rounds: [], roundURL: "", ephId: 0, receptionId: Data())
+    }
+    let lookup: MessengerLookupContact = .live(env)
+
+    XCTAssertThrowsError(try lookup(id: Data())) { error in
+      XCTAssertEqual(error as? Failure, failure)
+    }
+  }
+}
-- 
GitLab