From 72fdc4358ce5cb1892532e2a0bd5ecec3a2e173b Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Fri, 30 Sep 2022 11:08:07 +0200 Subject: [PATCH] Implement lookup --- .../AppFeature/AppEnvironment+Live.swift | 7 ++- .../ContactLookupFeature.swift | 53 +++++++++++++++---- .../ContactLookupView.swift | 3 -- .../ContactLookupFeatureTests.swift | 48 +++++++++++++---- 4 files changed, 87 insertions(+), 24 deletions(-) diff --git a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift index 34d9f806..cd5d752e 100644 --- a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift +++ b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift @@ -4,6 +4,7 @@ import ChatFeature import CheckContactAuthFeature import ConfirmRequestFeature import ContactFeature +import ContactLookupFeature import ContactsFeature import Foundation import HomeFeature @@ -38,7 +39,11 @@ extension AppEnvironment { mainQueue: mainQueue, bgQueue: bgQueue, lookup: { - ContactLookupEnvironment() + ContactLookupEnvironment( + messenger: messenger, + mainQueue: mainQueue, + bgQueue: bgQueue + ) }, sendRequest: { SendRequestEnvironment( diff --git a/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupFeature.swift b/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupFeature.swift index 7fd2fc8e..82a775dd 100644 --- a/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupFeature.swift +++ b/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupFeature.swift @@ -1,46 +1,81 @@ import ComposableArchitecture import Foundation import XCTestDynamicOverlay +import XXClient +import XXMessengerClient public struct ContactLookupState: Equatable { public init( id: Data, - isLookingUp: Bool = false + isLookingUp: Bool = false, + failure: String? = nil ) { self.id = id self.isLookingUp = isLookingUp + self.failure = failure } public var id: Data public var isLookingUp: Bool + public var failure: String? } public enum ContactLookupAction: Equatable { - case task - case cancelTask case lookupTapped + case didLookup(XXClient.Contact) + case didFail(NSError) } public struct ContactLookupEnvironment { - public init() {} + public init( + messenger: Messenger, + mainQueue: AnySchedulerOf<DispatchQueue>, + bgQueue: AnySchedulerOf<DispatchQueue> + ) { + self.messenger = messenger + self.mainQueue = mainQueue + self.bgQueue = bgQueue + } + + public var messenger: Messenger + public var mainQueue: AnySchedulerOf<DispatchQueue> + public var bgQueue: AnySchedulerOf<DispatchQueue> } #if DEBUG extension ContactLookupEnvironment { - public static let unimplemented = ContactLookupEnvironment() + public static let unimplemented = ContactLookupEnvironment( + messenger: .unimplemented, + mainQueue: .unimplemented, + bgQueue: .unimplemented + ) } #endif public let contactLookupReducer = Reducer<ContactLookupState, ContactLookupAction, ContactLookupEnvironment> { state, action, env in switch action { - case .task: - return .none + case .lookupTapped: + state.isLookingUp = true + return Effect.result { [state] in + do { + let contact = try env.messenger.lookupContact(id: state.id) + return .success(.didLookup(contact)) + } catch { + return .success(.didFail(error as NSError)) + } + } + .subscribe(on: env.bgQueue) + .receive(on: env.mainQueue) + .eraseToEffect() - case .cancelTask: + case .didLookup(_): + state.isLookingUp = false return .none - case .lookupTapped: + case .didFail(let error): + state.failure = error.localizedDescription + state.isLookingUp = false return .none } } diff --git a/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupView.swift b/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupView.swift index 1d1e0208..a8bcd339 100644 --- a/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupView.swift +++ b/Examples/xx-messenger/Sources/ContactLookupFeature/ContactLookupView.swift @@ -45,9 +45,6 @@ public struct ContactLookupView: View { } } .navigationTitle("Lookup") - .task { - await viewStore.send(.task).finish() - } } } } diff --git a/Examples/xx-messenger/Tests/ContactLookupFeatureTests/ContactLookupFeatureTests.swift b/Examples/xx-messenger/Tests/ContactLookupFeatureTests/ContactLookupFeatureTests.swift index 70847105..34ecabc3 100644 --- a/Examples/xx-messenger/Tests/ContactLookupFeatureTests/ContactLookupFeatureTests.swift +++ b/Examples/xx-messenger/Tests/ContactLookupFeatureTests/ContactLookupFeatureTests.swift @@ -1,31 +1,57 @@ import ComposableArchitecture import XCTest +import XXClient @testable import ContactLookupFeature final class ContactLookupFeatureTests: XCTestCase { - func testTask() { + func testLookup() { + let id: Data = "1234".data(using: .utf8)! + var didLookupId: [Data] = [] + let lookedUpContact = Contact.unimplemented("123data".data(using: .utf8)!) + let store = TestStore( - initialState: ContactLookupState( - id: "1234".data(using: .utf8)! - ), + initialState: ContactLookupState(id: id), reducer: contactLookupReducer, environment: .unimplemented ) + store.environment.mainQueue = .immediate + store.environment.bgQueue = .immediate + store.environment.messenger.lookupContact.run = { id in + didLookupId.append(id) + return lookedUpContact + } + + store.send(.lookupTapped) { + $0.isLookingUp = true + } - store.send(.task) + XCTAssertEqual(didLookupId, [id]) - store.send(.cancelTask) + store.receive(.didLookup(lookedUpContact)) { + $0.isLookingUp = false + } } - func testLookup() { + func testLookupFailure() { + let id: Data = "1234".data(using: .utf8)! + let failure = NSError(domain: "test", code: 0) + let store = TestStore( - initialState: ContactLookupState( - id: "1234".data(using: .utf8)! - ), + initialState: ContactLookupState(id: id), reducer: contactLookupReducer, environment: .unimplemented ) + store.environment.mainQueue = .immediate + store.environment.bgQueue = .immediate + store.environment.messenger.lookupContact.run = { _ in throw failure } + + store.send(.lookupTapped) { + $0.isLookingUp = true + } - store.send(.lookupTapped) + store.receive(.didFail(failure)) { + $0.failure = failure.localizedDescription + $0.isLookingUp = false + } } } -- GitLab