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
This commit is part of merge request !85. Comments created here will be created in the context of that merge request.
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.
Please register or to comment