mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-09 22:36:01 +05:45
890 lines
26 KiB
Swift
890 lines
26 KiB
Swift
// 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 FirebaseAuthInterop
|
|
@testable import FirebaseFunctions
|
|
import FirebaseMessagingInterop
|
|
import XCTest
|
|
|
|
/// This file was initialized as a direct port of
|
|
/// `FirebaseFunctionsSwift/Tests/IntegrationTests.swift`
|
|
/// which itself was ported from the Objective-C
|
|
/// `FirebaseFunctions/Tests/Integration/FIRIntegrationTests.m`
|
|
///
|
|
/// The tests require the emulator to be running with `FirebaseFunctions/Backend/start.sh
|
|
/// synchronous`
|
|
/// The Firebase Functions called in the tests are implemented in
|
|
/// `FirebaseFunctions/Backend/index.js`.
|
|
|
|
struct DataTestRequest: Encodable {
|
|
var bool: Bool
|
|
var int: Int32
|
|
var long: Int64
|
|
var string: String
|
|
var array: [Int32]
|
|
// NOTE: Auto-synthesized Encodable conformance uses 'encodeIfPresent' to
|
|
// encode Optional values. To encode Optional.none as null you either need
|
|
// to write a manual encodable conformance or use a helper like the
|
|
// propertyWrapper here:
|
|
@NullEncodable var null: Bool?
|
|
}
|
|
|
|
@propertyWrapper
|
|
struct NullEncodable<T>: Encodable where T: Encodable {
|
|
var wrappedValue: T?
|
|
|
|
init(wrappedValue: T?) {
|
|
self.wrappedValue = wrappedValue
|
|
}
|
|
|
|
func encode(to encoder: Encoder) throws {
|
|
var container = encoder.singleValueContainer()
|
|
switch wrappedValue {
|
|
case let .some(value): try container.encode(value)
|
|
case .none: try container.encodeNil()
|
|
}
|
|
}
|
|
}
|
|
|
|
struct DataTestResponse: Decodable, Equatable {
|
|
var message: String
|
|
var long: Int64
|
|
var code: Int32
|
|
}
|
|
|
|
class IntegrationTests: XCTestCase {
|
|
let functions = Functions(projectID: "functions-integration-test",
|
|
region: "us-central1",
|
|
customDomain: nil,
|
|
auth: nil,
|
|
messaging: MessagingTokenProvider(),
|
|
appCheck: nil)
|
|
|
|
override func setUp() {
|
|
super.setUp()
|
|
functions.useEmulator(withHost: "localhost", port: 5005)
|
|
}
|
|
|
|
func emulatorURL(_ funcName: String) -> URL {
|
|
return URL(string: "http://localhost:5005/functions-integration-test/us-central1/\(funcName)")!
|
|
}
|
|
|
|
func testData() {
|
|
let data = DataTestRequest(
|
|
bool: true,
|
|
int: 2,
|
|
long: 9_876_543_210,
|
|
string: "four",
|
|
array: [5, 6],
|
|
null: nil
|
|
)
|
|
let byName = functions.httpsCallable("dataTest",
|
|
requestAs: DataTestRequest.self,
|
|
responseAs: DataTestResponse.self)
|
|
let byURL = functions.httpsCallable(emulatorURL("dataTest"),
|
|
requestAs: DataTestRequest.self,
|
|
responseAs: DataTestResponse.self)
|
|
|
|
for function in [byName, byURL] {
|
|
let expectation = expectation(description: #function)
|
|
function.call(data) { result in
|
|
do {
|
|
let response = try result.get()
|
|
let expected = DataTestResponse(
|
|
message: "stub response",
|
|
long: 420,
|
|
code: 42
|
|
)
|
|
XCTAssertEqual(response, expected)
|
|
} catch {
|
|
XCTFail("Failed to unwrap the function result: \(error)")
|
|
}
|
|
expectation.fulfill()
|
|
}
|
|
waitForExpectations(timeout: 5)
|
|
}
|
|
}
|
|
|
|
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
|
|
func testDataAsync() async throws {
|
|
let data = DataTestRequest(
|
|
bool: true,
|
|
int: 2,
|
|
long: 9_876_543_210,
|
|
string: "four",
|
|
array: [5, 6],
|
|
null: nil
|
|
)
|
|
|
|
let byName = functions.httpsCallable("dataTest",
|
|
requestAs: DataTestRequest.self,
|
|
responseAs: DataTestResponse.self)
|
|
let byUrl = functions.httpsCallable(emulatorURL("dataTest"),
|
|
requestAs: DataTestRequest.self,
|
|
responseAs: DataTestResponse.self)
|
|
|
|
for function in [byName, byUrl] {
|
|
let response = try await function.call(data)
|
|
let expected = DataTestResponse(
|
|
message: "stub response",
|
|
long: 420,
|
|
code: 42
|
|
)
|
|
XCTAssertEqual(response, expected)
|
|
}
|
|
}
|
|
|
|
func testScalar() {
|
|
let byName = functions.httpsCallable(
|
|
"scalarTest",
|
|
requestAs: Int16.self,
|
|
responseAs: Int.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("scalarTest"),
|
|
requestAs: Int16.self,
|
|
responseAs: Int.self
|
|
)
|
|
for function in [byName, byURL] {
|
|
let expectation = expectation(description: #function)
|
|
function.call(17) { result in
|
|
do {
|
|
let response = try result.get()
|
|
XCTAssertEqual(response, 76)
|
|
} catch {
|
|
XCTAssert(false, "Failed to unwrap the function result: \(error)")
|
|
}
|
|
expectation.fulfill()
|
|
}
|
|
waitForExpectations(timeout: 5)
|
|
}
|
|
}
|
|
|
|
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
|
|
func testScalarAsync() async throws {
|
|
let byName = functions.httpsCallable(
|
|
"scalarTest",
|
|
requestAs: Int16.self,
|
|
responseAs: Int.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("scalarTest"),
|
|
requestAs: Int16.self,
|
|
responseAs: Int.self
|
|
)
|
|
|
|
for function in [byName, byURL] {
|
|
let result = try await function.call(17)
|
|
XCTAssertEqual(result, 76)
|
|
}
|
|
}
|
|
|
|
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
|
|
func testScalarAsyncAlternateSignature() async throws {
|
|
let byName: Callable<Int16, Int> = functions.httpsCallable("scalarTest")
|
|
let byURL: Callable<Int16, Int> = functions.httpsCallable(emulatorURL("scalarTest"))
|
|
for function in [byName, byURL] {
|
|
let result = try await function.call(17)
|
|
XCTAssertEqual(result, 76)
|
|
}
|
|
}
|
|
|
|
func testToken() {
|
|
// Recreate functions with a token.
|
|
let functions = Functions(
|
|
projectID: "functions-integration-test",
|
|
region: "us-central1",
|
|
customDomain: nil,
|
|
auth: AuthTokenProvider(token: "token"),
|
|
messaging: MessagingTokenProvider(),
|
|
appCheck: nil
|
|
)
|
|
functions.useEmulator(withHost: "localhost", port: 5005)
|
|
|
|
let byName = functions.httpsCallable(
|
|
"tokenTest",
|
|
requestAs: [String: Int].self,
|
|
responseAs: [String: Int].self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("tokenTest"),
|
|
requestAs: [String: Int].self,
|
|
responseAs: [String: Int].self
|
|
)
|
|
for function in [byName, byURL] {
|
|
let expectation = expectation(description: #function)
|
|
XCTAssertNotNil(function)
|
|
function.call([:]) { result in
|
|
do {
|
|
let data = try result.get()
|
|
XCTAssertEqual(data, [:])
|
|
} catch {
|
|
XCTAssert(false, "Failed to unwrap the function result: \(error)")
|
|
}
|
|
expectation.fulfill()
|
|
}
|
|
waitForExpectations(timeout: 5)
|
|
}
|
|
}
|
|
|
|
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
|
|
func testTokenAsync() async throws {
|
|
// Recreate functions with a token.
|
|
let functions = Functions(
|
|
projectID: "functions-integration-test",
|
|
region: "us-central1",
|
|
customDomain: nil,
|
|
auth: AuthTokenProvider(token: "token"),
|
|
messaging: MessagingTokenProvider(),
|
|
appCheck: nil
|
|
)
|
|
functions.useEmulator(withHost: "localhost", port: 5005)
|
|
|
|
let byName = functions.httpsCallable(
|
|
"tokenTest",
|
|
requestAs: [String: Int].self,
|
|
responseAs: [String: Int].self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("tokenTest"),
|
|
requestAs: [String: Int].self,
|
|
responseAs: [String: Int].self
|
|
)
|
|
|
|
for function in [byName, byURL] {
|
|
let data = try await function.call([:])
|
|
XCTAssertEqual(data, [:])
|
|
}
|
|
}
|
|
|
|
func testFCMToken() {
|
|
let byName = functions.httpsCallable(
|
|
"FCMTokenTest",
|
|
requestAs: [String: Int].self,
|
|
responseAs: [String: Int].self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("FCMTokenTest"),
|
|
requestAs: [String: Int].self,
|
|
responseAs: [String: Int].self
|
|
)
|
|
for function in [byName, byURL] {
|
|
let expectation = expectation(description: #function)
|
|
function.call([:]) { result in
|
|
do {
|
|
let data = try result.get()
|
|
XCTAssertEqual(data, [:])
|
|
} catch {
|
|
XCTAssert(false, "Failed to unwrap the function result: \(error)")
|
|
}
|
|
expectation.fulfill()
|
|
}
|
|
waitForExpectations(timeout: 5)
|
|
}
|
|
}
|
|
|
|
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
|
|
func testFCMTokenAsync() async throws {
|
|
let byName = functions.httpsCallable(
|
|
"FCMTokenTest",
|
|
requestAs: [String: Int].self,
|
|
responseAs: [String: Int].self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("FCMTokenTest"),
|
|
requestAs: [String: Int].self,
|
|
responseAs: [String: Int].self
|
|
)
|
|
|
|
for function in [byName, byURL] {
|
|
let data = try await function.call([:])
|
|
XCTAssertEqual(data, [:])
|
|
}
|
|
}
|
|
|
|
func testNull() {
|
|
let byName = functions.httpsCallable(
|
|
"nullTest",
|
|
requestAs: Int?.self,
|
|
responseAs: Int?.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("nullTest"),
|
|
requestAs: Int?.self,
|
|
responseAs: Int?.self
|
|
)
|
|
for function in [byName, byURL] {
|
|
let expectation = expectation(description: #function)
|
|
function.call(nil) { result in
|
|
do {
|
|
let data = try result.get()
|
|
XCTAssertEqual(data, nil)
|
|
} catch {
|
|
XCTAssert(false, "Failed to unwrap the function result: \(error)")
|
|
}
|
|
expectation.fulfill()
|
|
}
|
|
waitForExpectations(timeout: 5)
|
|
}
|
|
}
|
|
|
|
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
|
|
func testNullAsync() async throws {
|
|
let byName = functions.httpsCallable(
|
|
"nullTest",
|
|
requestAs: Int?.self,
|
|
responseAs: Int?.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("nullTest"),
|
|
requestAs: Int?.self,
|
|
responseAs: Int?.self
|
|
)
|
|
|
|
for function in [byName, byURL] {
|
|
let data = try await function.call(nil)
|
|
XCTAssertEqual(data, nil)
|
|
}
|
|
}
|
|
|
|
func testMissingResult() {
|
|
let byName = functions.httpsCallable(
|
|
"missingResultTest",
|
|
requestAs: Int?.self,
|
|
responseAs: Int?.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("missingResultTest"),
|
|
requestAs: Int?.self,
|
|
responseAs: Int?.self
|
|
)
|
|
for function in [byName, byURL] {
|
|
let expectation = expectation(description: #function)
|
|
function.call(nil) { result in
|
|
do {
|
|
_ = try result.get()
|
|
} catch {
|
|
let error = error as NSError
|
|
XCTAssertEqual(FunctionsErrorCode.internal.rawValue, error.code)
|
|
XCTAssertEqual("Response is missing data field.", error.localizedDescription)
|
|
expectation.fulfill()
|
|
return
|
|
}
|
|
XCTFail("Failed to throw error for missing result")
|
|
}
|
|
|
|
waitForExpectations(timeout: 5)
|
|
}
|
|
}
|
|
|
|
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
|
|
func testMissingResultAsync() async {
|
|
let byName = functions.httpsCallable(
|
|
"missingResultTest",
|
|
requestAs: Int?.self,
|
|
responseAs: Int?.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("missingResultTest"),
|
|
requestAs: Int?.self,
|
|
responseAs: Int?.self
|
|
)
|
|
for function in [byName, byURL] {
|
|
do {
|
|
_ = try await function.call(nil)
|
|
XCTFail("Failed to throw error for missing result")
|
|
} catch {
|
|
let error = error as NSError
|
|
XCTAssertEqual(FunctionsErrorCode.internal.rawValue, error.code)
|
|
XCTAssertEqual("Response is missing data field.", error.localizedDescription)
|
|
}
|
|
}
|
|
}
|
|
|
|
func testUnhandledError() {
|
|
let byName = functions.httpsCallable(
|
|
"unhandledErrorTest",
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("unhandledErrorTest"),
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
for function in [byName, byURL] {
|
|
let expectation = expectation(description: #function)
|
|
function.call([]) { result in
|
|
do {
|
|
_ = try result.get()
|
|
} catch {
|
|
let error = error as NSError
|
|
XCTAssertEqual(FunctionsErrorCode.internal.rawValue, error.code)
|
|
XCTAssertEqual("INTERNAL", error.localizedDescription)
|
|
expectation.fulfill()
|
|
return
|
|
}
|
|
XCTFail("Failed to throw error for missing result")
|
|
}
|
|
XCTAssert(true)
|
|
waitForExpectations(timeout: 5)
|
|
}
|
|
}
|
|
|
|
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
|
|
func testUnhandledErrorAsync() async {
|
|
let byName = functions.httpsCallable(
|
|
"unhandledErrorTest",
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
"unhandledErrorTest",
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
for function in [byName, byURL] {
|
|
do {
|
|
_ = try await function.call([])
|
|
XCTFail("Failed to throw error for missing result")
|
|
} catch {
|
|
let error = error as NSError
|
|
XCTAssertEqual(FunctionsErrorCode.internal.rawValue, error.code)
|
|
XCTAssertEqual("INTERNAL", error.localizedDescription)
|
|
}
|
|
}
|
|
}
|
|
|
|
func testUnknownError() {
|
|
let byName = functions.httpsCallable(
|
|
"unknownErrorTest",
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("unknownErrorTest"),
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
for function in [byName, byURL] {
|
|
let expectation = expectation(description: #function)
|
|
function.call([]) { result in
|
|
do {
|
|
_ = try result.get()
|
|
} catch {
|
|
let error = error as NSError
|
|
XCTAssertEqual(FunctionsErrorCode.internal.rawValue, error.code)
|
|
XCTAssertEqual("INTERNAL", error.localizedDescription)
|
|
expectation.fulfill()
|
|
return
|
|
}
|
|
XCTFail("Failed to throw error for missing result")
|
|
}
|
|
}
|
|
waitForExpectations(timeout: 5)
|
|
}
|
|
|
|
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
|
|
func testUnknownErrorAsync() async {
|
|
let byName = functions.httpsCallable(
|
|
"unknownErrorTest",
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("unknownErrorTest"),
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
for function in [byName, byURL] {
|
|
do {
|
|
_ = try await function.call([])
|
|
XCTAssertFalse(true, "Failed to throw error for missing result")
|
|
} catch {
|
|
let error = error as NSError
|
|
XCTAssertEqual(FunctionsErrorCode.internal.rawValue, error.code)
|
|
XCTAssertEqual("INTERNAL", error.localizedDescription)
|
|
}
|
|
}
|
|
}
|
|
|
|
func testExplicitError() {
|
|
let byName = functions.httpsCallable(
|
|
"explicitErrorTest",
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
"explicitErrorTest",
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
for function in [byName, byURL] {
|
|
let expectation = expectation(description: #function)
|
|
function.call([]) { result in
|
|
do {
|
|
_ = try result.get()
|
|
} catch {
|
|
let error = error as NSError
|
|
XCTAssertEqual(FunctionsErrorCode.outOfRange.rawValue, error.code)
|
|
XCTAssertEqual("explicit nope", error.localizedDescription)
|
|
XCTAssertEqual(["start": 10 as Int32, "end": 20 as Int32, "long": 30],
|
|
error.userInfo["details"] as? [String: Int32])
|
|
expectation.fulfill()
|
|
return
|
|
}
|
|
XCTFail("Failed to throw error for missing result")
|
|
}
|
|
waitForExpectations(timeout: 5)
|
|
}
|
|
}
|
|
|
|
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
|
|
func testExplicitErrorAsync() async {
|
|
let byName = functions.httpsCallable(
|
|
"explicitErrorTest",
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("explicitErrorTest"),
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
for function in [byName, byURL] {
|
|
do {
|
|
_ = try await function.call([])
|
|
XCTAssertFalse(true, "Failed to throw error for missing result")
|
|
} catch {
|
|
let error = error as NSError
|
|
XCTAssertEqual(FunctionsErrorCode.outOfRange.rawValue, error.code)
|
|
XCTAssertEqual("explicit nope", error.localizedDescription)
|
|
XCTAssertEqual(["start": 10 as Int32, "end": 20 as Int32, "long": 30],
|
|
error.userInfo["details"] as? [String: Int32])
|
|
}
|
|
}
|
|
}
|
|
|
|
func testHttpError() {
|
|
let byName = functions.httpsCallable(
|
|
"httpErrorTest",
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("httpErrorTest"),
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
for function in [byName, byURL] {
|
|
let expectation = expectation(description: #function)
|
|
XCTAssertNotNil(function)
|
|
function.call([]) { result in
|
|
do {
|
|
_ = try result.get()
|
|
} catch {
|
|
let error = error as NSError
|
|
XCTAssertEqual(FunctionsErrorCode.invalidArgument.rawValue, error.code)
|
|
expectation.fulfill()
|
|
return
|
|
}
|
|
XCTFail("Failed to throw error for missing result")
|
|
}
|
|
waitForExpectations(timeout: 5)
|
|
}
|
|
}
|
|
|
|
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
|
|
func testHttpErrorAsync() async {
|
|
let byName = functions.httpsCallable(
|
|
"httpErrorTest",
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("httpErrorTest"),
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
for function in [byName, byURL] {
|
|
do {
|
|
_ = try await function.call([])
|
|
XCTAssertFalse(true, "Failed to throw error for missing result")
|
|
} catch {
|
|
let error = error as NSError
|
|
XCTAssertEqual(FunctionsErrorCode.invalidArgument.rawValue, error.code)
|
|
}
|
|
}
|
|
}
|
|
|
|
func testThrowError() {
|
|
let byName = functions.httpsCallable(
|
|
"throwTest",
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("throwTest"),
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
for function in [byName, byURL] {
|
|
let expectation = expectation(description: #function)
|
|
XCTAssertNotNil(function)
|
|
function.call([]) { result in
|
|
do {
|
|
_ = try result.get()
|
|
} catch {
|
|
let error = error as NSError
|
|
XCTAssertEqual(FunctionsErrorCode.invalidArgument.rawValue, error.code)
|
|
XCTAssertEqual(error.localizedDescription, "Invalid test requested.")
|
|
expectation.fulfill()
|
|
return
|
|
}
|
|
XCTFail("Failed to throw error for missing result")
|
|
}
|
|
waitForExpectations(timeout: 5)
|
|
}
|
|
}
|
|
|
|
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
|
|
func testThrowErrorAsync() async {
|
|
let byName = functions.httpsCallable(
|
|
"throwTest",
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("throwTest"),
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
for function in [byName, byURL] {
|
|
do {
|
|
_ = try await function.call([])
|
|
XCTAssertFalse(true, "Failed to throw error for missing result")
|
|
} catch {
|
|
let error = error as NSError
|
|
XCTAssertEqual(FunctionsErrorCode.invalidArgument.rawValue, error.code)
|
|
XCTAssertEqual(error.localizedDescription, "Invalid test requested.")
|
|
}
|
|
}
|
|
}
|
|
|
|
func testTimeout() {
|
|
let byName = functions.httpsCallable(
|
|
"timeoutTest",
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
let byURL = functions.httpsCallable(
|
|
emulatorURL("timeoutTest"),
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
for var function in [byName, byURL] {
|
|
let expectation = expectation(description: #function)
|
|
function.timeoutInterval = 0.05
|
|
function.call([]) { result in
|
|
do {
|
|
_ = try result.get()
|
|
} catch {
|
|
let error = error as NSError
|
|
XCTAssertEqual(FunctionsErrorCode.deadlineExceeded.rawValue, error.code)
|
|
XCTAssertEqual("DEADLINE EXCEEDED", error.localizedDescription)
|
|
XCTAssertNil(error.userInfo["details"])
|
|
expectation.fulfill()
|
|
return
|
|
}
|
|
XCTFail("Failed to throw error for missing result")
|
|
}
|
|
waitForExpectations(timeout: 5)
|
|
}
|
|
}
|
|
|
|
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
|
|
func testTimeoutAsync() async {
|
|
var byName = functions.httpsCallable(
|
|
"timeoutTest",
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
byName.timeoutInterval = 0.05
|
|
var byURL = functions.httpsCallable(
|
|
emulatorURL("timeoutTest"),
|
|
requestAs: [Int].self,
|
|
responseAs: Int.self
|
|
)
|
|
byURL.timeoutInterval = 0.05
|
|
for function in [byName, byURL] {
|
|
do {
|
|
_ = try await function.call([])
|
|
XCTAssertFalse(true, "Failed to throw error for missing result")
|
|
} catch {
|
|
let error = error as NSError
|
|
XCTAssertEqual(FunctionsErrorCode.deadlineExceeded.rawValue, error.code)
|
|
XCTAssertEqual("DEADLINE EXCEEDED", error.localizedDescription)
|
|
XCTAssertNil(error.userInfo["details"])
|
|
}
|
|
}
|
|
}
|
|
|
|
func testCallAsFunction() {
|
|
let data = DataTestRequest(
|
|
bool: true,
|
|
int: 2,
|
|
long: 9_876_543_210,
|
|
string: "four",
|
|
array: [5, 6],
|
|
null: nil
|
|
)
|
|
let byName = functions.httpsCallable("dataTest",
|
|
requestAs: DataTestRequest.self,
|
|
responseAs: DataTestResponse.self)
|
|
let byURL = functions.httpsCallable(emulatorURL("dataTest"),
|
|
requestAs: DataTestRequest.self,
|
|
responseAs: DataTestResponse.self)
|
|
for function in [byName, byURL] {
|
|
let expectation = expectation(description: #function)
|
|
function(data) { result in
|
|
do {
|
|
let response = try result.get()
|
|
let expected = DataTestResponse(
|
|
message: "stub response",
|
|
long: 420,
|
|
code: 42
|
|
)
|
|
XCTAssertEqual(response, expected)
|
|
expectation.fulfill()
|
|
} catch {
|
|
XCTAssert(false, "Failed to unwrap the function result: \(error)")
|
|
}
|
|
}
|
|
waitForExpectations(timeout: 5)
|
|
}
|
|
}
|
|
|
|
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
|
|
func testCallAsFunctionAsync() async throws {
|
|
let data = DataTestRequest(
|
|
bool: true,
|
|
int: 2,
|
|
long: 9_876_543_210,
|
|
string: "four",
|
|
array: [5, 6],
|
|
null: nil
|
|
)
|
|
|
|
let byName = functions.httpsCallable("dataTest",
|
|
requestAs: DataTestRequest.self,
|
|
responseAs: DataTestResponse.self)
|
|
|
|
let byURL = functions.httpsCallable(emulatorURL("dataTest"),
|
|
requestAs: DataTestRequest.self,
|
|
responseAs: DataTestResponse.self)
|
|
|
|
for function in [byName, byURL] {
|
|
let response = try await function(data)
|
|
let expected = DataTestResponse(
|
|
message: "stub response",
|
|
long: 420,
|
|
code: 42
|
|
)
|
|
XCTAssertEqual(response, expected)
|
|
}
|
|
}
|
|
|
|
func testInferredTypes() {
|
|
let data = DataTestRequest(
|
|
bool: true,
|
|
int: 2,
|
|
long: 9_876_543_210,
|
|
string: "four",
|
|
array: [5, 6],
|
|
null: nil
|
|
)
|
|
let byName: Callable<DataTestRequest, DataTestResponse> = functions.httpsCallable("dataTest")
|
|
let byURL: Callable<DataTestRequest, DataTestResponse> = functions
|
|
.httpsCallable(emulatorURL("dataTest"))
|
|
|
|
for function in [byName, byURL] {
|
|
let expectation = expectation(description: #function)
|
|
function(data) { result in
|
|
do {
|
|
let response = try result.get()
|
|
let expected = DataTestResponse(
|
|
message: "stub response",
|
|
long: 420,
|
|
code: 42
|
|
)
|
|
XCTAssertEqual(response, expected)
|
|
expectation.fulfill()
|
|
} catch {
|
|
XCTAssert(false, "Failed to unwrap the function result: \(error)")
|
|
}
|
|
}
|
|
waitForExpectations(timeout: 5)
|
|
}
|
|
}
|
|
|
|
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
|
|
func testInferredTyesAsync() async throws {
|
|
let data = DataTestRequest(
|
|
bool: true,
|
|
int: 2,
|
|
long: 9_876_543_210,
|
|
string: "four",
|
|
array: [5, 6],
|
|
null: nil
|
|
)
|
|
|
|
let byName: Callable<DataTestRequest, DataTestResponse> = functions
|
|
.httpsCallable("dataTest")
|
|
let byURL: Callable<DataTestRequest, DataTestResponse> = functions
|
|
.httpsCallable(emulatorURL("dataTest"))
|
|
|
|
for function in [byName, byURL] {
|
|
let response = try await function(data)
|
|
let expected = DataTestResponse(
|
|
message: "stub response",
|
|
long: 420,
|
|
code: 42
|
|
)
|
|
XCTAssertEqual(response, expected)
|
|
}
|
|
}
|
|
}
|
|
|
|
private class AuthTokenProvider: AuthInterop {
|
|
func getUserID() -> String? {
|
|
return "fake user"
|
|
}
|
|
|
|
let token: String
|
|
|
|
init(token: String) {
|
|
self.token = token
|
|
}
|
|
|
|
func getToken(forcingRefresh: Bool, completion: (String?, Error?) -> Void) {
|
|
completion(token, nil)
|
|
}
|
|
}
|
|
|
|
private class MessagingTokenProvider: NSObject, MessagingInterop {
|
|
var fcmToken: String? { return "fakeFCMToken" }
|
|
}
|