diff --git a/Examples/xx-messenger/Package.swift b/Examples/xx-messenger/Package.swift index f552abe40f22920d1358f3487de7207633d272af..5457518c69182edcba6c38d10f956f33401f32c8 100644 --- a/Examples/xx-messenger/Package.swift +++ b/Examples/xx-messenger/Package.swift @@ -344,6 +344,7 @@ let package = Package( .target( name: "WelcomeFeature", dependencies: [ + .target(name: "AppCore"), .product(name: "ComposableArchitecture", package: "swift-composable-architecture"), .product(name: "XXMessengerClient", package: "elixxir-dapps-sdk-swift"), ], diff --git a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift index e00d9d8231fd35509eabc64d79c22f2de715646b..c6bb208ebdbbe014fcccb62b3ecf9231a015eefd 100644 --- a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift +++ b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift @@ -90,6 +90,7 @@ extension AppEnvironment { welcome: { WelcomeEnvironment( messenger: messenger, + dbManager: dbManager, mainQueue: mainQueue, bgQueue: bgQueue ) diff --git a/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeFeature.swift b/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeFeature.swift index 6c6f2e22aa36e73ff0fc4acc441eb63b91f56e66..9e98e4be26e2a23ed85e2e2989a10fac059f91e8 100644 --- a/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeFeature.swift +++ b/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeFeature.swift @@ -1,15 +1,19 @@ +import AppCore import ComposableArchitecture import SwiftUI import XXMessengerClient public struct WelcomeState: Equatable { public init( - isCreatingCMix: Bool = false + isCreatingCMix: Bool = false, + failure: String? = nil ) { self.isCreatingAccount = isCreatingCMix + self.failure = failure } public var isCreatingAccount: Bool + public var failure: String? } public enum WelcomeAction: Equatable { @@ -22,15 +26,18 @@ public enum WelcomeAction: Equatable { public struct WelcomeEnvironment { public init( messenger: Messenger, + dbManager: DBManager, mainQueue: AnySchedulerOf<DispatchQueue>, bgQueue: AnySchedulerOf<DispatchQueue> ) { self.messenger = messenger + self.dbManager = dbManager self.mainQueue = mainQueue self.bgQueue = bgQueue } public var messenger: Messenger + public var dbManager: DBManager public var mainQueue: AnySchedulerOf<DispatchQueue> public var bgQueue: AnySchedulerOf<DispatchQueue> } @@ -38,6 +45,7 @@ public struct WelcomeEnvironment { extension WelcomeEnvironment { public static let unimplemented = WelcomeEnvironment( messenger: .unimplemented, + dbManager: .unimplemented, mainQueue: .unimplemented, bgQueue: .unimplemented ) @@ -48,8 +56,10 @@ public let welcomeReducer = Reducer<WelcomeState, WelcomeAction, WelcomeEnvironm switch action { case .newAccountTapped: state.isCreatingAccount = true + state.failure = nil return .future { fulfill in do { + try env.dbManager.removeDB() try env.messenger.create() fulfill(.success(.finished)) } @@ -66,10 +76,12 @@ public let welcomeReducer = Reducer<WelcomeState, WelcomeAction, WelcomeEnvironm case .finished: state.isCreatingAccount = false + state.failure = nil return .none - case .failed(_): + case .failed(let failure): state.isCreatingAccount = false + state.failure = failure return .none } } diff --git a/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeView.swift b/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeView.swift index 32312386644b0331d069a386e337f17b4003d41c..0050a572f08f565a88ef3581ddc464503151c260 100644 --- a/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeView.swift +++ b/Examples/xx-messenger/Sources/WelcomeFeature/WelcomeView.swift @@ -11,9 +11,11 @@ public struct WelcomeView: View { struct ViewState: Equatable { init(_ state: WelcomeState) { isCreatingAccount = state.isCreatingAccount + failure = state.failure } var isCreatingAccount: Bool + var failure: String? } public var body: some View { @@ -24,6 +26,14 @@ public struct WelcomeView: View { Text("xx messenger") } + if let failure = viewStore.failure { + Section { + Text(failure) + } header: { + Text("Error") + } + } + Section { Button { viewStore.send(.newAccountTapped) diff --git a/Examples/xx-messenger/Tests/WelcomeFeatureTests/WelcomeFeatureTests.swift b/Examples/xx-messenger/Tests/WelcomeFeatureTests/WelcomeFeatureTests.swift index eb6b08566af0f4193c10b5167271bd86b2897330..160e8e13bb3d8694b10e2ee16fb6dee1f9371ff4 100644 --- a/Examples/xx-messenger/Tests/WelcomeFeatureTests/WelcomeFeatureTests.swift +++ b/Examples/xx-messenger/Tests/WelcomeFeatureTests/WelcomeFeatureTests.swift @@ -13,52 +13,97 @@ final class WelcomeFeatureTests: XCTestCase { let mainQueue = DispatchQueue.test let bgQueue = DispatchQueue.test - var messengerDidCreate = false + + enum Action: Equatable { + case didCreateMessenger + case didRemoveDB + } + var actions: [Action] = [] store.environment.mainQueue = mainQueue.eraseToAnyScheduler() store.environment.bgQueue = bgQueue.eraseToAnyScheduler() - store.environment.messenger.create.run = { messengerDidCreate = true } + store.environment.messenger.create.run = { actions.append(.didCreateMessenger) } + store.environment.dbManager.removeDB.run = { actions.append(.didRemoveDB) } store.send(.newAccountTapped) { $0.isCreatingAccount = true + $0.failure = nil } bgQueue.advance() - XCTAssertTrue(messengerDidCreate) + XCTAssertNoDifference(actions, [ + .didRemoveDB, + .didCreateMessenger + ]) mainQueue.advance() store.receive(.finished) { $0.isCreatingAccount = false + $0.failure = nil } } func testNewAccountTappedMessengerCreateFailure() { + struct Failure: Error {} + let failure = Failure() + let mainQueue = DispatchQueue.test + let bgQueue = DispatchQueue.test + let store = TestStore( initialState: WelcomeState(), reducer: welcomeReducer, environment: .unimplemented ) + store.environment.mainQueue = mainQueue.eraseToAnyScheduler() + store.environment.bgQueue = bgQueue.eraseToAnyScheduler() + store.environment.messenger.create.run = { throw failure } + store.environment.dbManager.removeDB.run = {} + + store.send(.newAccountTapped) { + $0.isCreatingAccount = true + $0.failure = nil + } + + bgQueue.advance() + mainQueue.advance() + + store.receive(.failed(failure.localizedDescription)) { + $0.isCreatingAccount = false + $0.failure = failure.localizedDescription + } + } + + func testNewAccountTappedRemoveDBFailure() { + struct Failure: Error, Equatable {} + let failure = Failure() let mainQueue = DispatchQueue.test let bgQueue = DispatchQueue.test - struct Error: Swift.Error, Equatable {} - let error = Error() + + let store = TestStore( + initialState: WelcomeState(), + reducer: welcomeReducer, + environment: .unimplemented + ) store.environment.mainQueue = mainQueue.eraseToAnyScheduler() store.environment.bgQueue = bgQueue.eraseToAnyScheduler() - store.environment.messenger.create.run = { throw error } + store.environment.messenger.create.run = {} + store.environment.dbManager.removeDB.run = { throw failure } store.send(.newAccountTapped) { $0.isCreatingAccount = true + $0.failure = nil } bgQueue.advance() mainQueue.advance() - store.receive(.failed(error.localizedDescription)) { + store.receive(.failed(failure.localizedDescription)) { $0.isCreatingAccount = false + $0.failure = failure.localizedDescription } }