| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- // Copyright 2021 Google LLC
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- import Foundation
- import Combine
- import FirebaseCore
- @testable import FirebaseFunctions
- import FirebaseFunctionsCombineSwift
- import FirebaseAuthInterop
- import FirebaseAppCheckInterop
- import FirebaseMessagingInterop
- import GTMSessionFetcherCore
- import XCTest
- // hardcoded in HTTPSCallable.swift
- private let timeoutInterval: TimeInterval = 70.0
- private let expectationTimeout: TimeInterval = 2
- class MockFunctions: Functions {
- let mockCallFunction: () throws -> HTTPSCallableResult
- var verifyParameters: ((_ name: String, _ data: Any?, _ timeout: TimeInterval) throws -> Void)?
- override func callFunction(name: String,
- withObject data: Any?,
- timeout: TimeInterval,
- completion: @escaping ((Result<HTTPSCallableResult, Error>) -> Void)) {
- do {
- try verifyParameters?(name, data, timeout)
- let result = try mockCallFunction()
- completion(.success(result))
- } catch {
- completion(.failure(error))
- }
- }
- init(mockCallFunction: @escaping () throws -> HTTPSCallableResult) {
- self.mockCallFunction = mockCallFunction
- super.init(
- projectID: "dummy-project",
- region: "",
- customDomain: nil,
- auth: nil,
- messaging: nil,
- appCheck: nil,
- fetcherService: GTMSessionFetcherService()
- )
- }
- }
- public class HTTPSCallableResultFake: HTTPSCallableResult {
- let fakeData: String
- init(data: String) {
- fakeData = data
- super.init(data: data)
- }
- }
- @available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *)
- class HTTPSCallableTests: XCTestCase {
- func testCallWithoutParametersSuccess() {
- // given
- var cancellables = Set<AnyCancellable>()
- let httpsFunctionWasCalledExpectation = expectation(description: "HTTPS Function was called")
- let functionWasCalledExpectation = expectation(description: "Function was called")
- let expectedResult = "mockResult w/o parameters"
- let functions = MockFunctions {
- httpsFunctionWasCalledExpectation.fulfill()
- return HTTPSCallableResultFake(data: expectedResult)
- }
- let dummyFunction = functions.httpsCallable("dummyFunction")
- // when
- dummyFunction.call()
- .sink { completion in
- switch completion {
- case .finished:
- print("Finished")
- case let .failure(error):
- XCTFail("💥 Something went wrong: \(error)")
- }
- } receiveValue: { functionResult in
- guard let result = functionResult.data as? String else {
- XCTFail("Expected String data")
- return
- }
- XCTAssertEqual(result, expectedResult)
- functionWasCalledExpectation.fulfill()
- }
- .store(in: &cancellables)
- // then
- wait(
- for: [functionWasCalledExpectation, httpsFunctionWasCalledExpectation],
- timeout: expectationTimeout
- )
- }
- func testCallWithParametersSuccess() {
- // given
- var cancellables = Set<AnyCancellable>()
- let httpsFunctionWasCalledExpectation = expectation(description: "HTTPS Function was called")
- let functionWasCalledExpectation = expectation(description: "Function was called")
- let inputParameter = "input parameter"
- let expectedResult = "mockResult w/ parameters: \(inputParameter)"
- let functions = MockFunctions {
- httpsFunctionWasCalledExpectation.fulfill()
- return HTTPSCallableResultFake(data: expectedResult)
- }
- functions.verifyParameters = { name, data, timeout in
- XCTAssertEqual(name as String, "dummyFunction")
- XCTAssertEqual(data as? String, inputParameter)
- XCTAssertEqual(timeout as TimeInterval, timeoutInterval)
- }
- let dummyFunction = functions.httpsCallable("dummyFunction")
- // when
- dummyFunction.call(inputParameter)
- .sink { completion in
- switch completion {
- case .finished:
- print("Finished")
- case let .failure(error):
- XCTFail("💥 Something went wrong: \(error)")
- }
- } receiveValue: { functionResult in
- guard let result = functionResult.data as? String else {
- XCTFail("Expected String data")
- return
- }
- XCTAssertEqual(result, expectedResult)
- functionWasCalledExpectation.fulfill()
- }
- .store(in: &cancellables)
- // then
- wait(
- for: [httpsFunctionWasCalledExpectation, functionWasCalledExpectation],
- timeout: expectationTimeout
- )
- }
- func testCallWithParametersFailure() {
- // given
- var cancellables = Set<AnyCancellable>()
- let httpsFunctionWasCalledExpectation = expectation(description: "HTTPS Function was called")
- let functionCallFailedExpectation = expectation(description: "Function call failed")
- let inputParameter = "input parameter"
- let functions = MockFunctions {
- httpsFunctionWasCalledExpectation.fulfill()
- throw NSError(domain: FunctionsErrorDomain,
- code: FunctionsErrorCode.internal.rawValue,
- userInfo: [NSLocalizedDescriptionKey: "Response is missing data field."])
- }
- functions.verifyParameters = { name, data, timeout in
- XCTAssertEqual(name as String, "dummyFunction")
- XCTAssertEqual(data as? String, inputParameter)
- XCTAssertEqual(timeout as TimeInterval, timeoutInterval)
- }
- let dummyFunction = functions.httpsCallable("dummyFunction")
- // when
- dummyFunction.call(inputParameter)
- .sink { completion in
- if case let .failure(error as NSError) = completion {
- // Verify user mismatch error.
- XCTAssertEqual(error.code, FunctionsErrorCode.internal.rawValue)
- functionCallFailedExpectation.fulfill()
- }
- } receiveValue: { functionResult in
- XCTFail("💥 result unexpected")
- }
- .store(in: &cancellables)
- // then
- wait(
- for: [functionCallFailedExpectation, httpsFunctionWasCalledExpectation],
- timeout: expectationTimeout
- )
- }
- }
|