diff --git a/Examples/xx-messenger/Package.swift b/Examples/xx-messenger/Package.swift index f7e0d0399b2b67ef32c8bece58cfb102e76864a2..8f1e26f79d8f80884a0e60b4a81a249fb00f76d8 100644 --- a/Examples/xx-messenger/Package.swift +++ b/Examples/xx-messenger/Package.swift @@ -106,8 +106,10 @@ let package = Package( .target( name: "RegisterFeature", dependencies: [ + .target(name: "AppCore"), .product(name: "ComposableArchitecture", package: "swift-composable-architecture"), .product(name: "XXMessengerClient", package: "elixxir-dapps-sdk-swift"), + .product(name: "XXModels", package: "client-ios-db"), ], swiftSettings: swiftSettings ), diff --git a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift index d3cc134a7dbca79b4d9e75472eb26697f08a455b..3cbca1db738e7462cff142bcf576a575abcd57e3 100644 --- a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift +++ b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift @@ -38,6 +38,8 @@ extension AppEnvironment { register: { RegisterEnvironment( messenger: messenger, + db: dbManager.getDB, + now: Date.init, mainQueue: mainQueue, bgQueue: bgQueue ) diff --git a/Examples/xx-messenger/Sources/RegisterFeature/RegisterFeature.swift b/Examples/xx-messenger/Sources/RegisterFeature/RegisterFeature.swift index f929d18fd5bdc1a004cd05f4bb366b5c0d835c03..a8d3280c5e321cb78ade668570dcc40159f0b7b7 100644 --- a/Examples/xx-messenger/Sources/RegisterFeature/RegisterFeature.swift +++ b/Examples/xx-messenger/Sources/RegisterFeature/RegisterFeature.swift @@ -1,6 +1,9 @@ +import AppCore import ComposableArchitecture import SwiftUI +import XCTestDynamicOverlay import XXMessengerClient +import XXModels public struct RegisterState: Equatable { public enum Field: String, Hashable { @@ -33,15 +36,21 @@ public enum RegisterAction: Equatable, BindableAction { public struct RegisterEnvironment { public init( messenger: Messenger, + db: DBManagerGetDB, + now: @escaping () -> Date, mainQueue: AnySchedulerOf<DispatchQueue>, bgQueue: AnySchedulerOf<DispatchQueue> ) { self.messenger = messenger + self.db = db + self.now = now self.mainQueue = mainQueue self.bgQueue = bgQueue } public var messenger: Messenger + public var db: DBManagerGetDB + public var now: () -> Date public var mainQueue: AnySchedulerOf<DispatchQueue> public var bgQueue: AnySchedulerOf<DispatchQueue> } @@ -49,6 +58,8 @@ public struct RegisterEnvironment { extension RegisterEnvironment { public static let unimplemented = RegisterEnvironment( messenger: .unimplemented, + db: .unimplemented, + now: XCTUnimplemented("\(Self.self).now"), mainQueue: .unimplemented, bgQueue: .unimplemented ) @@ -66,7 +77,15 @@ public let registerReducer = Reducer<RegisterState, RegisterAction, RegisterEnvi state.failure = nil return .future { [username = state.username] fulfill in do { + let db = try env.db() try env.messenger.register(username: username) + let contact = env.messenger.e2e()!.getContact() + try db.saveContact(Contact( + id: try contact.getId(), + marshaled: contact.data, + username: username, + createdAt: env.now() + )) fulfill(.success(.finished)) } catch { diff --git a/Examples/xx-messenger/Tests/RegisterFeatureTests/RegisterFeatureTests.swift b/Examples/xx-messenger/Tests/RegisterFeatureTests/RegisterFeatureTests.swift index 21d4da16412ab852ff11e1b40da58ac1a5fd5388..a2aad5bd7977dbd210a163d8cdac9001de239723 100644 --- a/Examples/xx-messenger/Tests/RegisterFeatureTests/RegisterFeatureTests.swift +++ b/Examples/xx-messenger/Tests/RegisterFeatureTests/RegisterFeatureTests.swift @@ -1,8 +1,10 @@ import ComposableArchitecture import XCTest +import XXClient +import XXMessengerClient +import XXModels @testable import RegisterFeature -@MainActor final class RegisterFeatureTests: XCTestCase { func testRegister() throws { let store = TestStore( @@ -11,15 +13,35 @@ final class RegisterFeatureTests: XCTestCase { 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" @@ -30,17 +52,56 @@ final class RegisterFeatureTests: XCTestCase { } 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 testRegisterFailure() throws { + 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() @@ -55,6 +116,7 @@ final class RegisterFeatureTests: XCTestCase { 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) {