From 2e50e9c88e80c549d88e2bdf56fffd495f8c1d11 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Tue, 6 Sep 2022 23:51:12 +0200 Subject: [PATCH] Add UserSearchResultFeature --- .../UserSearchResultFeature.swift | 52 +++++++++++++++ .../UserSearchResultView.swift | 63 +++++++++++++++++++ .../UserSearchResultFeatureTests.swift | 32 ++++++++++ 3 files changed, 147 insertions(+) create mode 100644 Examples/xx-messenger/Sources/UserSearchFeature/UserSearchResultFeature.swift create mode 100644 Examples/xx-messenger/Sources/UserSearchFeature/UserSearchResultView.swift create mode 100644 Examples/xx-messenger/Tests/UserSearchFeatureTests/UserSearchResultFeatureTests.swift diff --git a/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchResultFeature.swift b/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchResultFeature.swift new file mode 100644 index 00000000..a224384b --- /dev/null +++ b/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchResultFeature.swift @@ -0,0 +1,52 @@ +import ComposableArchitecture +import Foundation +import XCTestDynamicOverlay +import XXClient + +public struct UserSearchResultState: Equatable, Identifiable { + public init( + id: Data, + contact: Contact, + username: String? = nil, + email: String? = nil, + phone: String? = nil + ) { + self.id = id + self.contact = contact + self.username = username + self.email = email + self.phone = phone + } + + public var id: Data + public var contact: XXClient.Contact + public var username: String? + public var email: String? + public var phone: String? +} + +public enum UserSearchResultAction: Equatable { + case start +} + +public struct UserSearchResultEnvironment { + public init() {} +} + +#if DEBUG +extension UserSearchResultEnvironment { + public static let unimplemented = UserSearchResultEnvironment() +} +#endif + +public let userSearchResultReducer = Reducer<UserSearchResultState, UserSearchResultAction, UserSearchResultEnvironment> +{ state, action, env in + switch action { + case .start: + let facts = (try? state.contact.getFacts()) ?? [] + state.username = facts.first(where: { $0.type == 0 })?.fact + state.email = facts.first(where: { $0.type == 1 })?.fact + state.phone = facts.first(where: { $0.type == 2 })?.fact + return .none + } +} diff --git a/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchResultView.swift b/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchResultView.swift new file mode 100644 index 00000000..b1a6e267 --- /dev/null +++ b/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchResultView.swift @@ -0,0 +1,63 @@ +import ComposableArchitecture +import SwiftUI + +public struct UserSearchResultView: View { + public init(store: Store<UserSearchResultState, UserSearchResultAction>) { + self.store = store + } + + let store: Store<UserSearchResultState, UserSearchResultAction> + + struct ViewState: Equatable { + var username: String? + var email: String? + var phone: String? + + init(state: UserSearchResultState) { + username = state.username + email = state.email + phone = state.phone + } + + var isEmpty: Bool { + username == nil && email == nil && phone == nil + } + } + + public var body: some View { + WithViewStore(store.scope(state: ViewState.init)) { viewStore in + Section { + if viewStore.isEmpty { + Image(systemName: "questionmark") + .frame(maxWidth: .infinity) + } else { + if let username = viewStore.username { + Text(username) + } + if let email = viewStore.email { + Text(email) + } + if let phone = viewStore.phone { + Text(phone) + } + } + } + .task { viewStore.send(.start) } + } + } +} + +#if DEBUG +public struct UserSearchResultView_Previews: PreviewProvider { + public static var previews: some View { + UserSearchResultView(store: Store( + initialState: UserSearchResultState( + id: "contact-id".data(using: .utf8)!, + contact: .unimplemented("contact-data".data(using: .utf8)!) + ), + reducer: .empty, + environment: () + )) + } +} +#endif diff --git a/Examples/xx-messenger/Tests/UserSearchFeatureTests/UserSearchResultFeatureTests.swift b/Examples/xx-messenger/Tests/UserSearchFeatureTests/UserSearchResultFeatureTests.swift new file mode 100644 index 00000000..b4f68452 --- /dev/null +++ b/Examples/xx-messenger/Tests/UserSearchFeatureTests/UserSearchResultFeatureTests.swift @@ -0,0 +1,32 @@ +import ComposableArchitecture +import XCTest +import XXClient +@testable import UserSearchFeature + +final class UserSearchResultFeatureTests: XCTestCase { + func testStart() { + var contact = Contact.unimplemented("contact-data".data(using: .utf8)!) + contact.getFactsFromContact.run = { _ in + [ + Fact(fact: "contact-username", type: 0), + Fact(fact: "contact-email", type: 1), + Fact(fact: "contact-phone", type: 2), + ] + } + + let store = TestStore( + initialState: UserSearchResultState( + id: "contact-id".data(using: .utf8)!, + contact: contact + ), + reducer: userSearchResultReducer, + environment: .unimplemented + ) + + store.send(.start) { + $0.username = "contact-username" + $0.email = "contact-email" + $0.phone = "contact-phone" + } + } +} -- GitLab