import ChatFeature import CheckContactAuthFeature import Combine import ComposableArchitecture import ConfirmRequestFeature import ContactLookupFeature import CustomDump import SendRequestFeature import VerifyContactFeature import XCTest import XXClient import XXModels @testable import ContactFeature final class ContactFeatureTests: XCTestCase { func testStart() { let store = TestStore( initialState: ContactState( id: "contact-id".data(using: .utf8)! ), reducer: contactReducer, environment: .unimplemented ) var dbDidFetchContacts: [XXModels.Contact.Query] = [] let dbContactsPublisher = PassthroughSubject<[XXModels.Contact], Error>() store.environment.mainQueue = .immediate store.environment.bgQueue = .immediate store.environment.db.run = { var db: Database = .unimplemented db.fetchContactsPublisher.run = { query in dbDidFetchContacts.append(query) return dbContactsPublisher.eraseToAnyPublisher() } return db } store.send(.start) XCTAssertNoDifference(dbDidFetchContacts, [ .init(id: ["contact-id".data(using: .utf8)!]) ]) let dbContact = XXModels.Contact(id: "contact-id".data(using: .utf8)!) dbContactsPublisher.send([dbContact]) store.receive(.dbContactFetched(dbContact)) { $0.dbContact = dbContact } dbContactsPublisher.send(completion: .finished) } func testImportFacts() { let dbContact: XXModels.Contact = .init( id: "contact-id".data(using: .utf8)! ) var xxContact: XXClient.Contact = .unimplemented("contact-data".data(using: .utf8)!) xxContact.getFactsFromContact.run = { _ in [ Fact(type: .username, value: "contact-username"), Fact(type: .email, value: "contact-email"), Fact(type: .phone, value: "contact-phone"), ] } let store = TestStore( initialState: ContactState( id: "contact-id".data(using: .utf8)!, dbContact: dbContact, xxContact: xxContact ), reducer: contactReducer, environment: .unimplemented ) var dbDidSaveContact: [XXModels.Contact] = [] store.environment.mainQueue = .immediate store.environment.bgQueue = .immediate store.environment.db.run = { var db: Database = .unimplemented db.saveContact.run = { contact in dbDidSaveContact.append(contact) return contact } return db } store.send(.importFactsTapped) var expectedSavedContact = dbContact expectedSavedContact.marshaled = xxContact.data expectedSavedContact.username = "contact-username" expectedSavedContact.email = "contact-email" expectedSavedContact.phone = "contact-phone" XCTAssertNoDifference(dbDidSaveContact, [expectedSavedContact]) } func testLookupTapped() { let contactId = "contact-id".data(using: .utf8)! let store = TestStore( initialState: ContactState( id: contactId ), reducer: contactReducer, environment: .unimplemented ) store.send(.lookupTapped) { $0.lookup = ContactLookupState(id: contactId) } } func testLookupDismissed() { let contactId = "contact-id".data(using: .utf8)! let store = TestStore( initialState: ContactState( id: contactId, lookup: ContactLookupState(id: contactId) ), reducer: contactReducer, environment: .unimplemented ) store.send(.lookupDismissed) { $0.lookup = nil } } func testLookupDidLookup() { let contactId = "contact-id".data(using: .utf8)! let contact = Contact.unimplemented("contact-data".data(using: .utf8)!) let store = TestStore( initialState: ContactState( id: contactId, lookup: ContactLookupState(id: contactId) ), reducer: contactReducer, environment: .unimplemented ) store.send(.lookup(.didLookup(contact))) { $0.xxContact = contact $0.lookup = nil } } func testSendRequestWithDBContact() { var dbContact = XXModels.Contact(id: "contact-id".data(using: .utf8)!) dbContact.marshaled = "contact-data".data(using: .utf8)! let store = TestStore( initialState: ContactState( id: dbContact.id, dbContact: dbContact ), reducer: contactReducer, environment: .unimplemented ) store.send(.sendRequestTapped) { $0.sendRequest = SendRequestState(contact: .live(dbContact.marshaled!)) } } func testSendRequestWithXXContact() { let xxContact = XXClient.Contact.unimplemented("contact-id".data(using: .utf8)!) let store = TestStore( initialState: ContactState( id: "contact-id".data(using: .utf8)!, xxContact: xxContact ), reducer: contactReducer, environment: .unimplemented ) store.send(.sendRequestTapped) { $0.sendRequest = SendRequestState(contact: xxContact) } } func testSendRequestDismissed() { let store = TestStore( initialState: ContactState( id: "contact-id".data(using: .utf8)!, sendRequest: SendRequestState( contact: .unimplemented("contact-id".data(using: .utf8)!) ) ), reducer: contactReducer, environment: .unimplemented ) store.send(.sendRequestDismissed) { $0.sendRequest = nil } } func testSendRequestSucceeded() { let store = TestStore( initialState: ContactState( id: "contact-id".data(using: .utf8)!, sendRequest: SendRequestState( contact: .unimplemented("contact-id".data(using: .utf8)!) ) ), reducer: contactReducer, environment: .unimplemented ) store.send(.sendRequest(.sendSucceeded)) { $0.sendRequest = nil } } func testVerifyContactTapped() { let contactData = "contact-data".data(using: .utf8)! let store = TestStore( initialState: ContactState( id: Data(), dbContact: XXModels.Contact( id: Data(), marshaled: contactData ) ), reducer: contactReducer, environment: .unimplemented ) store.send(.verifyContactTapped) { $0.verifyContact = VerifyContactState( contact: .unimplemented(contactData) ) } } func testVerifyContactDismissed() { let store = TestStore( initialState: ContactState( id: "contact-id".data(using: .utf8)!, verifyContact: VerifyContactState( contact: .unimplemented("contact-data".data(using: .utf8)!) ) ), reducer: contactReducer, environment: .unimplemented ) store.send(.verifyContactDismissed) { $0.verifyContact = nil } } func testCheckAuthTapped() { let contactData = "contact-data".data(using: .utf8)! let store = TestStore( initialState: ContactState( id: Data(), dbContact: XXModels.Contact( id: Data(), marshaled: contactData ) ), reducer: contactReducer, environment: .unimplemented ) store.send(.checkAuthTapped) { $0.checkAuth = CheckContactAuthState( contact: .unimplemented(contactData) ) } } func testCheckAuthDismissed() { let store = TestStore( initialState: ContactState( id: "contact-id".data(using: .utf8)!, checkAuth: CheckContactAuthState( contact: .unimplemented("contact-data".data(using: .utf8)!) ) ), reducer: contactReducer, environment: .unimplemented ) store.send(.checkAuthDismissed) { $0.checkAuth = nil } } func testConfirmRequestTapped() { let contactData = "contact-data".data(using: .utf8)! let store = TestStore( initialState: ContactState( id: Data(), dbContact: XXModels.Contact( id: Data(), marshaled: contactData ) ), reducer: contactReducer, environment: .unimplemented ) store.send(.confirmRequestTapped) { $0.confirmRequest = ConfirmRequestState( contact: .unimplemented(contactData) ) } } func testConfirmRequestDismissed() { let store = TestStore( initialState: ContactState( id: "contact-id".data(using: .utf8)!, confirmRequest: ConfirmRequestState( contact: .unimplemented("contact-data".data(using: .utf8)!) ) ), reducer: contactReducer, environment: .unimplemented ) store.send(.confirmRequestDismissed) { $0.confirmRequest = nil } } func testChatTapped() { let contactId = "contact-id".data(using: .utf8)! let store = TestStore( initialState: ContactState( id: contactId ), reducer: contactReducer, environment: .unimplemented ) store.send(.chatTapped) { $0.chat = ChatState(id: .contact(contactId)) } } func testChatDismissed() { let store = TestStore( initialState: ContactState( id: "contact-id".data(using: .utf8)!, chat: ChatState(id: .contact("contact-id".data(using: .utf8)!)) ), reducer: contactReducer, environment: .unimplemented ) store.send(.chatDismissed) { $0.chat = nil } } }