From 15798ff9a952591d190a899230c8bb4a560e4058 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Wed, 7 Sep 2022 15:18:40 +0200 Subject: [PATCH] Fetch my facts in SendRequestFeature --- .../AppFeature/AppEnvironment+Live.swift | 7 +- .../SendRequestFeature.swift | 46 ++++++++++++- .../SendRequestFeatureTests.swift | 68 +++++++++++++++++++ 3 files changed, 118 insertions(+), 3 deletions(-) diff --git a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift index 9b298c38..298cb9f6 100644 --- a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift +++ b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift @@ -63,7 +63,12 @@ extension AppEnvironment { mainQueue: mainQueue, bgQueue: bgQueue, sendRequest: { - SendRequestEnvironment() + SendRequestEnvironment( + messenger: messenger, + db: dbManager.getDB, + mainQueue: mainQueue, + bgQueue: bgQueue + ) } ) } diff --git a/Examples/xx-messenger/Sources/SendRequestFeature/SendRequestFeature.swift b/Examples/xx-messenger/Sources/SendRequestFeature/SendRequestFeature.swift index cefd80d3..8740c744 100644 --- a/Examples/xx-messenger/Sources/SendRequestFeature/SendRequestFeature.swift +++ b/Examples/xx-messenger/Sources/SendRequestFeature/SendRequestFeature.swift @@ -1,6 +1,9 @@ +import AppCore import ComposableArchitecture +import Foundation import XCTestDynamicOverlay import XXClient +import XXMessengerClient import XXModels public struct SendRequestState: Equatable { @@ -35,22 +38,60 @@ public enum SendRequestAction: Equatable, BindableAction { case start case sendTapped case binding(BindingAction<SendRequestState>) + case myContactFetched(XXClient.Contact?) } public struct SendRequestEnvironment { - public init() {} + public init( + messenger: Messenger, + db: DBManagerGetDB, + mainQueue: AnySchedulerOf<DispatchQueue>, + bgQueue: AnySchedulerOf<DispatchQueue> + ) { + self.messenger = messenger + self.db = db + self.mainQueue = mainQueue + self.bgQueue = bgQueue + } + + public var messenger: Messenger + public var db: DBManagerGetDB + public var mainQueue: AnySchedulerOf<DispatchQueue> + public var bgQueue: AnySchedulerOf<DispatchQueue> } #if DEBUG extension SendRequestEnvironment { - public static let unimplemented = SendRequestEnvironment() + public static let unimplemented = SendRequestEnvironment( + messenger: .unimplemented, + db: .unimplemented, + mainQueue: .unimplemented, + bgQueue: .unimplemented + ) } #endif public let sendRequestReducer = Reducer<SendRequestState, SendRequestAction, SendRequestEnvironment> { state, action, env in + enum DBFetchEffectID {} + switch action { case .start: + return Effect + .catching { try env.messenger.e2e.tryGet().getContact().getId() } + .tryMap { try env.db().fetchContactsPublisher(.init(id: [$0])) } + .flatMap { $0 } + .assertNoFailure() + .map(\.first) + .map { $0?.marshaled.map { XXClient.Contact.live($0) } } + .map(SendRequestAction.myContactFetched) + .subscribe(on: env.bgQueue) + .receive(on: env.mainQueue) + .eraseToEffect() + .cancellable(id: DBFetchEffectID.self, cancelInFlight: true) + + case .myContactFetched(let contact): + state.myContact = contact return .none case .sendTapped: @@ -60,3 +101,4 @@ public let sendRequestReducer = Reducer<SendRequestState, SendRequestAction, Sen return .none } } +.binding() diff --git a/Examples/xx-messenger/Tests/SendRequestFeatureTests/SendRequestFeatureTests.swift b/Examples/xx-messenger/Tests/SendRequestFeatureTests/SendRequestFeatureTests.swift index a67a241c..a0a7750f 100644 --- a/Examples/xx-messenger/Tests/SendRequestFeatureTests/SendRequestFeatureTests.swift +++ b/Examples/xx-messenger/Tests/SendRequestFeatureTests/SendRequestFeatureTests.swift @@ -1,5 +1,8 @@ +import Combine import ComposableArchitecture import XCTest +import XXClient +import XXModels @testable import SendRequestFeature final class SendRequestFeatureTests: XCTestCase { @@ -12,6 +15,71 @@ final class SendRequestFeatureTests: XCTestCase { environment: .unimplemented ) + var dbDidFetchContacts: [XXModels.Contact.Query] = [] + let dbContactsPublisher = PassthroughSubject<[XXModels.Contact], Error>() + + store.environment.mainQueue = .immediate + store.environment.bgQueue = .immediate + store.environment.messenger.e2e.get = { + var e2e: E2E = .unimplemented + e2e.getContact.run = { + var contact: XXClient.Contact = .unimplemented("my-contact-data".data(using: .utf8)!) + contact.getIdFromContact.run = { _ in "my-contact-id".data(using: .utf8)! } + return contact + } + return e2e + } + store.environment.db.run = { + var db: Database = .failing + db.fetchContactsPublisher.run = { query in + dbDidFetchContacts.append(query) + return dbContactsPublisher.eraseToAnyPublisher() + } + return db + } + store.send(.start) + + XCTAssertNoDifference(dbDidFetchContacts, [.init(id: ["my-contact-id".data(using: .utf8)!])]) + + dbContactsPublisher.send([]) + + store.receive(.myContactFetched(nil)) + + var myDbContact = XXModels.Contact(id: "my-contact-id".data(using: .utf8)!) + myDbContact.marshaled = "my-contact-data".data(using: .utf8)! + dbContactsPublisher.send([myDbContact]) + + store.receive(.myContactFetched(.live("my-contact-data".data(using: .utf8)!))) { + $0.myContact = .live("my-contact-data".data(using: .utf8)!) + } + + dbContactsPublisher.send(completion: .finished) + } + + func testSendRequest() { + var myContact: XXClient.Contact = .unimplemented("my-contact-data".data(using: .utf8)!) + myContact.getFactsFromContact.run = { _ in + [ + Fact(fact: "my-username", type: 0), + Fact(fact: "my-email", type: 1), + Fact(fact: "my-phone", type: 2), + ] + } + + let store = TestStore( + initialState: SendRequestState( + contact: .unimplemented("contact-data".data(using: .utf8)!), + myContact: myContact + ), + reducer: sendRequestReducer, + environment: .unimplemented + ) + + store.send(.set(\.$sendPhone, false)) { + $0.sendPhone = false + } + + store.send(.sendTapped) } } -- GitLab