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

Implement lookup

parent 89c7eab8
No related branches found
No related tags found
2 merge requests!112Restore contacts from backup,!102Release 1.0.0
This commit is part of merge request !112. Comments created here will be created in the context of that merge request.
...@@ -4,6 +4,7 @@ import ChatFeature ...@@ -4,6 +4,7 @@ import ChatFeature
import CheckContactAuthFeature import CheckContactAuthFeature
import ConfirmRequestFeature import ConfirmRequestFeature
import ContactFeature import ContactFeature
import ContactLookupFeature
import ContactsFeature import ContactsFeature
import Foundation import Foundation
import HomeFeature import HomeFeature
...@@ -38,7 +39,11 @@ extension AppEnvironment { ...@@ -38,7 +39,11 @@ extension AppEnvironment {
mainQueue: mainQueue, mainQueue: mainQueue,
bgQueue: bgQueue, bgQueue: bgQueue,
lookup: { lookup: {
ContactLookupEnvironment() ContactLookupEnvironment(
messenger: messenger,
mainQueue: mainQueue,
bgQueue: bgQueue
)
}, },
sendRequest: { sendRequest: {
SendRequestEnvironment( SendRequestEnvironment(
......
import ComposableArchitecture import ComposableArchitecture
import Foundation import Foundation
import XCTestDynamicOverlay import XCTestDynamicOverlay
import XXClient
import XXMessengerClient
public struct ContactLookupState: Equatable { public struct ContactLookupState: Equatable {
public init( public init(
id: Data, id: Data,
isLookingUp: Bool = false isLookingUp: Bool = false,
failure: String? = nil
) { ) {
self.id = id self.id = id
self.isLookingUp = isLookingUp self.isLookingUp = isLookingUp
self.failure = failure
} }
public var id: Data public var id: Data
public var isLookingUp: Bool public var isLookingUp: Bool
public var failure: String?
} }
public enum ContactLookupAction: Equatable { public enum ContactLookupAction: Equatable {
case task
case cancelTask
case lookupTapped case lookupTapped
case didLookup(XXClient.Contact)
case didFail(NSError)
} }
public struct ContactLookupEnvironment { public struct ContactLookupEnvironment {
public init() {} public init(
messenger: Messenger,
mainQueue: AnySchedulerOf<DispatchQueue>,
bgQueue: AnySchedulerOf<DispatchQueue>
) {
self.messenger = messenger
self.mainQueue = mainQueue
self.bgQueue = bgQueue
}
public var messenger: Messenger
public var mainQueue: AnySchedulerOf<DispatchQueue>
public var bgQueue: AnySchedulerOf<DispatchQueue>
} }
#if DEBUG #if DEBUG
extension ContactLookupEnvironment { extension ContactLookupEnvironment {
public static let unimplemented = ContactLookupEnvironment() public static let unimplemented = ContactLookupEnvironment(
messenger: .unimplemented,
mainQueue: .unimplemented,
bgQueue: .unimplemented
)
} }
#endif #endif
public let contactLookupReducer = Reducer<ContactLookupState, ContactLookupAction, ContactLookupEnvironment> public let contactLookupReducer = Reducer<ContactLookupState, ContactLookupAction, ContactLookupEnvironment>
{ state, action, env in { state, action, env in
switch action { switch action {
case .task: case .lookupTapped:
return .none state.isLookingUp = true
return Effect.result { [state] in
do {
let contact = try env.messenger.lookupContact(id: state.id)
return .success(.didLookup(contact))
} catch {
return .success(.didFail(error as NSError))
}
}
.subscribe(on: env.bgQueue)
.receive(on: env.mainQueue)
.eraseToEffect()
case .cancelTask: case .didLookup(_):
state.isLookingUp = false
return .none return .none
case .lookupTapped: case .didFail(let error):
state.failure = error.localizedDescription
state.isLookingUp = false
return .none return .none
} }
} }
...@@ -45,9 +45,6 @@ public struct ContactLookupView: View { ...@@ -45,9 +45,6 @@ public struct ContactLookupView: View {
} }
} }
.navigationTitle("Lookup") .navigationTitle("Lookup")
.task {
await viewStore.send(.task).finish()
}
} }
} }
} }
......
import ComposableArchitecture import ComposableArchitecture
import XCTest import XCTest
import XXClient
@testable import ContactLookupFeature @testable import ContactLookupFeature
final class ContactLookupFeatureTests: XCTestCase { final class ContactLookupFeatureTests: XCTestCase {
func testTask() { func testLookup() {
let id: Data = "1234".data(using: .utf8)!
var didLookupId: [Data] = []
let lookedUpContact = Contact.unimplemented("123data".data(using: .utf8)!)
let store = TestStore( let store = TestStore(
initialState: ContactLookupState( initialState: ContactLookupState(id: id),
id: "1234".data(using: .utf8)!
),
reducer: contactLookupReducer, reducer: contactLookupReducer,
environment: .unimplemented environment: .unimplemented
) )
store.environment.mainQueue = .immediate
store.environment.bgQueue = .immediate
store.environment.messenger.lookupContact.run = { id in
didLookupId.append(id)
return lookedUpContact
}
store.send(.lookupTapped) {
$0.isLookingUp = true
}
store.send(.task) XCTAssertEqual(didLookupId, [id])
store.send(.cancelTask) store.receive(.didLookup(lookedUpContact)) {
$0.isLookingUp = false
}
} }
func testLookup() { func testLookupFailure() {
let id: Data = "1234".data(using: .utf8)!
let failure = NSError(domain: "test", code: 0)
let store = TestStore( let store = TestStore(
initialState: ContactLookupState( initialState: ContactLookupState(id: id),
id: "1234".data(using: .utf8)!
),
reducer: contactLookupReducer, reducer: contactLookupReducer,
environment: .unimplemented environment: .unimplemented
) )
store.environment.mainQueue = .immediate
store.environment.bgQueue = .immediate
store.environment.messenger.lookupContact.run = { _ in throw failure }
store.send(.lookupTapped) {
$0.isLookingUp = true
}
store.send(.lookupTapped) store.receive(.didFail(failure)) {
$0.failure = failure.localizedDescription
$0.isLookingUp = false
}
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment