Skip to content
Snippets Groups Projects
Commit a8031c07 authored by Dariusz Rybicki's avatar Dariusz Rybicki
Browse files

Migrate CheckContactAuthFeature to ReducerProtocol

parent 551df629
No related branches found
No related tags found
2 merge requests!126Migrate example app to ComposableArchitecture's ReducerProtocol,!102Release 1.0.0
import AppCore
import ComposableArchitecture
import Foundation
import XCTestDynamicOverlay
import XXClient
import XXMessengerClient
import XXModels
public struct CheckContactAuthComponent: ReducerProtocol {
public struct State: Equatable {
public enum Result: Equatable {
case success(Bool)
case failure(String)
}
public init(
contact: XXClient.Contact,
isChecking: Bool = false,
result: Result? = nil
) {
self.contact = contact
self.isChecking = isChecking
self.result = result
}
public var contact: XXClient.Contact
public var isChecking: Bool
public var result: Result?
}
public enum Action: Equatable {
case checkTapped
case didCheck(State.Result)
}
@Dependency(\.app.messenger) var messenger: Messenger
@Dependency(\.app.dbManager.getDB) var db: DBManagerGetDB
@Dependency(\.app.mainQueue) var mainQueue: AnySchedulerOf<DispatchQueue>
@Dependency(\.app.bgQueue) var bgQueue: AnySchedulerOf<DispatchQueue>
public init() {}
public func reduce(into state: inout State, action: Action) -> EffectTask<Action> {
switch action {
case .checkTapped:
state.isChecking = true
state.result = nil
return Effect.result { [state] in
do {
let e2e = try messenger.e2e.tryGet()
let contactId = try state.contact.getId()
let result = try e2e.hasAuthenticatedChannel(partnerId: contactId)
try db().bulkUpdateContacts.callAsFunction(
.init(id: [contactId]),
.init(authStatus: result ? .friend : .stranger)
)
return .success(.didCheck(.success(result)))
} catch {
return .success(.didCheck(.failure(error.localizedDescription)))
}
}
.subscribe(on: bgQueue)
.receive(on: mainQueue)
.eraseToEffect()
case .didCheck(let result):
state.isChecking = false
state.result = result
return .none
}
}
}
import AppCore
import ComposableArchitecture
import Foundation
import XCTestDynamicOverlay
import XXClient
import XXMessengerClient
import XXModels
public struct CheckContactAuthState: Equatable {
public enum Result: Equatable {
case success(Bool)
case failure(String)
}
public init(
contact: XXClient.Contact,
isChecking: Bool = false,
result: Result? = nil
) {
self.contact = contact
self.isChecking = isChecking
self.result = result
}
public var contact: XXClient.Contact
public var isChecking: Bool
public var result: Result?
}
public enum CheckContactAuthAction: Equatable {
case checkTapped
case didCheck(CheckContactAuthState.Result)
}
public struct CheckContactAuthEnvironment {
public init(
messenger: Messenger,
db: DBManagerGetDB,
mainQueue: AnySchedulerOf<DispatchQueue>,
bgQueue: AnySchedulerOf<DispatchQueue>
) {
self.messenger = messenger
self.db = db
self.mainQueue = mainQueue
self.bgQueue = bgQueue
}
public var messenger: Messenger
public var db: DBManagerGetDB
public var mainQueue: AnySchedulerOf<DispatchQueue>
public var bgQueue: AnySchedulerOf<DispatchQueue>
}
#if DEBUG
extension CheckContactAuthEnvironment {
public static let unimplemented = CheckContactAuthEnvironment(
messenger: .unimplemented,
db: .unimplemented,
mainQueue: .unimplemented,
bgQueue: .unimplemented
)
}
#endif
public let checkContactAuthReducer = Reducer<CheckContactAuthState, CheckContactAuthAction, CheckContactAuthEnvironment>
{ state, action, env in
switch action {
case .checkTapped:
state.isChecking = true
state.result = nil
return Effect.result { [state] in
do {
let e2e = try env.messenger.e2e.tryGet()
let contactId = try state.contact.getId()
let result = try e2e.hasAuthenticatedChannel(partnerId: contactId)
try env.db().bulkUpdateContacts.callAsFunction(
.init(id: [contactId]),
.init(authStatus: result ? .friend : .stranger)
)
return .success(.didCheck(.success(result)))
} catch {
return .success(.didCheck(.failure(error.localizedDescription)))
}
}
.subscribe(on: env.bgQueue)
.receive(on: env.mainQueue)
.eraseToEffect()
case .didCheck(let result):
state.isChecking = false
state.result = result
return .none
}
}
...@@ -3,20 +3,20 @@ import SwiftUI ...@@ -3,20 +3,20 @@ import SwiftUI
import XXClient import XXClient
public struct CheckContactAuthView: View { public struct CheckContactAuthView: View {
public init(store: Store<CheckContactAuthState, CheckContactAuthAction>) { public init(store: StoreOf<CheckContactAuthComponent>) {
self.store = store self.store = store
} }
let store: Store<CheckContactAuthState, CheckContactAuthAction> let store: StoreOf<CheckContactAuthComponent>
struct ViewState: Equatable { struct ViewState: Equatable {
var username: String? var username: String?
var email: String? var email: String?
var phone: String? var phone: String?
var isChecking: Bool var isChecking: Bool
var result: CheckContactAuthState.Result? var result: CheckContactAuthComponent.State.Result?
init(state: CheckContactAuthState) { init(state: CheckContactAuthComponent.State) {
username = try? state.contact.getFact(.username)?.value username = try? state.contact.getFact(.username)?.value
email = try? state.contact.getFact(.email)?.value email = try? state.contact.getFact(.email)?.value
phone = try? state.contact.getFact(.phone)?.value phone = try? state.contact.getFact(.phone)?.value
...@@ -90,11 +90,10 @@ public struct CheckContactAuthView: View { ...@@ -90,11 +90,10 @@ public struct CheckContactAuthView: View {
public struct CheckContactAuthView_Previews: PreviewProvider { public struct CheckContactAuthView_Previews: PreviewProvider {
public static var previews: some View { public static var previews: some View {
CheckContactAuthView(store: Store( CheckContactAuthView(store: Store(
initialState: CheckContactAuthState( initialState: CheckContactAuthComponent.State(
contact: .unimplemented("contact-data".data(using: .utf8)!) contact: .unimplemented("contact-data".data(using: .utf8)!)
), ),
reducer: .empty, reducer: EmptyReducer()
environment: ()
)) ))
} }
} }
......
...@@ -5,27 +5,26 @@ import XXClient ...@@ -5,27 +5,26 @@ import XXClient
import XXModels import XXModels
@testable import CheckContactAuthFeature @testable import CheckContactAuthFeature
final class CheckContactAuthFeatureTests: XCTestCase { final class CheckContactAuthComponentTests: XCTestCase {
func testCheck() { func testCheck() {
var contact = XXClient.Contact.unimplemented("contact-data".data(using: .utf8)!) var contact = XXClient.Contact.unimplemented("contact-data".data(using: .utf8)!)
let contactId = "contact-id".data(using: .utf8)! let contactId = "contact-id".data(using: .utf8)!
contact.getIdFromContact.run = { _ in contactId } contact.getIdFromContact.run = { _ in contactId }
let store = TestStore( let store = TestStore(
initialState: CheckContactAuthState( initialState: CheckContactAuthComponent.State(
contact: contact contact: contact
), ),
reducer: checkContactAuthReducer, reducer: CheckContactAuthComponent()
environment: .unimplemented
) )
var didCheckPartnerId: [Data] = [] var didCheckPartnerId: [Data] = []
var didBulkUpdateContactsWithQuery: [XXModels.Contact.Query] = [] var didBulkUpdateContactsWithQuery: [XXModels.Contact.Query] = []
var didBulkUpdateContactsWithAssignments: [XXModels.Contact.Assignments] = [] var didBulkUpdateContactsWithAssignments: [XXModels.Contact.Assignments] = []
store.environment.mainQueue = .immediate store.dependencies.app.mainQueue = .immediate
store.environment.bgQueue = .immediate store.dependencies.app.bgQueue = .immediate
store.environment.messenger.e2e.get = { store.dependencies.app.messenger.e2e.get = {
var e2e: E2E = .unimplemented var e2e: E2E = .unimplemented
e2e.hasAuthenticatedChannel.run = { partnerId in e2e.hasAuthenticatedChannel.run = { partnerId in
didCheckPartnerId.append(partnerId) didCheckPartnerId.append(partnerId)
...@@ -33,7 +32,7 @@ final class CheckContactAuthFeatureTests: XCTestCase { ...@@ -33,7 +32,7 @@ final class CheckContactAuthFeatureTests: XCTestCase {
} }
return e2e return e2e
} }
store.environment.db.run = { store.dependencies.app.dbManager.getDB.run = {
var db: Database = .unimplemented var db: Database = .unimplemented
db.bulkUpdateContacts.run = { query, assignments in db.bulkUpdateContacts.run = { query, assignments in
didBulkUpdateContactsWithQuery.append(query) didBulkUpdateContactsWithQuery.append(query)
...@@ -64,20 +63,19 @@ final class CheckContactAuthFeatureTests: XCTestCase { ...@@ -64,20 +63,19 @@ final class CheckContactAuthFeatureTests: XCTestCase {
contact.getIdFromContact.run = { _ in contactId } contact.getIdFromContact.run = { _ in contactId }
let store = TestStore( let store = TestStore(
initialState: CheckContactAuthState( initialState: CheckContactAuthComponent.State(
contact: contact contact: contact
), ),
reducer: checkContactAuthReducer, reducer: CheckContactAuthComponent()
environment: .unimplemented
) )
var didCheckPartnerId: [Data] = [] var didCheckPartnerId: [Data] = []
var didBulkUpdateContactsWithQuery: [XXModels.Contact.Query] = [] var didBulkUpdateContactsWithQuery: [XXModels.Contact.Query] = []
var didBulkUpdateContactsWithAssignments: [XXModels.Contact.Assignments] = [] var didBulkUpdateContactsWithAssignments: [XXModels.Contact.Assignments] = []
store.environment.mainQueue = .immediate store.dependencies.app.mainQueue = .immediate
store.environment.bgQueue = .immediate store.dependencies.app.bgQueue = .immediate
store.environment.messenger.e2e.get = { store.dependencies.app.messenger.e2e.get = {
var e2e: E2E = .unimplemented var e2e: E2E = .unimplemented
e2e.hasAuthenticatedChannel.run = { partnerId in e2e.hasAuthenticatedChannel.run = { partnerId in
didCheckPartnerId.append(partnerId) didCheckPartnerId.append(partnerId)
...@@ -85,7 +83,7 @@ final class CheckContactAuthFeatureTests: XCTestCase { ...@@ -85,7 +83,7 @@ final class CheckContactAuthFeatureTests: XCTestCase {
} }
return e2e return e2e
} }
store.environment.db.run = { store.dependencies.app.dbManager.getDB.run = {
var db: Database = .unimplemented var db: Database = .unimplemented
db.bulkUpdateContacts.run = { query, assignments in db.bulkUpdateContacts.run = { query, assignments in
didBulkUpdateContactsWithQuery.append(query) didBulkUpdateContactsWithQuery.append(query)
...@@ -116,19 +114,18 @@ final class CheckContactAuthFeatureTests: XCTestCase { ...@@ -116,19 +114,18 @@ final class CheckContactAuthFeatureTests: XCTestCase {
contact.getIdFromContact.run = { _ in contactId } contact.getIdFromContact.run = { _ in contactId }
let store = TestStore( let store = TestStore(
initialState: CheckContactAuthState( initialState: CheckContactAuthComponent.State(
contact: contact contact: contact
), ),
reducer: checkContactAuthReducer, reducer: CheckContactAuthComponent()
environment: .unimplemented
) )
struct Failure: Error {} struct Failure: Error {}
let error = Failure() let error = Failure()
store.environment.mainQueue = .immediate store.dependencies.app.mainQueue = .immediate
store.environment.bgQueue = .immediate store.dependencies.app.bgQueue = .immediate
store.environment.messenger.e2e.get = { store.dependencies.app.messenger.e2e.get = {
var e2e: E2E = .unimplemented var e2e: E2E = .unimplemented
e2e.hasAuthenticatedChannel.run = { _ in throw error } e2e.hasAuthenticatedChannel.run = { _ in throw error }
return e2e return e2e
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment