Skip to content
Snippets Groups Projects
Commit dfb51c9f authored by Dariusz Rybicki's avatar Dariusz Rybicki
Browse files

Add MessengerSendMessage function

parent 82c5b95f
No related branches found
No related tags found
2 merge requests!102Release 1.0.0,!85Messenger - send & receive messages
import Foundation
import XCTestDynamicOverlay
import XXClient
public struct MessengerSendMessage {
public struct DeliveryReport: Equatable {
public enum Result: Equatable {
case delivered
case notDelivered(timedOut: Bool)
case failure(NSError)
}
public init(
report: E2ESendReport,
result: Result
) {
self.report = report
self.result = result
}
public var report: E2ESendReport
public var result: Result
}
public typealias DeliveryCallback = (DeliveryReport) -> Void
public enum Error: Swift.Error, Equatable {
case notLoaded
case notConnected
}
public var run: (Data, Data, DeliveryCallback?) throws -> E2ESendReport
public func callAsFunction(
recipientId: Data,
payload: Data,
deliveryCallback: DeliveryCallback?
) throws -> E2ESendReport {
try run(recipientId, payload, deliveryCallback)
}
}
extension MessengerSendMessage {
public static func live(_ env: MessengerEnvironment) -> MessengerSendMessage {
MessengerSendMessage { recipientId, payload, deliveryCallback in
guard let cMix = env.cMix() else {
throw Error.notLoaded
}
guard let e2e = env.e2e() else {
throw Error.notConnected
}
let report = try e2e.send(
messageType: 2,
recipientId: recipientId,
payload: payload,
e2eParams: env.getE2EParams()
)
if let deliveryCallback = deliveryCallback {
do {
try cMix.waitForRoundResult(
roundList: try report.encode(),
timeoutMS: 30_000,
callback: .init { result in
switch result {
case .delivered(_):
deliveryCallback(.init(report: report, result: .delivered))
case .notDelivered(let timedOut):
deliveryCallback(.init(report: report, result: .notDelivered(timedOut: timedOut)))
}
}
)
} catch {
deliveryCallback(.init(report: report, result: .failure(error as NSError)))
}
}
return report
}
}
}
extension MessengerSendMessage {
public static let unimplemented = MessengerSendMessage(
run: XCTUnimplemented("\(Self.self)")
)
}
......@@ -24,6 +24,7 @@ public struct Messenger {
public var searchUsers: MessengerSearchUsers
public var registerForNotifications: MessengerRegisterForNotifications
public var verifyContact: MessengerVerifyContact
public var sendMessage: MessengerSendMessage
}
extension Messenger {
......@@ -51,7 +52,8 @@ extension Messenger {
destroy: .live(env),
searchUsers: .live(env),
registerForNotifications: .live(env),
verifyContact: .live(env)
verifyContact: .live(env),
sendMessage: .live(env)
)
}
}
......@@ -80,6 +82,7 @@ extension Messenger {
destroy: .unimplemented,
searchUsers: .unimplemented,
registerForNotifications: .unimplemented,
verifyContact: .unimplemented
verifyContact: .unimplemented,
sendMessage: .unimplemented
)
}
import CustomDump
import XCTest
import XXClient
@testable import XXMessengerClient
final class MessengerSendMessageTests: XCTestCase {
func testSend() throws {
struct E2ESendParams: Equatable {
var messageType: Int
var recipientId: Data
var payload: Data
var e2eParams: Data
}
var e2eDidSendWithParams: [E2ESendParams] = []
let e2eSendReport = E2ESendReport(
rounds: [1, 2, 3],
roundURL: "round-url",
messageId: "message-id".data(using: .utf8)!,
timestamp: 123,
keyResidue: "key-residue".data(using: .utf8)!
)
var env: MessengerEnvironment = .unimplemented
env.getE2EParams.run = { "e2e-params".data(using: .utf8)! }
env.cMix.get = { .unimplemented }
env.e2e.get = {
var e2e: E2E = .unimplemented
e2e.send.run = { messageType, recipientId, payload, e2eParams in
e2eDidSendWithParams.append(.init(
messageType: messageType,
recipientId: recipientId,
payload: payload,
e2eParams: e2eParams
))
return e2eSendReport
}
return e2e
}
let send: MessengerSendMessage = .live(env)
let report = try send(
recipientId: "recipient-id".data(using: .utf8)!,
payload: "payload".data(using: .utf8)!,
deliveryCallback: nil
)
XCTAssertNoDifference(e2eDidSendWithParams, [.init(
messageType: 2,
recipientId: "recipient-id".data(using: .utf8)!,
payload: "payload".data(using: .utf8)!,
e2eParams: "e2e-params".data(using: .utf8)!
)])
XCTAssertNoDifference(report, e2eSendReport)
}
func testSendWithDeliveryCallback() throws {
struct WaitForRoundResultsParams: Equatable {
var roundList: Data
var timeoutMS: Int
}
var didWaitForRoundResultsWithParams: [WaitForRoundResultsParams] = []
var didWaitForRoundResultsWithCallback: [MessageDeliveryCallback] = []
var didReceiveDeliveryReport: [MessengerSendMessage.DeliveryReport] = []
let e2eSendReport = E2ESendReport(
rounds: [1, 2, 3],
roundURL: "round-url",
messageId: "message-id".data(using: .utf8)!,
timestamp: 123,
keyResidue: "key-residue".data(using: .utf8)!
)
var env: MessengerEnvironment = .unimplemented
env.getE2EParams.run = { "e2e-params".data(using: .utf8)! }
env.cMix.get = {
var cMix: CMix = .unimplemented
cMix.waitForRoundResult.run = { roundList, timeoutMS, callback in
didWaitForRoundResultsWithParams.append(.init(roundList: roundList, timeoutMS: timeoutMS))
didWaitForRoundResultsWithCallback.append(callback)
}
return cMix
}
env.e2e.get = {
var e2e: E2E = .unimplemented
e2e.send.run = { _, _, _, _ in e2eSendReport }
return e2e
}
let send: MessengerSendMessage = .live(env)
let report = try send(
recipientId: "recipient-id".data(using: .utf8)!,
payload: "payload".data(using: .utf8)!,
deliveryCallback: .init { deliveryReport in
didReceiveDeliveryReport.append(deliveryReport)
}
)
XCTAssertNoDifference(report, e2eSendReport)
XCTAssertNoDifference(didWaitForRoundResultsWithParams, [
.init(roundList: try! e2eSendReport.encode(), timeoutMS: 30_000),
])
didWaitForRoundResultsWithCallback.first?.handle(.delivered(roundResults: [1, 2, 3]))
XCTAssertNoDifference(didReceiveDeliveryReport, [
.init(report: report, result: .delivered)
])
didReceiveDeliveryReport.removeAll()
didWaitForRoundResultsWithCallback.first?.handle(.notDelivered(timedOut: false))
XCTAssertNoDifference(didReceiveDeliveryReport, [
.init(report: report, result: .notDelivered(timedOut: false))
])
didReceiveDeliveryReport.removeAll()
didWaitForRoundResultsWithCallback.first?.handle(.notDelivered(timedOut: true))
XCTAssertNoDifference(didReceiveDeliveryReport, [
.init(report: report, result: .notDelivered(timedOut: true))
])
}
func testSendWhenNotLoaded() {
var env: MessengerEnvironment = .unimplemented
env.cMix.get = { nil }
let send: MessengerSendMessage = .live(env)
XCTAssertThrowsError(
try send(
recipientId: Data(),
payload: Data(),
deliveryCallback: nil
)
) { error in
XCTAssertNoDifference(
error as? MessengerSendMessage.Error,
.notLoaded
)
}
}
func testSendWhenNotConnected() {
var env: MessengerEnvironment = .unimplemented
env.cMix.get = { .unimplemented }
env.e2e.get = { nil }
let send: MessengerSendMessage = .live(env)
XCTAssertThrowsError(
try send(
recipientId: Data(),
payload: Data(),
deliveryCallback: nil
)
) { error in
XCTAssertNoDifference(
error as? MessengerSendMessage.Error,
.notConnected
)
}
}
func testSendFailure() {
struct Failure: Error, Equatable {}
let error = Failure()
var env: MessengerEnvironment = .unimplemented
env.getE2EParams.run = { "e2e-params".data(using: .utf8)! }
env.cMix.get = { .unimplemented }
env.e2e.get = {
var e2e: E2E = .unimplemented
e2e.send.run = { _, _, _, _ in throw error }
return e2e
}
let send: MessengerSendMessage = .live(env)
XCTAssertThrowsError(
try send(
recipientId: "recipient-id".data(using: .utf8)!,
payload: "payload".data(using: .utf8)!,
deliveryCallback: nil
)
) { err in
XCTAssertNoDifference(err as? Failure, error)
}
}
func testSendDeliveryFailure() throws {
let e2eSendReport = E2ESendReport(
rounds: [1, 2, 3],
roundURL: "round-url",
messageId: "message-id".data(using: .utf8)!,
timestamp: 123,
keyResidue: "key-residue".data(using: .utf8)!
)
struct Failure: Error {}
let error = Failure()
var didReceiveDeliveryReport: [MessengerSendMessage.DeliveryReport] = []
var env: MessengerEnvironment = .unimplemented
env.getE2EParams.run = { "e2e-params".data(using: .utf8)! }
env.cMix.get = {
var cMix: CMix = .unimplemented
cMix.waitForRoundResult.run = { _, _, _ in throw error }
return cMix
}
env.e2e.get = {
var e2e: E2E = .unimplemented
e2e.send.run = { _, _, _, _ in e2eSendReport }
return e2e
}
let send: MessengerSendMessage = .live(env)
let report = try send(
recipientId: "recipient-id".data(using: .utf8)!,
payload: "payload".data(using: .utf8)!,
deliveryCallback: .init { deliveryReport in
didReceiveDeliveryReport.append(deliveryReport)
}
)
XCTAssertNoDifference(report, e2eSendReport)
XCTAssertNoDifference(didReceiveDeliveryReport, [
.init(report: report, result: .failure(error as NSError))
])
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment