diff --git a/Sources/XXMessengerClient/Utils/ReceiveFileCallbacksRegistry.swift b/Sources/XXMessengerClient/Utils/ReceiveFileCallbacksRegistry.swift new file mode 100644 index 0000000000000000000000000000000000000000..e82670ca748e4d28469d3b5c66b5eae0f77e4903 --- /dev/null +++ b/Sources/XXMessengerClient/Utils/ReceiveFileCallbacksRegistry.swift @@ -0,0 +1,36 @@ +import Foundation +import XCTestDynamicOverlay +import XXClient + +public struct ReceiveFileCallbacksRegistry { + public var register: (ReceiveFileCallback) -> Cancellable + public var registered: () -> ReceiveFileCallback +} + +extension ReceiveFileCallbacksRegistry { + public static func live() -> ReceiveFileCallbacksRegistry { + class Registry { + var callbacks: [UUID: ReceiveFileCallback] = [:] + } + let registry = Registry() + return ReceiveFileCallbacksRegistry( + register: { callback in + let id = UUID() + registry.callbacks[id] = callback + return Cancellable { registry.callbacks[id] = nil } + }, + registered: { + ReceiveFileCallback { result in + registry.callbacks.values.forEach { $0.handle(result) } + } + } + ) + } +} + +extension ReceiveFileCallbacksRegistry { + public static let unimplemented = ReceiveFileCallbacksRegistry( + register: XCTUnimplemented("\(Self.self).register", placeholder: Cancellable {}), + registered: XCTUnimplemented("\(Self.self).registered", placeholder: .unimplemented) + ) +} diff --git a/Tests/XXMessengerClientTests/Utils/ReceiveFileCallbacksRegistryTests.swift b/Tests/XXMessengerClientTests/Utils/ReceiveFileCallbacksRegistryTests.swift new file mode 100644 index 0000000000000000000000000000000000000000..d40e6d7923c1e8a69cda09d1d8bcaccd93c18d2b --- /dev/null +++ b/Tests/XXMessengerClientTests/Utils/ReceiveFileCallbacksRegistryTests.swift @@ -0,0 +1,57 @@ +import CustomDump +import XCTest +import XXClient +@testable import XXMessengerClient + +final class ReceiveFileCallbacksRegistryTests: XCTestCase { + func testRegistry() { + var firstCallbackDidHandle: [Result<ReceivedFile, NSError>] = [] + var secondCallbackDidHandle: [Result<ReceivedFile, NSError>] = [] + + let firstCallback = ReceiveFileCallback { result in + firstCallbackDidHandle.append(result) + } + let secondCallback = ReceiveFileCallback { result in + secondCallbackDidHandle.append(result) + } + let callbackRegistry: ReceiveFileCallbacksRegistry = .live() + let registeredCallbacks = callbackRegistry.registered() + let firstCallbackCancellable = callbackRegistry.register(firstCallback) + let secondCallbackCancellable = callbackRegistry.register(secondCallback) + + let firstResult = Result<ReceivedFile, NSError>.success(.stub(1)) + registeredCallbacks.handle(firstResult) + + XCTAssertNoDifference(firstCallbackDidHandle, [firstResult]) + XCTAssertNoDifference(secondCallbackDidHandle, [firstResult]) + + firstCallbackCancellable.cancel() + let secondError = NSError(domain: "test", code: 321) + let secondResult = Result<ReceivedFile, NSError>.failure(secondError) + registeredCallbacks.handle(secondResult) + + XCTAssertNoDifference(firstCallbackDidHandle, [firstResult]) + XCTAssertNoDifference(secondCallbackDidHandle, [firstResult, secondResult]) + + secondCallbackCancellable.cancel() + + let thirdData = Result<ReceivedFile, NSError>.success(.stub(2)) + registeredCallbacks.handle(thirdData) + + XCTAssertNoDifference(firstCallbackDidHandle, [firstResult]) + XCTAssertNoDifference(secondCallbackDidHandle, [firstResult, secondResult]) + } +} + +private extension ReceivedFile { + static func stub(_ id: Int) -> ReceivedFile { + ReceivedFile( + transferId: "transfer-id-\(id)".data(using: .utf8)!, + senderId: "sender-id-\(id)".data(using: .utf8)!, + preview: "preview-\(id)".data(using: .utf8)!, + name: "name-\(id)", + type: "type-\(id)", + size: id + ) + } +}