From 978e4ffd402010500967cc5ab202a584872a6884 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 14 Sep 2022 12:21:30 +0200 Subject: [PATCH] Implement MessageListenerHandler --- .../MessageListenerHandler.swift | 50 ++++++++ .../MessageListenerHandlerTests.swift | 110 ++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 Examples/xx-messenger/Sources/AppCore/MessageListenerHandler/MessageListenerHandler.swift create mode 100644 Examples/xx-messenger/Tests/AppCoreTests/MessageListenerHandler/MessageListenerHandlerTests.swift diff --git a/Examples/xx-messenger/Sources/AppCore/MessageListenerHandler/MessageListenerHandler.swift b/Examples/xx-messenger/Sources/AppCore/MessageListenerHandler/MessageListenerHandler.swift new file mode 100644 index 00000000..70fbace7 --- /dev/null +++ b/Examples/xx-messenger/Sources/AppCore/MessageListenerHandler/MessageListenerHandler.swift @@ -0,0 +1,50 @@ +import Foundation +import XCTestDynamicOverlay +import XXClient +import XXMessengerClient +import XXModels + +public struct MessageListenerHandler { + public typealias OnError = (Error) -> Void + + public var run: (@escaping OnError) -> Cancellable + + public func callAsFunction(onError: @escaping OnError) -> Cancellable { + run(onError) + } +} + +extension MessageListenerHandler { + public static func live( + messenger: Messenger, + db: DBManagerGetDB + ) -> MessageListenerHandler { + MessageListenerHandler { onError in + let listener = Listener { message in + do { + let payload = try MessagePayload.decode(message.payload) + try db().saveMessage(.init( + networkId: message.id, + senderId: message.sender, + recipientId: message.recipientId, + groupId: nil, + date: Date(timeIntervalSince1970: TimeInterval(message.timestamp) / 1_000_000_000), + status: .received, + isUnread: true, + text: payload.text, + roundURL: message.roundURL + )) + } catch { + onError(error) + } + } + return messenger.registerMessageListener(listener) + } + } +} + +extension MessageListenerHandler { + public static let unimplemented = MessageListenerHandler( + run: XCTUnimplemented("\(Self.self)", placeholder: Cancellable {}) + ) +} diff --git a/Examples/xx-messenger/Tests/AppCoreTests/MessageListenerHandler/MessageListenerHandlerTests.swift b/Examples/xx-messenger/Tests/AppCoreTests/MessageListenerHandler/MessageListenerHandlerTests.swift new file mode 100644 index 00000000..4038cb0d --- /dev/null +++ b/Examples/xx-messenger/Tests/AppCoreTests/MessageListenerHandler/MessageListenerHandlerTests.swift @@ -0,0 +1,110 @@ +import CustomDump +import XCTest +import XXClient +import XXMessengerClient +import XXModels +@testable import AppCore + +final class MessageListenerHandlerTests: XCTestCase { + func testHandleIncomingMessage() throws { + var didRegisterListener: [Listener] = [] + var didCancelListener = 0 + var didSaveMessage: [XXModels.Message] = [] + + var messenger: Messenger = .unimplemented + messenger.registerMessageListener.run = { listener in + didRegisterListener.append(listener) + return Cancellable { didCancelListener += 1 } + } + var db: DBManagerGetDB = .unimplemented + db.run = { + var db: Database = .failing + db.saveMessage.run = { message in + didSaveMessage.append(message) + return message + } + return db + } + let handler: MessageListenerHandler = .live( + messenger: messenger, + db: db + ) + + var cancellable: Cancellable? = handler(onError: { _ in XCTFail() }) + + XCTAssertNoDifference(didRegisterListener.count, 1) + + let payload = MessagePayload(text: "Hello") + let xxMessage = XXClient.Message( + messageType: 111, + id: "message-id".data(using: .utf8)!, + payload: try! payload.encode(), + sender: "sender-id".data(using: .utf8)!, + recipientId: "recipient-id".data(using: .utf8)!, + ephemeralId: 222, + timestamp: 1_653_580_439_357_351_000, + encrypted: true, + roundId: 333, + roundURL: "round-url" + ) + didRegisterListener.first?.handle(xxMessage) + + XCTAssertNoDifference(didSaveMessage, [ + .init( + networkId: xxMessage.id, + senderId: xxMessage.sender, + recipientId: xxMessage.recipientId, + groupId: nil, + date: Date(timeIntervalSince1970: TimeInterval(xxMessage.timestamp) / 1_000_000_000), + status: .received, + isUnread: true, + text: payload.text, + roundURL: xxMessage.roundURL + ) + ]) + + cancellable = nil + _ = cancellable + + XCTAssertNoDifference(didCancelListener, 1) + } + + func testDatabaseFailure() { + struct Failure: Error, Equatable {} + let error = Failure() + var registeredListeners: [Listener] = [] + var didReceiveError: [Error] = [] + + var messenger: Messenger = .unimplemented + messenger.registerMessageListener.run = { listener in + registeredListeners.append(listener) + return Cancellable {} + } + var db: DBManagerGetDB = .unimplemented + db.run = { throw error } + let handler: MessageListenerHandler = .live( + messenger: messenger, + db: db + ) + + _ = handler(onError: { error in didReceiveError.append(error) }) + + let payload = MessagePayload(text: "Hello") + let xxMessage = XXClient.Message( + messageType: 111, + id: "message-id".data(using: .utf8)!, + payload: try! payload.encode(), + sender: "sender-id".data(using: .utf8)!, + recipientId: "recipient-id".data(using: .utf8)!, + ephemeralId: 222, + timestamp: 1_653_580_439_357_351_000, + encrypted: true, + roundId: 333, + roundURL: "round-url" + ) + registeredListeners.first?.handle(xxMessage) + + XCTAssertNoDifference(didReceiveError.count, 1) + XCTAssertNoDifference(didReceiveError.first as? Failure, error) + } +} -- GitLab