diff --git a/Examples/xx-messenger/Sources/AppCore/SharedUI/ContactAuthStatusView.swift b/Examples/xx-messenger/Sources/AppCore/SharedUI/ContactAuthStatusView.swift new file mode 100644 index 0000000000000000000000000000000000000000..355749c2e05f7feb9ba4bcdb4d2821309d31712b --- /dev/null +++ b/Examples/xx-messenger/Sources/AppCore/SharedUI/ContactAuthStatusView.swift @@ -0,0 +1,94 @@ +import SwiftUI +import XXModels + +public struct ContactAuthStatusView: View { + public init(_ authStatus: Contact.AuthStatus) { + self.authStatus = authStatus + } + + public var authStatus: Contact.AuthStatus + + public var body: some View { + switch authStatus { + case .stranger: + HStack { + Text("Stranger") + Spacer() + Image(systemName: "person.fill.questionmark") + } + + case .requesting: + HStack { + Text("Sending auth request") + Spacer() + ProgressView() + } + + case .requested: + HStack { + Text("Request sent") + Spacer() + Image(systemName: "paperplane") + } + + case .requestFailed: + HStack { + Text("Sending request failed") + Spacer() + Image(systemName: "xmark.diamond.fill") + .foregroundColor(.red) + } + + case .verificationInProgress: + HStack { + Text("Verification is progress") + Spacer() + ProgressView() + } + + case .verified: + HStack { + Text("Verified") + Spacer() + Image(systemName: "person.fill.checkmark") + } + + case .verificationFailed: + HStack { + Text("Verification failed") + Spacer() + Image(systemName: "xmark.diamond.fill") + .foregroundColor(.red) + } + + case .confirming: + HStack { + Text("Confirming auth request") + Spacer() + ProgressView() + } + + case .confirmationFailed: + HStack { + Text("Confirmation failed") + Spacer() + Image(systemName: "xmark.diamond.fill") + .foregroundColor(.red) + } + + case .friend: + HStack { + Text("Friend") + Spacer() + Image(systemName: "person.fill.checkmark") + } + + case .hidden: + HStack { + Text("Hidden") + Spacer() + Image(systemName: "eye.slash") + } + } + } +} diff --git a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift index 298cb9f6e78b7d3bea1c0e5ec35f1fac235519ea..01e315198e89816e8a7f8054bf0c791d707b9d30 100644 --- a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift +++ b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift @@ -53,9 +53,6 @@ extension AppEnvironment { messenger: messenger, mainQueue: mainQueue, bgQueue: bgQueue, - result: { - UserSearchResultEnvironment() - }, contact: { ContactEnvironment( messenger: messenger, diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift index 8126b792074a9a82050228cc0d0edbe8d26742ce..9f6ef294f5a8b35bdc7e7d0300ce05fd84ae1823 100644 --- a/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift +++ b/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift @@ -105,13 +105,13 @@ public let contactReducer = Reducer<ContactState, ContactAction, ContactEnvironm var dbContact = state.dbContact ?? XXModels.Contact(id: state.id) dbContact.marshaled = xxContact.data if state.importUsername { - dbContact.username = try? xxContact.getFact(.username)?.fact + dbContact.username = try? xxContact.getFact(.username)?.value } if state.importEmail { - dbContact.email = try? xxContact.getFact(.email)?.fact + dbContact.email = try? xxContact.getFact(.email)?.value } if state.importPhone { - dbContact.phone = try? xxContact.getFact(.phone)?.fact + dbContact.phone = try? xxContact.getFact(.phone)?.value } _ = try! env.db().saveContact(dbContact) } diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift index 48743b07af69b695c6f6ec34159d2b0c75400458..9869169327924ffcf719f88e0fd71feee16493e8 100644 --- a/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift +++ b/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift @@ -26,9 +26,9 @@ public struct ContactView: View { init(state: ContactState) { dbContact = state.dbContact xxContactIsSet = state.xxContact != nil - xxContactUsername = try? state.xxContact?.getFact(.username)?.fact - xxContactEmail = try? state.xxContact?.getFact(.email)?.fact - xxContactPhone = try? state.xxContact?.getFact(.phone)?.fact + xxContactUsername = try? state.xxContact?.getFact(.username)?.value + xxContactEmail = try? state.xxContact?.getFact(.email)?.value + xxContactPhone = try? state.xxContact?.getFact(.phone)?.value importUsername = state.importUsername importEmail = state.importEmail importPhone = state.importPhone @@ -79,10 +79,14 @@ public struct ContactView: View { Button { viewStore.send(.importFactsTapped) } label: { - if viewStore.dbContact == nil { - Text("Save contact") - } else { - Text("Update contact") + HStack { + if viewStore.dbContact == nil { + Text("Save contact") + } else { + Text("Update contact") + } + Spacer() + Image(systemName: "arrow.down") } } } header: { @@ -100,87 +104,7 @@ public struct ContactView: View { } Section { - switch dbContact.authStatus { - case .stranger: - HStack { - Text("Stranger") - Spacer() - Image(systemName: "person.fill.questionmark") - } - - case .requesting: - HStack { - Text("Sending auth request") - Spacer() - ProgressView() - } - - case .requested: - HStack { - Text("Request sent") - Spacer() - Image(systemName: "paperplane") - } - - case .requestFailed: - HStack { - Text("Sending request failed") - Spacer() - Image(systemName: "xmark.diamond.fill") - .foregroundColor(.red) - } - - case .verificationInProgress: - HStack { - Text("Verification is progress") - Spacer() - ProgressView() - } - - case .verified: - HStack { - Text("Verified") - Spacer() - Image(systemName: "person.fill.checkmark") - } - - case .verificationFailed: - HStack { - Text("Verification failed") - Spacer() - Image(systemName: "xmark.diamond.fill") - .foregroundColor(.red) - } - - case .confirming: - HStack { - Text("Confirming auth request") - Spacer() - ProgressView() - } - - case .confirmationFailed: - HStack { - Text("Confirmation failed") - Spacer() - Image(systemName: "xmark.diamond.fill") - .foregroundColor(.red) - } - - case .friend: - HStack { - Text("Friend") - Spacer() - Image(systemName: "person.fill.checkmark") - } - - case .hidden: - HStack { - Text("Hidden") - Spacer() - Image(systemName: "eye.slash") - } - } + ContactAuthStatusView(dbContact.authStatus) Button { viewStore.send(.sendRequestTapped) } label: { diff --git a/Examples/xx-messenger/Sources/HomeFeature/HomeFeature.swift b/Examples/xx-messenger/Sources/HomeFeature/HomeFeature.swift index 712855ba1ba4aecfe467679b4fcc87090de4ee43..9df6d745b07e282095cac03a0d978646795af301 100644 --- a/Examples/xx-messenger/Sources/HomeFeature/HomeFeature.swift +++ b/Examples/xx-messenger/Sources/HomeFeature/HomeFeature.swift @@ -200,7 +200,7 @@ public let homeReducer = Reducer<HomeState, HomeAction, HomeEnvironment> let contact = try env.dbManager.getDB().fetchContacts(.init(id: [contactId])).first if let username = contact?.username { let ud = try env.messenger.ud.tryGet() - try ud.permanentDeleteAccount(username: Fact(fact: username, type: 0)) + try ud.permanentDeleteAccount(username: Fact(type: .username, value: username)) } try env.messenger.destroy() try env.dbManager.removeDB() diff --git a/Examples/xx-messenger/Sources/SendRequestFeature/SendRequestView.swift b/Examples/xx-messenger/Sources/SendRequestFeature/SendRequestView.swift index 5f1cd7d53e8300fc55ffc907a410fb66c2b92c77..fbfd9958fbc721504586ee04a1927166c340fa6e 100644 --- a/Examples/xx-messenger/Sources/SendRequestFeature/SendRequestView.swift +++ b/Examples/xx-messenger/Sources/SendRequestFeature/SendRequestView.swift @@ -24,12 +24,12 @@ public struct SendRequestView: View { var failure: String? init(state: SendRequestState) { - contactUsername = try? state.contact.getFact(.username)?.fact - contactEmail = try? state.contact.getFact(.email)?.fact - contactPhone = try? state.contact.getFact(.phone)?.fact - myUsername = try? state.myContact?.getFact(.username)?.fact - myEmail = try? state.myContact?.getFact(.email)?.fact - myPhone = try? state.myContact?.getFact(.phone)?.fact + contactUsername = try? state.contact.getFact(.username)?.value + contactEmail = try? state.contact.getFact(.email)?.value + contactPhone = try? state.contact.getFact(.phone)?.value + myUsername = try? state.myContact?.getFact(.username)?.value + myEmail = try? state.myContact?.getFact(.email)?.value + myPhone = try? state.myContact?.getFact(.phone)?.value sendUsername = state.sendUsername sendEmail = state.sendEmail sendPhone = state.sendPhone @@ -134,9 +134,9 @@ public struct SendRequestView_Previews: PreviewProvider { var contact = XXClient.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), + Fact(type: .username, value: "contact-username"), + Fact(type: .email, value: "contact-email"), + Fact(type: .phone, value: "contact-phone"), ] } return contact @@ -145,9 +145,9 @@ public struct SendRequestView_Previews: PreviewProvider { var contact = XXClient.Contact.unimplemented("my-data".data(using: .utf8)!) contact.getFactsFromContact.run = { _ in [ - Fact(fact: "my-username", type: 0), - Fact(fact: "my-email", type: 1), - Fact(fact: "my-phone", type: 2), + Fact(type: .username, value: "my-username"), + Fact(type: .email, value: "my-email"), + Fact(type: .phone, value: "my-phone"), ] } return contact diff --git a/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchFeature.swift b/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchFeature.swift index 1b10c1b3c416b6cac1ae579da1b71f186f83c583..2e892bb4882b43ddab7d91ab81d15c007e561a87 100644 --- a/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchFeature.swift +++ b/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchFeature.swift @@ -13,12 +13,38 @@ public struct UserSearchState: Equatable { case phone } + public struct Result: Equatable, Identifiable { + public init( + id: Data, + xxContact: XXClient.Contact, + username: String? = nil, + email: String? = nil, + phone: String? = nil + ) { + self.id = id + self.xxContact = xxContact + self.username = username + self.email = email + self.phone = phone + } + + public var id: Data + public var xxContact: XXClient.Contact + public var username: String? + public var email: String? + public var phone: String? + + public var hasFacts: Bool { + username != nil || email != nil || phone != nil + } + } + public init( focusedField: Field? = nil, query: MessengerSearchUsers.Query = .init(), isSearching: Bool = false, failure: String? = nil, - results: IdentifiedArrayOf<UserSearchResultState> = [], + results: IdentifiedArrayOf<Result> = [], contact: ContactState? = nil ) { self.focusedField = focusedField @@ -33,7 +59,7 @@ public struct UserSearchState: Equatable { @BindableState public var query: MessengerSearchUsers.Query public var isSearching: Bool public var failure: String? - public var results: IdentifiedArrayOf<UserSearchResultState> + public var results: IdentifiedArrayOf<Result> public var contact: ContactState? } @@ -42,8 +68,8 @@ public enum UserSearchAction: Equatable, BindableAction { case didFail(String) case didSucceed([Contact]) case didDismissContact + case resultTapped(id: Data) case binding(BindingAction<UserSearchState>) - case result(id: UserSearchResultState.ID, action: UserSearchResultAction) case contact(ContactAction) } @@ -52,20 +78,17 @@ public struct UserSearchEnvironment { messenger: Messenger, mainQueue: AnySchedulerOf<DispatchQueue>, bgQueue: AnySchedulerOf<DispatchQueue>, - result: @escaping () -> UserSearchResultEnvironment, contact: @escaping () -> ContactEnvironment ) { self.messenger = messenger self.mainQueue = mainQueue self.bgQueue = bgQueue - self.result = result self.contact = contact } public var messenger: Messenger public var mainQueue: AnySchedulerOf<DispatchQueue> public var bgQueue: AnySchedulerOf<DispatchQueue> - public var result: () -> UserSearchResultEnvironment public var contact: () -> ContactEnvironment } @@ -75,7 +98,6 @@ extension UserSearchEnvironment { messenger: .unimplemented, mainQueue: .unimplemented, bgQueue: .unimplemented, - result: { .unimplemented }, contact: { .unimplemented } ) } @@ -105,7 +127,13 @@ public let userSearchReducer = Reducer<UserSearchState, UserSearchAction, UserSe state.failure = nil state.results = IdentifiedArray(uniqueElements: contacts.compactMap { contact in guard let id = try? contact.getId() else { return nil } - return UserSearchResultState(id: id, xxContact: contact) + return UserSearchState.Result( + id: id, + xxContact: contact, + username: try? contact.getFact(.username)?.value, + email: try? contact.getFact(.email)?.value, + phone: try? contact.getFact(.phone)?.value + ) }) return .none @@ -119,24 +147,18 @@ public let userSearchReducer = Reducer<UserSearchState, UserSearchAction, UserSe state.contact = nil return .none - case .result(let id, action: .tapped): + case .resultTapped(let id): state.contact = ContactState( id: id, xxContact: state.results[id: id]?.xxContact ) return .none - case .binding(_), .result(_, _), .contact(_): + case .binding(_), .contact(_): return .none } } .binding() -.presenting( - forEach: userSearchResultReducer, - state: \.results, - action: /UserSearchAction.result(id:action:), - environment: { $0.result() } -) .presenting( contactReducer, state: .keyPath(\.contact), diff --git a/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchResultFeature.swift b/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchResultFeature.swift deleted file mode 100644 index 839e6886236eec081b64616e64b8ff7c59811fbb..0000000000000000000000000000000000000000 --- a/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchResultFeature.swift +++ /dev/null @@ -1,55 +0,0 @@ -import ComposableArchitecture -import Foundation -import XCTestDynamicOverlay -import XXClient - -public struct UserSearchResultState: Equatable, Identifiable { - public init( - id: Data, - xxContact: XXClient.Contact, - username: String? = nil, - email: String? = nil, - phone: String? = nil - ) { - self.id = id - self.xxContact = xxContact - self.username = username - self.email = email - self.phone = phone - } - - public var id: Data - public var xxContact: XXClient.Contact - public var username: String? - public var email: String? - public var phone: String? -} - -public enum UserSearchResultAction: Equatable { - case start - case tapped -} - -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: - state.username = try? state.xxContact.getFact(.username)?.fact - state.email = try? state.xxContact.getFact(.email)?.fact - state.phone = try? state.xxContact.getFact(.phone)?.fact - return .none - - case .tapped: - return .none - } -} diff --git a/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchResultView.swift b/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchResultView.swift deleted file mode 100644 index fd29a84fb819761505b8b973c757f29a46597490..0000000000000000000000000000000000000000 --- a/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchResultView.swift +++ /dev/null @@ -1,74 +0,0 @@ -import ComposableArchitecture -import SwiftUI -import XXModels - -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 { - Button { - viewStore.send(.tapped) - } label: { - HStack { - VStack { - 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) - } - } - } - Spacer() - Image(systemName: "chevron.forward") - } - } - } - .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)!, - xxContact: .unimplemented("contact-data".data(using: .utf8)!) - ), - reducer: .empty, - environment: () - )) - } -} -#endif diff --git a/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchView.swift b/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchView.swift index f0416b3a53542ef4195a66ca077617327d62737c..c694411972c9227955d33a1a3b0776a829d16546 100644 --- a/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchView.swift +++ b/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchView.swift @@ -17,12 +17,14 @@ public struct UserSearchView: View { var query: MessengerSearchUsers.Query var isSearching: Bool var failure: String? + var results: IdentifiedArrayOf<UserSearchState.Result> init(state: UserSearchState) { focusedField = state.focusedField query = state.query isSearching = state.isSearching failure = state.failure + results = state.results } } @@ -87,13 +89,34 @@ public struct UserSearchView: View { } } - ForEachStore( - store.scope( - state: \.results, - action: UserSearchAction.result(id:action:) - ), - content: UserSearchResultView.init(store:) - ) + ForEach(viewStore.results) { result in + Section { + Button { + viewStore.send(.resultTapped(id: result.id)) + } label: { + HStack { + VStack { + if result.hasFacts { + if let username = result.username { + Label(username, systemImage: "person") + } + if let email = result.email { + Label(email, systemImage: "envelope") + } + if let phone = result.phone { + Label(phone, systemImage: "phone") + } + } else { + Label("No facts", systemImage: "questionmark") + } + } + .tint(Color.primary) + Spacer() + Image(systemName: "chevron.forward") + } + } + } + } } .onChange(of: viewStore.focusedField) { focusedField = $0 } .onChange(of: focusedField) { viewStore.send(.set(\.$focusedField, $0)) } diff --git a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift index 244cc90093c2267fd124a268982c5e65e5c57380..247abb49e226acd5ea720d8a7cd8265f6ca197ef 100644 --- a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift +++ b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift @@ -55,9 +55,9 @@ final class ContactFeatureTests: XCTestCase { var xxContact: XXClient.Contact = .unimplemented("contact-data".data(using: .utf8)!) xxContact.getFactsFromContact.run = { _ in [ - Fact(fact: "contact-username", type: 0), - Fact(fact: "contact-email", type: 1), - Fact(fact: "contact-phone", type: 2), + Fact(type: .username, value: "contact-username"), + Fact(type: .email, value: "contact-email"), + Fact(type: .phone, value: "contact-phone"), ] } diff --git a/Examples/xx-messenger/Tests/HomeFeatureTests/HomeFeatureTests.swift b/Examples/xx-messenger/Tests/HomeFeatureTests/HomeFeatureTests.swift index cbc261cefd8f85153c3316d08bada0337cceea35..2d7f6dafd6f5833483112c9e7bea9912be90314e 100644 --- a/Examples/xx-messenger/Tests/HomeFeatureTests/HomeFeatureTests.swift +++ b/Examples/xx-messenger/Tests/HomeFeatureTests/HomeFeatureTests.swift @@ -370,7 +370,7 @@ final class HomeFeatureTests: XCTestCase { } XCTAssertNoDifference(dbDidFetchContacts, [.init(id: ["contact-id".data(using: .utf8)!])]) - XCTAssertNoDifference(udDidPermanentDeleteAccount, [Fact(fact: "MyUsername", type: 0)]) + XCTAssertNoDifference(udDidPermanentDeleteAccount, [Fact(type: .username, value: "MyUsername")]) XCTAssertNoDifference(messengerDidDestroy, 1) XCTAssertNoDifference(didRemoveDB, 1) diff --git a/Examples/xx-messenger/Tests/RegisterFeatureTests/RegisterFeatureTests.swift b/Examples/xx-messenger/Tests/RegisterFeatureTests/RegisterFeatureTests.swift index 12addba7f1a5901fcf2d9424d44e791db8ab4904..6c802874d64bbd0dcf7e0ac5b9fee0de7e136d8f 100644 --- a/Examples/xx-messenger/Tests/RegisterFeatureTests/RegisterFeatureTests.swift +++ b/Examples/xx-messenger/Tests/RegisterFeatureTests/RegisterFeatureTests.swift @@ -63,7 +63,7 @@ final class RegisterFeatureTests: XCTestCase { bgQueue.advance() XCTAssertNoDifference(messengerDidRegisterUsername, ["NewUser"]) - XCTAssertNoDifference(didSetFactsOnContact, [[Fact(fact: "NewUser", type: 0)]]) + XCTAssertNoDifference(didSetFactsOnContact, [[Fact(type: .username, value: "NewUser")]]) XCTAssertNoDifference(dbDidSaveContact, [ XXModels.Contact( id: "contact-id".data(using: .utf8)!, diff --git a/Examples/xx-messenger/Tests/SendRequestFeatureTests/SendRequestFeatureTests.swift b/Examples/xx-messenger/Tests/SendRequestFeatureTests/SendRequestFeatureTests.swift index 1dbe26be1d99196abe4217b23f5daeba46fe15c7..cec3587e845624edc68ef537b00604b8a577c13c 100644 --- a/Examples/xx-messenger/Tests/SendRequestFeatureTests/SendRequestFeatureTests.swift +++ b/Examples/xx-messenger/Tests/SendRequestFeatureTests/SendRequestFeatureTests.swift @@ -63,9 +63,9 @@ final class SendRequestFeatureTests: XCTestCase { var myContact: XXClient.Contact = .unimplemented("my-contact-data".data(using: .utf8)!) let myFacts = [ - Fact(fact: "my-username", type: 0), - Fact(fact: "my-email", type: 1), - Fact(fact: "my-phone", type: 2), + Fact(type: .username, value: "my-username"), + Fact(type: .email, value: "my-email"), + Fact(type: .phone, value: "my-phone"), ] myContact.getFactsFromContact.run = { _ in myFacts } @@ -142,9 +142,9 @@ final class SendRequestFeatureTests: XCTestCase { var myContact: XXClient.Contact = .unimplemented("my-contact-data".data(using: .utf8)!) let myFacts = [ - Fact(fact: "my-username", type: 0), - Fact(fact: "my-email", type: 1), - Fact(fact: "my-phone", type: 2), + Fact(type: .username, value: "my-username"), + Fact(type: .email, value: "my-email"), + Fact(type: .phone, value: "my-phone"), ] myContact.getFactsFromContact.run = { _ in myFacts } diff --git a/Examples/xx-messenger/Tests/UserSearchFeatureTests/UserSearchFeatureTests.swift b/Examples/xx-messenger/Tests/UserSearchFeatureTests/UserSearchFeatureTests.swift index c457327c86722f020ffe2ffc55c251c3261fcc8a..f8f482f6c49d236f511239a6722cc357ec48ab77 100644 --- a/Examples/xx-messenger/Tests/UserSearchFeatureTests/UserSearchFeatureTests.swift +++ b/Examples/xx-messenger/Tests/UserSearchFeatureTests/UserSearchFeatureTests.swift @@ -20,12 +20,26 @@ final class UserSearchFeatureTests: XCTestCase { var contact1 = Contact.unimplemented("contact-1".data(using: .utf8)!) contact1.getIdFromContact.run = { _ in "contact-1-id".data(using: .utf8)! } - var contact2 = Contact.unimplemented("contact-1".data(using: .utf8)!) + contact1.getFactsFromContact.run = { _ in + [ + Fact(type: .username, value: "contact-1-username"), + Fact(type: .email, value: "contact-1-email"), + Fact(type: .phone, value: "contact-1-phone"), + ] + } + var contact2 = Contact.unimplemented("contact-2".data(using: .utf8)!) contact2.getIdFromContact.run = { _ in "contact-2-id".data(using: .utf8)! } + contact2.getFactsFromContact.run = { _ in + [ + Fact(type: .username, value: "contact-2-username"), + ] + } var contact3 = Contact.unimplemented("contact-3".data(using: .utf8)!) contact3.getIdFromContact.run = { _ in throw GetIdFromContactError() } + contact3.getFactsFromContact.run = { _ in [] } var contact4 = Contact.unimplemented("contact-4".data(using: .utf8)!) contact4.getIdFromContact.run = { _ in "contact-4-id".data(using: .utf8)! } + contact4.getFactsFromContact.run = { _ in throw GetFactsFromContactError() } let contacts = [contact1, contact2, contact3, contact4] store.environment.bgQueue = .immediate @@ -54,9 +68,22 @@ final class UserSearchFeatureTests: XCTestCase { $0.isSearching = false $0.failure = nil $0.results = [ - .init(id: "contact-1-id".data(using: .utf8)!, xxContact: contact1), - .init(id: "contact-2-id".data(using: .utf8)!, xxContact: contact2), - .init(id: "contact-4-id".data(using: .utf8)!, xxContact: contact4) + .init( + id: "contact-1-id".data(using: .utf8)!, + xxContact: contact1, + username: "contact-1-username", + email: "contact-1-email", + phone: "contact-1-phone" + ), + .init( + id: "contact-2-id".data(using: .utf8)!, + xxContact: contact2, + username: "contact-2-username" + ), + .init( + id: "contact-4-id".data(using: .utf8)!, + xxContact: contact4 + ) ] } } @@ -103,7 +130,7 @@ final class UserSearchFeatureTests: XCTestCase { environment: .unimplemented ) - store.send(.result(id: "contact-id".data(using: .utf8)!, action: .tapped)) { + store.send(.resultTapped(id: "contact-id".data(using: .utf8)!)) { $0.contact = ContactState( id: "contact-id".data(using: .utf8)!, xxContact: .unimplemented("contact-data".data(using: .utf8)!) diff --git a/Examples/xx-messenger/Tests/UserSearchFeatureTests/UserSearchResultFeatureTests.swift b/Examples/xx-messenger/Tests/UserSearchFeatureTests/UserSearchResultFeatureTests.swift deleted file mode 100644 index c8f2a99b92b35b645c1d3e94462e6353ec4d33fc..0000000000000000000000000000000000000000 --- a/Examples/xx-messenger/Tests/UserSearchFeatureTests/UserSearchResultFeatureTests.swift +++ /dev/null @@ -1,46 +0,0 @@ -import ComposableArchitecture -import XCTest -import XCTestDynamicOverlay -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)!, - xxContact: contact - ), - reducer: userSearchResultReducer, - environment: .unimplemented - ) - - store.send(.start) { - $0.username = "contact-username" - $0.email = "contact-email" - $0.phone = "contact-phone" - } - } - - func testTapped() { - let store = TestStore( - initialState: UserSearchResultState( - id: "contact-id".data(using: .utf8)!, - xxContact: .unimplemented("contact-data".data(using: .utf8)!) - ), - reducer: userSearchResultReducer, - environment: .unimplemented - ) - - store.send(.tapped) - } -}