import ComposableArchitecture import XCTest import XXClient import XXMessengerClient import XXModels @testable import RegisterFeature final class RegisterFeatureTests: XCTestCase { func testRegister() throws { let store = TestStore( initialState: RegisterState(), reducer: registerReducer, environment: .unimplemented ) let now = Date() let mainQueue = DispatchQueue.test let bgQueue = DispatchQueue.test var dbDidSaveContact: [XXModels.Contact] = [] var messengerDidRegisterUsername: [String] = [] store.environment.now = { now } store.environment.mainQueue = mainQueue.eraseToAnyScheduler() store.environment.bgQueue = bgQueue.eraseToAnyScheduler() store.environment.messenger.register.run = { username in messengerDidRegisterUsername.append(username) } store.environment.messenger.e2e.get = { var e2e: E2E = .unimplemented e2e.getContact.run = { var contact = XXClient.Contact.unimplemented("contact-data".data(using: .utf8)!) contact.getIdFromContact.run = { _ in "contact-id".data(using: .utf8)! } return contact } return e2e } store.environment.db.run = { var db: Database = .failing db.saveContact.run = { contact in dbDidSaveContact.append(contact) return contact } return db } store.send(.set(\.$username, "NewUser")) { $0.username = "NewUser" } store.send(.registerTapped) { $0.isRegistering = true } XCTAssertNoDifference(messengerDidRegisterUsername, []) XCTAssertNoDifference(dbDidSaveContact, []) bgQueue.advance() XCTAssertNoDifference(messengerDidRegisterUsername, ["NewUser"]) XCTAssertNoDifference(dbDidSaveContact, [ XXModels.Contact( id: "contact-id".data(using: .utf8)!, marshaled: "contact-data".data(using: .utf8)!, username: "NewUser", createdAt: now ) ]) mainQueue.advance() store.receive(.finished) } func testGetDbFailure() throws { struct Error: Swift.Error, Equatable {} let error = Error() let store = TestStore( initialState: RegisterState(), reducer: registerReducer, environment: .unimplemented ) let mainQueue = DispatchQueue.test let bgQueue = DispatchQueue.test store.environment.mainQueue = mainQueue.eraseToAnyScheduler() store.environment.bgQueue = bgQueue.eraseToAnyScheduler() store.environment.db.run = { throw error } store.send(.registerTapped) { $0.isRegistering = true } bgQueue.advance() mainQueue.advance() store.receive(.failed(error.localizedDescription)) { $0.isRegistering = false $0.failure = error.localizedDescription } } func testMessengerRegisterFailure() throws { struct Error: Swift.Error, Equatable {} let error = Error() let store = TestStore( initialState: RegisterState(), reducer: registerReducer, environment: .unimplemented ) let mainQueue = DispatchQueue.test let bgQueue = DispatchQueue.test store.environment.mainQueue = mainQueue.eraseToAnyScheduler() store.environment.bgQueue = bgQueue.eraseToAnyScheduler() store.environment.db.run = { .failing } store.environment.messenger.register.run = { _ in throw error } store.send(.registerTapped) { $0.isRegistering = true } bgQueue.advance() mainQueue.advance() store.receive(.failed(error.localizedDescription)) { $0.isRegistering = false $0.failure = error.localizedDescription } } }