Skip to content
Snippets Groups Projects
SendRequestFeatureTests.swift 5.2 KiB
Newer Older
import Combine
import ComposableArchitecture
Dariusz Rybicki's avatar
Dariusz Rybicki committed
import CustomDump
import XXClient
import XXMessengerClient
import XXModels
@testable import SendRequestFeature

final class SendRequestFeatureTests: XCTestCase {
  func testStart() {
    let myContact = XXClient.Contact.unimplemented("my-contact-data".data(using: .utf8)!)

    var didGetMyContact: [MessengerMyContact.IncludeFacts?] = []

    let store = TestStore(
      initialState: SendRequestState(
        contact: .unimplemented("contact-data".data(using: .utf8)!)
      ),
      reducer: sendRequestReducer,
      environment: .unimplemented
    )
    store.environment.mainQueue = .immediate
    store.environment.bgQueue = .immediate
    store.environment.messenger.myContact.run = { includeFacts in
      didGetMyContact.append(includeFacts)
      return myContact
    store.receive(.myContactFetched(myContact)) {
      $0.myContact = myContact
  func testMyContactFailure() {
    struct Failure: Error {}
    let failure = Failure()
    let store = TestStore(
      initialState: SendRequestState(
        contact: .unimplemented("contact-data".data(using: .utf8)!)
      ),
      reducer: sendRequestReducer,
      environment: .unimplemented
    )
    store.environment.mainQueue = .immediate
    store.environment.bgQueue = .immediate
    store.environment.messenger.myContact.run = { _ in throw failure }
    store.send(.start)
    store.receive(.myContactFetchFailed(failure as NSError)) {
      $0.myContact = nil
      $0.failure = failure.localizedDescription
    }
  }

  func testSendRequest() {
Dariusz Rybicki's avatar
Dariusz Rybicki committed
    var contact: XXClient.Contact = .unimplemented("contact-data".data(using: .utf8)!)
    contact.getIdFromContact.run = { _ in "contact-id".data(using: .utf8)! }

    var myContact: XXClient.Contact = .unimplemented("my-contact-data".data(using: .utf8)!)
Dariusz Rybicki's avatar
Dariusz Rybicki committed
    let myFacts = [
Dariusz Rybicki's avatar
Dariusz Rybicki committed
      Fact(type: .username, value: "my-username"),
      Fact(type: .email, value: "my-email"),
      Fact(type: .phone, value: "my-phone"),
Dariusz Rybicki's avatar
Dariusz Rybicki committed
    ]
    myContact.getFactsFromContact.run = { _ in myFacts }

    let store = TestStore(
      initialState: SendRequestState(
        contact: contact,
        myContact: myContact
      ),
      reducer: sendRequestReducer,
      environment: .unimplemented
    )

    struct DidBulkUpdateContacts: Equatable {
      var query: XXModels.Contact.Query
      var assignments: XXModels.Contact.Assignments
    }
    struct DidRequestAuthChannel: Equatable {
      var partner: XXClient.Contact
      var myFacts: [XXClient.Fact]
    }

    var didBulkUpdateContacts: [DidBulkUpdateContacts] = []
    var didRequestAuthChannel: [DidRequestAuthChannel] = []

    store.environment.mainQueue = .immediate
    store.environment.bgQueue = .immediate
    store.environment.db.run = {
      var db: Database = .unimplemented
Dariusz Rybicki's avatar
Dariusz Rybicki committed
      db.bulkUpdateContacts.run = { query, assignments in
        didBulkUpdateContacts.append(.init(query: query, assignments: assignments))
        return 0
      }
      return db
    }
    store.environment.messenger.e2e.get = {
      var e2e: E2E = .unimplemented
      e2e.requestAuthenticatedChannel.run = { partner, myFacts in
        didRequestAuthChannel.append(.init(partner: partner, myFacts: myFacts))
        return 0
      }
      return e2e
Dariusz Rybicki's avatar
Dariusz Rybicki committed
    store.send(.sendTapped) {
      $0.isSending = true
    }

    XCTAssertNoDifference(didBulkUpdateContacts, [
      .init(
        query: .init(id: ["contact-id".data(using: .utf8)!]),
        assignments: .init(authStatus: .requesting)
      ),
      .init(
        query: .init(id: ["contact-id".data(using: .utf8)!]),
        assignments: .init(authStatus: .requested)
      )
    ])

    XCTAssertNoDifference(didRequestAuthChannel, [
      .init(
        partner: contact,
        myFacts: myFacts
      )
    ])

    store.receive(.sendSucceeded) {
      $0.isSending = false
    }
  }

  func testSendRequestFailure() {
    var contact: XXClient.Contact = .unimplemented("contact-data".data(using: .utf8)!)
    contact.getIdFromContact.run = { _ in "contact-id".data(using: .utf8)! }

    var myContact: XXClient.Contact = .unimplemented("my-contact-data".data(using: .utf8)!)
    let myFacts = [
Dariusz Rybicki's avatar
Dariusz Rybicki committed
      Fact(type: .username, value: "my-username"),
      Fact(type: .email, value: "my-email"),
      Fact(type: .phone, value: "my-phone"),
Dariusz Rybicki's avatar
Dariusz Rybicki committed
    ]
    myContact.getFactsFromContact.run = { _ in myFacts }

    let store = TestStore(
      initialState: SendRequestState(
Dariusz Rybicki's avatar
Dariusz Rybicki committed
        contact: contact,
        myContact: myContact
      ),
      reducer: sendRequestReducer,
      environment: .unimplemented
    )

Dariusz Rybicki's avatar
Dariusz Rybicki committed
    struct Failure: Error {}
    let failure = Failure()

    store.environment.mainQueue = .immediate
    store.environment.bgQueue = .immediate
    store.environment.db.run = {
      var db: Database = .unimplemented
Dariusz Rybicki's avatar
Dariusz Rybicki committed
      db.bulkUpdateContacts.run = { _, _ in return 0 }
      return db
    }
    store.environment.messenger.e2e.get = {
      var e2e: E2E = .unimplemented
      e2e.requestAuthenticatedChannel.run = { _, _ in throw failure }
      return e2e
Dariusz Rybicki's avatar
Dariusz Rybicki committed
    store.send(.sendTapped) {
      $0.isSending = true
    }

    store.receive(.sendFailed(failure.localizedDescription)) {
      $0.isSending = false
      $0.failure = failure.localizedDescription
    }