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

Migrate ContactFeature to ReducerProtocol

parent c039bb0a
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 ChatFeature
import CheckContactAuthFeature
import ComposableArchitecture
import ComposablePresentation
import ConfirmRequestFeature
import ContactLookupFeature
import Foundation
import ResetAuthFeature
import SendRequestFeature
import VerifyContactFeature
import XCTestDynamicOverlay
import XXClient
import XXMessengerClient
import XXModels
public struct ContactComponent: ReducerProtocol {
public struct State: Equatable {
public init(
id: Data,
dbContact: XXModels.Contact? = nil,
xxContact: XXClient.Contact? = nil,
importUsername: Bool = true,
importEmail: Bool = true,
importPhone: Bool = true,
lookup: ContactLookupComponent.State? = nil,
sendRequest: SendRequestComponent.State? = nil,
verifyContact: VerifyContactComponent.State? = nil,
confirmRequest: ConfirmRequestComponent.State? = nil,
checkAuth: CheckContactAuthComponent.State? = nil,
resetAuth: ResetAuthComponent.State? = nil,
chat: ChatComponent.State? = nil
) {
self.id = id
self.dbContact = dbContact
self.xxContact = xxContact
self.importUsername = importUsername
self.importEmail = importEmail
self.importPhone = importPhone
self.lookup = lookup
self.sendRequest = sendRequest
self.verifyContact = verifyContact
self.confirmRequest = confirmRequest
self.checkAuth = checkAuth
self.resetAuth = resetAuth
self.chat = chat
}
public var id: Data
public var dbContact: XXModels.Contact?
public var xxContact: XXClient.Contact?
@BindableState public var importUsername: Bool
@BindableState public var importEmail: Bool
@BindableState public var importPhone: Bool
public var lookup: ContactLookupComponent.State?
public var sendRequest: SendRequestComponent.State?
public var verifyContact: VerifyContactComponent.State?
public var confirmRequest: ConfirmRequestComponent.State?
public var checkAuth: CheckContactAuthComponent.State?
public var resetAuth: ResetAuthComponent.State?
public var chat: ChatComponent.State?
}
public enum Action: Equatable, BindableAction {
case start
case dbContactFetched(XXModels.Contact?)
case importFactsTapped
case lookupTapped
case lookupDismissed
case lookup(ContactLookupComponent.Action)
case sendRequestTapped
case sendRequestDismissed
case sendRequest(SendRequestComponent.Action)
case verifyContactTapped
case verifyContactDismissed
case verifyContact(VerifyContactComponent.Action)
case checkAuthTapped
case checkAuthDismissed
case checkAuth(CheckContactAuthComponent.Action)
case confirmRequestTapped
case confirmRequestDismissed
case confirmRequest(ConfirmRequestComponent.Action)
case resetAuthTapped
case resetAuthDismissed
case resetAuth(ResetAuthComponent.Action)
case chatTapped
case chatDismissed
case chat(ChatComponent.Action)
case binding(BindingAction<State>)
}
public init() {}
@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 var body: some ReducerProtocol<State, Action> {
BindingReducer()
Reduce { state, action in
enum DBFetchEffectID {}
switch action {
case .start:
return try! db().fetchContactsPublisher(.init(id: [state.id]))
.assertNoFailure()
.map(\.first)
.map(Action.dbContactFetched)
.subscribe(on: bgQueue)
.receive(on: mainQueue)
.eraseToEffect()
.cancellable(id: DBFetchEffectID.self, cancelInFlight: true)
case .dbContactFetched(let contact):
state.dbContact = contact
return .none
case .importFactsTapped:
guard let xxContact = state.xxContact else { return .none }
return .fireAndForget { [state] in
var dbContact = state.dbContact ?? XXModels.Contact(id: state.id)
dbContact.marshaled = xxContact.data
if state.importUsername {
dbContact.username = try? xxContact.getFact(.username)?.value
}
if state.importEmail {
dbContact.email = try? xxContact.getFact(.email)?.value
}
if state.importPhone {
dbContact.phone = try? xxContact.getFact(.phone)?.value
}
_ = try! db().saveContact(dbContact)
}
.subscribe(on: bgQueue)
.receive(on: mainQueue)
.eraseToEffect()
case .lookupTapped:
state.lookup = ContactLookupComponent.State(id: state.id)
return .none
case .lookupDismissed:
state.lookup = nil
return .none
case .lookup(.didLookup(let xxContact)):
state.xxContact = xxContact
state.lookup = nil
return .none
case .sendRequestTapped:
if let xxContact = state.xxContact {
state.sendRequest = SendRequestComponent.State(contact: xxContact)
} else if let marshaled = state.dbContact?.marshaled {
state.sendRequest = SendRequestComponent.State(contact: .live(marshaled))
}
return .none
case .sendRequestDismissed:
state.sendRequest = nil
return .none
case .sendRequest(.sendSucceeded):
state.sendRequest = nil
return .none
case .verifyContactTapped:
if let marshaled = state.dbContact?.marshaled {
state.verifyContact = VerifyContactComponent.State(
contact: .live(marshaled)
)
}
return .none
case .verifyContactDismissed:
state.verifyContact = nil
return .none
case .checkAuthTapped:
if let marshaled = state.dbContact?.marshaled {
state.checkAuth = CheckContactAuthComponent.State(
contact: .live(marshaled)
)
}
return .none
case .checkAuthDismissed:
state.checkAuth = nil
return .none
case .confirmRequestTapped:
if let marshaled = state.dbContact?.marshaled {
state.confirmRequest = ConfirmRequestComponent.State(
contact: .live(marshaled)
)
}
return .none
case .confirmRequestDismissed:
state.confirmRequest = nil
return .none
case .chatTapped:
state.chat = ChatComponent.State(id: .contact(state.id))
return .none
case .chatDismissed:
state.chat = nil
return .none
case .resetAuthTapped:
if let marshaled = state.dbContact?.marshaled {
state.resetAuth = ResetAuthComponent.State(
partner: .live(marshaled)
)
}
return .none
case .resetAuthDismissed:
state.resetAuth = nil
return .none
case .binding(_), .lookup(_), .sendRequest(_),
.verifyContact(_), .confirmRequest(_),
.checkAuth(_), .resetAuth(_), .chat(_):
return .none
}
}
.presenting(
state: .keyPath(\.lookup),
id: .notNil(),
action: /ContactComponent.Action.lookup,
presented: { ContactLookupComponent() }
)
.presenting(
state: .keyPath(\.sendRequest),
id: .notNil(),
action: /ContactComponent.Action.sendRequest,
presented: { SendRequestComponent() }
)
.presenting(
state: .keyPath(\.verifyContact),
id: .notNil(),
action: /ContactComponent.Action.verifyContact,
presented: { VerifyContactComponent() }
)
.presenting(
state: .keyPath(\.confirmRequest),
id: .notNil(),
action: /ContactComponent.Action.confirmRequest,
presented: { ConfirmRequestComponent() }
)
.presenting(
state: .keyPath(\.checkAuth),
id: .notNil(),
action: /ContactComponent.Action.checkAuth,
presented: { CheckContactAuthComponent() }
)
.presenting(
state: .keyPath(\.resetAuth),
id: .notNil(),
action: /ContactComponent.Action.resetAuth,
presented: { ResetAuthComponent() }
)
.presenting(
state: .keyPath(\.chat),
id: .keyPath(\.?.id),
action: /ContactComponent.Action.chat,
presented: { ChatComponent() }
)
}
}
import AppCore
import ChatFeature
import CheckContactAuthFeature
import ComposableArchitecture
import ComposablePresentation
import ConfirmRequestFeature
import ContactLookupFeature
import Foundation
import ResetAuthFeature
import SendRequestFeature
import VerifyContactFeature
import XCTestDynamicOverlay
import XXClient
import XXMessengerClient
import XXModels
public struct ContactState: Equatable {
public init(
id: Data,
dbContact: XXModels.Contact? = nil,
xxContact: XXClient.Contact? = nil,
importUsername: Bool = true,
importEmail: Bool = true,
importPhone: Bool = true,
lookup: ContactLookupState? = nil,
sendRequest: SendRequestState? = nil,
verifyContact: VerifyContactState? = nil,
confirmRequest: ConfirmRequestState? = nil,
checkAuth: CheckContactAuthState? = nil,
resetAuth: ResetAuthState? = nil,
chat: ChatState? = nil
) {
self.id = id
self.dbContact = dbContact
self.xxContact = xxContact
self.importUsername = importUsername
self.importEmail = importEmail
self.importPhone = importPhone
self.lookup = lookup
self.sendRequest = sendRequest
self.verifyContact = verifyContact
self.confirmRequest = confirmRequest
self.checkAuth = checkAuth
self.resetAuth = resetAuth
self.chat = chat
}
public var id: Data
public var dbContact: XXModels.Contact?
public var xxContact: XXClient.Contact?
@BindableState public var importUsername: Bool
@BindableState public var importEmail: Bool
@BindableState public var importPhone: Bool
public var lookup: ContactLookupState?
public var sendRequest: SendRequestState?
public var verifyContact: VerifyContactState?
public var confirmRequest: ConfirmRequestState?
public var checkAuth: CheckContactAuthState?
public var resetAuth: ResetAuthState?
public var chat: ChatState?
}
public enum ContactAction: Equatable, BindableAction {
case start
case dbContactFetched(XXModels.Contact?)
case importFactsTapped
case lookupTapped
case lookupDismissed
case lookup(ContactLookupAction)
case sendRequestTapped
case sendRequestDismissed
case sendRequest(SendRequestAction)
case verifyContactTapped
case verifyContactDismissed
case verifyContact(VerifyContactAction)
case checkAuthTapped
case checkAuthDismissed
case checkAuth(CheckContactAuthAction)
case confirmRequestTapped
case confirmRequestDismissed
case confirmRequest(ConfirmRequestAction)
case resetAuthTapped
case resetAuthDismissed
case resetAuth(ResetAuthAction)
case chatTapped
case chatDismissed
case chat(ChatAction)
case binding(BindingAction<ContactState>)
}
public struct ContactEnvironment {
public init(
messenger: Messenger,
db: DBManagerGetDB,
mainQueue: AnySchedulerOf<DispatchQueue>,
bgQueue: AnySchedulerOf<DispatchQueue>,
lookup: @escaping () -> ContactLookupEnvironment,
sendRequest: @escaping () -> SendRequestEnvironment,
verifyContact: @escaping () -> VerifyContactEnvironment,
confirmRequest: @escaping () -> ConfirmRequestEnvironment,
checkAuth: @escaping () -> CheckContactAuthEnvironment,
resetAuth: @escaping () -> ResetAuthEnvironment,
chat: @escaping () -> ChatEnvironment
) {
self.messenger = messenger
self.db = db
self.mainQueue = mainQueue
self.bgQueue = bgQueue
self.lookup = lookup
self.sendRequest = sendRequest
self.verifyContact = verifyContact
self.confirmRequest = confirmRequest
self.checkAuth = checkAuth
self.resetAuth = resetAuth
self.chat = chat
}
public var messenger: Messenger
public var db: DBManagerGetDB
public var mainQueue: AnySchedulerOf<DispatchQueue>
public var bgQueue: AnySchedulerOf<DispatchQueue>
public var lookup: () -> ContactLookupEnvironment
public var sendRequest: () -> SendRequestEnvironment
public var verifyContact: () -> VerifyContactEnvironment
public var confirmRequest: () -> ConfirmRequestEnvironment
public var checkAuth: () -> CheckContactAuthEnvironment
public var resetAuth: () -> ResetAuthEnvironment
public var chat: () -> ChatEnvironment
}
#if DEBUG
extension ContactEnvironment {
public static let unimplemented = ContactEnvironment(
messenger: .unimplemented,
db: .unimplemented,
mainQueue: .unimplemented,
bgQueue: .unimplemented,
lookup: { .unimplemented },
sendRequest: { .unimplemented },
verifyContact: { .unimplemented },
confirmRequest: { .unimplemented },
checkAuth: { .unimplemented },
resetAuth: { .unimplemented },
chat: { .unimplemented }
)
}
#endif
public let contactReducer = Reducer<ContactState, ContactAction, ContactEnvironment>
{ state, action, env in
enum DBFetchEffectID {}
switch action {
case .start:
return try! env.db().fetchContactsPublisher(.init(id: [state.id]))
.assertNoFailure()
.map(\.first)
.map(ContactAction.dbContactFetched)
.subscribe(on: env.bgQueue)
.receive(on: env.mainQueue)
.eraseToEffect()
.cancellable(id: DBFetchEffectID.self, cancelInFlight: true)
case .dbContactFetched(let contact):
state.dbContact = contact
return .none
case .importFactsTapped:
guard let xxContact = state.xxContact else { return .none }
return .fireAndForget { [state] in
var dbContact = state.dbContact ?? XXModels.Contact(id: state.id)
dbContact.marshaled = xxContact.data
if state.importUsername {
dbContact.username = try? xxContact.getFact(.username)?.value
}
if state.importEmail {
dbContact.email = try? xxContact.getFact(.email)?.value
}
if state.importPhone {
dbContact.phone = try? xxContact.getFact(.phone)?.value
}
_ = try! env.db().saveContact(dbContact)
}
.subscribe(on: env.bgQueue)
.receive(on: env.mainQueue)
.eraseToEffect()
case .lookupTapped:
state.lookup = ContactLookupState(id: state.id)
return .none
case .lookupDismissed:
state.lookup = nil
return .none
case .lookup(.didLookup(let xxContact)):
state.xxContact = xxContact
state.lookup = nil
return .none
case .sendRequestTapped:
if let xxContact = state.xxContact {
state.sendRequest = SendRequestState(contact: xxContact)
} else if let marshaled = state.dbContact?.marshaled {
state.sendRequest = SendRequestState(contact: .live(marshaled))
}
return .none
case .sendRequestDismissed:
state.sendRequest = nil
return .none
case .sendRequest(.sendSucceeded):
state.sendRequest = nil
return .none
case .verifyContactTapped:
if let marshaled = state.dbContact?.marshaled {
state.verifyContact = VerifyContactState(
contact: .live(marshaled)
)
}
return .none
case .verifyContactDismissed:
state.verifyContact = nil
return .none
case .checkAuthTapped:
if let marshaled = state.dbContact?.marshaled {
state.checkAuth = CheckContactAuthState(
contact: .live(marshaled)
)
}
return .none
case .checkAuthDismissed:
state.checkAuth = nil
return .none
case .confirmRequestTapped:
if let marshaled = state.dbContact?.marshaled {
state.confirmRequest = ConfirmRequestState(
contact: .live(marshaled)
)
}
return .none
case .confirmRequestDismissed:
state.confirmRequest = nil
return .none
case .chatTapped:
state.chat = ChatState(id: .contact(state.id))
return .none
case .chatDismissed:
state.chat = nil
return .none
case .resetAuthTapped:
if let marshaled = state.dbContact?.marshaled {
state.resetAuth = ResetAuthState(
partner: .live(marshaled)
)
}
return .none
case .resetAuthDismissed:
state.resetAuth = nil
return .none
case .binding(_), .lookup(_), .sendRequest(_),
.verifyContact(_), .confirmRequest(_),
.checkAuth(_), .resetAuth(_), .chat(_):
return .none
}
}
.binding()
.presenting(
contactLookupReducer,
state: .keyPath(\.lookup),
id: .notNil(),
action: /ContactAction.lookup,
environment: { $0.lookup() }
)
.presenting(
sendRequestReducer,
state: .keyPath(\.sendRequest),
id: .notNil(),
action: /ContactAction.sendRequest,
environment: { $0.sendRequest() }
)
.presenting(
verifyContactReducer,
state: .keyPath(\.verifyContact),
id: .notNil(),
action: /ContactAction.verifyContact,
environment: { $0.verifyContact() }
)
.presenting(
confirmRequestReducer,
state: .keyPath(\.confirmRequest),
id: .notNil(),
action: /ContactAction.confirmRequest,
environment: { $0.confirmRequest() }
)
.presenting(
checkContactAuthReducer,
state: .keyPath(\.checkAuth),
id: .notNil(),
action: /ContactAction.checkAuth,
environment: { $0.checkAuth() }
)
.presenting(
resetAuthReducer,
state: .keyPath(\.resetAuth),
id: .notNil(),
action: /ContactAction.resetAuth,
environment: { $0.resetAuth() }
)
.presenting(
chatReducer,
state: .keyPath(\.chat),
id: .keyPath(\.?.id),
action: /ContactAction.chat,
environment: { $0.chat() }
)
......@@ -13,11 +13,11 @@ import XXClient
import XXModels
public struct ContactView: View {
public init(store: Store<ContactState, ContactAction>) {
public init(store: StoreOf<ContactComponent>) {
self.store = store
}
let store: Store<ContactState, ContactAction>
let store: StoreOf<ContactComponent>
struct ViewState: Equatable {
var dbContact: XXModels.Contact?
......@@ -35,7 +35,7 @@ public struct ContactView: View {
var canCheckAuthorization: Bool
var canResetAuthorization: Bool
init(state: ContactState) {
init(state: ContactComponent.State) {
dbContact = state.dbContact
xxContactIsSet = state.xxContact != nil
xxContactUsername = try? state.xxContact?.getFact(.username)?.value
......@@ -217,7 +217,7 @@ public struct ContactView: View {
.background(NavigationLinkWithStore(
store.scope(
state: \.lookup,
action: ContactAction.lookup
action: ContactComponent.Action.lookup
),
mapState: replayNonNil(),
onDeactivate: { viewStore.send(.lookupDismissed) },
......@@ -226,7 +226,7 @@ public struct ContactView: View {
.background(NavigationLinkWithStore(
store.scope(
state: \.sendRequest,
action: ContactAction.sendRequest
action: ContactComponent.Action.sendRequest
),
mapState: replayNonNil(),
onDeactivate: { viewStore.send(.sendRequestDismissed) },
......@@ -235,7 +235,7 @@ public struct ContactView: View {
.background(NavigationLinkWithStore(
store.scope(
state: \.verifyContact,
action: ContactAction.verifyContact
action: ContactComponent.Action.verifyContact
),
onDeactivate: { viewStore.send(.verifyContactDismissed) },
destination: VerifyContactView.init(store:)
......@@ -243,7 +243,7 @@ public struct ContactView: View {
.background(NavigationLinkWithStore(
store.scope(
state: \.confirmRequest,
action: ContactAction.confirmRequest
action: ContactComponent.Action.confirmRequest
),
onDeactivate: { viewStore.send(.confirmRequestDismissed) },
destination: ConfirmRequestView.init(store:)
......@@ -251,7 +251,7 @@ public struct ContactView: View {
.background(NavigationLinkWithStore(
store.scope(
state: \.checkAuth,
action: ContactAction.checkAuth
action: ContactComponent.Action.checkAuth
),
onDeactivate: { viewStore.send(.checkAuthDismissed) },
destination: CheckContactAuthView.init(store:)
......@@ -259,7 +259,7 @@ public struct ContactView: View {
.background(NavigationLinkWithStore(
store.scope(
state: \.resetAuth,
action: ContactAction.resetAuth
action: ContactComponent.Action.resetAuth
),
onDeactivate: { viewStore.send(.resetAuthDismissed) },
destination: ResetAuthView.init(store:)
......@@ -267,7 +267,7 @@ public struct ContactView: View {
.background(NavigationLinkWithStore(
store.scope(
state: \.chat,
action: ContactAction.chat
action: ContactComponent.Action.chat
),
onDeactivate: { viewStore.send(.chatDismissed) },
destination: ChatView.init(store:)
......@@ -280,11 +280,10 @@ public struct ContactView: View {
public struct ContactView_Previews: PreviewProvider {
public static var previews: some View {
ContactView(store: Store(
initialState: ContactState(
initialState: ContactComponent.State(
id: "contact-id".data(using: .utf8)!
),
reducer: .empty,
environment: ()
reducer: EmptyReducer()
))
}
}
......
......@@ -16,19 +16,18 @@ import XXModels
final class ContactFeatureTests: XCTestCase {
func testStart() {
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: "contact-id".data(using: .utf8)!
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
var dbDidFetchContacts: [XXModels.Contact.Query] = []
let dbContactsPublisher = PassthroughSubject<[XXModels.Contact], Error>()
store.environment.mainQueue = .immediate
store.environment.bgQueue = .immediate
store.environment.db.run = {
store.dependencies.app.mainQueue = .immediate
store.dependencies.app.bgQueue = .immediate
store.dependencies.app.dbManager.getDB.run = {
var db: Database = .unimplemented
db.fetchContactsPublisher.run = { query in
dbDidFetchContacts.append(query)
......@@ -68,20 +67,19 @@ final class ContactFeatureTests: XCTestCase {
}
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: "contact-id".data(using: .utf8)!,
dbContact: dbContact,
xxContact: xxContact
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
var dbDidSaveContact: [XXModels.Contact] = []
store.environment.mainQueue = .immediate
store.environment.bgQueue = .immediate
store.environment.db.run = {
store.dependencies.app.mainQueue = .immediate
store.dependencies.app.bgQueue = .immediate
store.dependencies.app.dbManager.getDB.run = {
var db: Database = .unimplemented
db.saveContact.run = { contact in
dbDidSaveContact.append(contact)
......@@ -104,27 +102,25 @@ final class ContactFeatureTests: XCTestCase {
func testLookupTapped() {
let contactId = "contact-id".data(using: .utf8)!
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: contactId
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.lookupTapped) {
$0.lookup = ContactLookupState(id: contactId)
$0.lookup = ContactLookupComponent.State(id: contactId)
}
}
func testLookupDismissed() {
let contactId = "contact-id".data(using: .utf8)!
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: contactId,
lookup: ContactLookupState(id: contactId)
lookup: ContactLookupComponent.State(id: contactId)
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.lookupDismissed) {
......@@ -136,12 +132,11 @@ final class ContactFeatureTests: XCTestCase {
let contactId = "contact-id".data(using: .utf8)!
let contact = Contact.unimplemented("contact-data".data(using: .utf8)!)
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: contactId,
lookup: ContactLookupState(id: contactId)
lookup: ContactLookupComponent.State(id: contactId)
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.lookup(.didLookup(contact))) {
......@@ -155,16 +150,15 @@ final class ContactFeatureTests: XCTestCase {
dbContact.marshaled = "contact-data".data(using: .utf8)!
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: dbContact.id,
dbContact: dbContact
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.sendRequestTapped) {
$0.sendRequest = SendRequestState(contact: .live(dbContact.marshaled!))
$0.sendRequest = SendRequestComponent.State(contact: .live(dbContact.marshaled!))
}
}
......@@ -172,29 +166,27 @@ final class ContactFeatureTests: XCTestCase {
let xxContact = XXClient.Contact.unimplemented("contact-id".data(using: .utf8)!)
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: "contact-id".data(using: .utf8)!,
xxContact: xxContact
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.sendRequestTapped) {
$0.sendRequest = SendRequestState(contact: xxContact)
$0.sendRequest = SendRequestComponent.State(contact: xxContact)
}
}
func testSendRequestDismissed() {
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: "contact-id".data(using: .utf8)!,
sendRequest: SendRequestState(
sendRequest: SendRequestComponent.State(
contact: .unimplemented("contact-id".data(using: .utf8)!)
)
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.sendRequestDismissed) {
......@@ -204,14 +196,13 @@ final class ContactFeatureTests: XCTestCase {
func testSendRequestSucceeded() {
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: "contact-id".data(using: .utf8)!,
sendRequest: SendRequestState(
sendRequest: SendRequestComponent.State(
contact: .unimplemented("contact-id".data(using: .utf8)!)
)
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.sendRequest(.sendSucceeded)) {
......@@ -222,19 +213,18 @@ final class ContactFeatureTests: XCTestCase {
func testVerifyContactTapped() {
let contactData = "contact-data".data(using: .utf8)!
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: Data(),
dbContact: XXModels.Contact(
id: Data(),
marshaled: contactData
)
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.verifyContactTapped) {
$0.verifyContact = VerifyContactState(
$0.verifyContact = VerifyContactComponent.State(
contact: .unimplemented(contactData)
)
}
......@@ -242,14 +232,13 @@ final class ContactFeatureTests: XCTestCase {
func testVerifyContactDismissed() {
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: "contact-id".data(using: .utf8)!,
verifyContact: VerifyContactState(
verifyContact: VerifyContactComponent.State(
contact: .unimplemented("contact-data".data(using: .utf8)!)
)
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.verifyContactDismissed) {
......@@ -260,19 +249,18 @@ final class ContactFeatureTests: XCTestCase {
func testCheckAuthTapped() {
let contactData = "contact-data".data(using: .utf8)!
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: Data(),
dbContact: XXModels.Contact(
id: Data(),
marshaled: contactData
)
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.checkAuthTapped) {
$0.checkAuth = CheckContactAuthState(
$0.checkAuth = CheckContactAuthComponent.State(
contact: .unimplemented(contactData)
)
}
......@@ -280,14 +268,13 @@ final class ContactFeatureTests: XCTestCase {
func testCheckAuthDismissed() {
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: "contact-id".data(using: .utf8)!,
checkAuth: CheckContactAuthState(
checkAuth: CheckContactAuthComponent.State(
contact: .unimplemented("contact-data".data(using: .utf8)!)
)
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.checkAuthDismissed) {
......@@ -298,19 +285,18 @@ final class ContactFeatureTests: XCTestCase {
func testResetAuthTapped() {
let contactData = "contact-data".data(using: .utf8)!
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: Data(),
dbContact: XXModels.Contact(
id: Data(),
marshaled: contactData
)
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.resetAuthTapped) {
$0.resetAuth = ResetAuthState(
$0.resetAuth = ResetAuthComponent.State(
partner: .unimplemented(contactData)
)
}
......@@ -318,14 +304,13 @@ final class ContactFeatureTests: XCTestCase {
func testResetAuthDismissed() {
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: Data(),
resetAuth: ResetAuthState(
resetAuth: ResetAuthComponent.State(
partner: .unimplemented(Data())
)
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.resetAuthDismissed) {
......@@ -336,19 +321,18 @@ final class ContactFeatureTests: XCTestCase {
func testConfirmRequestTapped() {
let contactData = "contact-data".data(using: .utf8)!
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: Data(),
dbContact: XXModels.Contact(
id: Data(),
marshaled: contactData
)
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.confirmRequestTapped) {
$0.confirmRequest = ConfirmRequestState(
$0.confirmRequest = ConfirmRequestComponent.State(
contact: .unimplemented(contactData)
)
}
......@@ -356,14 +340,13 @@ final class ContactFeatureTests: XCTestCase {
func testConfirmRequestDismissed() {
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: "contact-id".data(using: .utf8)!,
confirmRequest: ConfirmRequestState(
confirmRequest: ConfirmRequestComponent.State(
contact: .unimplemented("contact-data".data(using: .utf8)!)
)
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.confirmRequestDismissed) {
......@@ -374,26 +357,24 @@ final class ContactFeatureTests: XCTestCase {
func testChatTapped() {
let contactId = "contact-id".data(using: .utf8)!
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: contactId
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.chatTapped) {
$0.chat = ChatState(id: .contact(contactId))
$0.chat = ChatComponent.State(id: .contact(contactId))
}
}
func testChatDismissed() {
let store = TestStore(
initialState: ContactState(
initialState: ContactComponent.State(
id: "contact-id".data(using: .utf8)!,
chat: ChatState(id: .contact("contact-id".data(using: .utf8)!))
chat: ChatComponent.State(id: .contact("contact-id".data(using: .utf8)!))
),
reducer: contactReducer,
environment: .unimplemented
reducer: ContactComponent()
)
store.send(.chatDismissed) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment