import Combine import ComposableArchitecture import CustomDump import SendRequestFeature 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 = .failing 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 testSaveFacts() { 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(fact: "contact-username", type: 0), Fact(fact: "contact-email", type: 1), Fact(fact: "contact-phone", type: 2), ] } 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 = .failing db.saveContact.run = { contact in dbDidSaveContact.append(contact) return contact } return db } store.send(.saveFactsTapped) var expectedSavedContact = dbContact expectedSavedContact.marshaled = xxContact.data expectedSavedContact.username = "contact-username" expectedSavedContact.email = "contact-email" expectedSavedContact.phone = "contact-phone" XCTAssertNoDifference(dbDidSaveContact, [expectedSavedContact]) } 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 } } }