Files
firebase-ios-sdk/FirebaseFunctions/Tests/SwiftIntegration/IntegrationTests.swift
T
2021-12-15 14:11:53 -08:00

483 lines
16 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 FirebaseFunctions
import FirebaseFunctionsTestingSupport
import XCTest
/// This file was initialized as a direct port of 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`.
class IntegrationTests: XCTestCase {
let functions = FunctionsFake(
projectID: "functions-integration-test",
region: "us-central1",
customDomain: nil,
withToken: nil
)
let projectID = "functions-swift-integration-test"
override func setUp() {
super.setUp()
functions.useLocalhost()
}
func testData() {
let expectation = expectation(description: #function)
let data = [
"bool": true,
"int": 2 as Int32,
"long": 9_876_543_210,
"string": "four",
"array": [5 as Int32, 6 as Int32],
"null": nil,
] as [String: Any?]
let function = functions.httpsCallable("dataTest")
XCTAssertNotNil(function)
function.call(data) { result, error in
do {
XCTAssertNil(error)
let data = try XCTUnwrap(result?.data as? [String: Any])
let message = try XCTUnwrap(data["message"] as? String)
let long = try XCTUnwrap(data["long"] as? Int64)
let code = try XCTUnwrap(data["code"] as? Int32)
XCTAssertEqual(message, "stub response")
XCTAssertEqual(long, 420)
XCTAssertEqual(code, 42)
expectation.fulfill()
} catch {
XCTAssert(false, "Failed to unwrap the function result: \(error)")
}
}
waitForExpectations(timeout: 5)
}
#if compiler(>=5.5) && canImport(_Concurrency)
@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testDataAsync() async throws {
let input = [
"bool": true,
"int": 2 as Int32,
"long": 9_876_543_210,
"string": "four",
"array": [5 as Int32, 6 as Int32],
"null": nil,
] as [String: Any?]
let function = functions.httpsCallable("dataTest")
XCTAssertNotNil(function)
let result = try await function.call(input)
let data = try XCTUnwrap(result.data as? [String: Any])
let message = try XCTUnwrap(data["message"] as? String)
let long = try XCTUnwrap(data["long"] as? Int64)
let code = try XCTUnwrap(data["code"] as? Int32)
XCTAssertEqual(message, "stub response")
XCTAssertEqual(long, 420)
XCTAssertEqual(code, 42)
}
#endif
func testScalar() {
let expectation = expectation(description: #function)
let function = functions.httpsCallable("scalarTest")
XCTAssertNotNil(function)
function.call(17 as Int16) { result, error in
do {
XCTAssertNil(error)
let data = try XCTUnwrap(result?.data as? Int)
XCTAssertEqual(data, 76)
expectation.fulfill()
} catch {
XCTAssert(false, "Failed to unwrap the function result: \(error)")
}
}
waitForExpectations(timeout: 5)
}
#if compiler(>=5.5) && canImport(_Concurrency)
@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testScalarAsync() async throws {
let function = functions.httpsCallable("scalarTest")
XCTAssertNotNil(function)
let result = try await function.call(17 as Int16)
let data = try XCTUnwrap(result.data as? Int)
XCTAssertEqual(data, 76)
}
#endif
func testToken() {
// Recreate functions with a token.
let functions = FunctionsFake(
projectID: "functions-integration-test",
region: "us-central1",
customDomain: nil,
withToken: "token"
)
functions.useLocalhost()
let expectation = expectation(description: #function)
let function = functions.httpsCallable("FCMTokenTest")
XCTAssertNotNil(function)
function.call([:]) { result, error in
do {
XCTAssertNil(error)
let data = try XCTUnwrap(result?.data) as? [String: Int]
XCTAssertEqual(data, [:])
expectation.fulfill()
} catch {
XCTAssert(false, "Failed to unwrap the function result: \(error)")
}
}
waitForExpectations(timeout: 5)
}
#if compiler(>=5.5) && canImport(_Concurrency)
@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testTokenAsync() async throws {
// Recreate functions with a token.
let functions = FunctionsFake(
projectID: "functions-integration-test",
region: "us-central1",
customDomain: nil,
withToken: "token"
)
functions.useLocalhost()
let function = functions.httpsCallable("FCMTokenTest")
XCTAssertNotNil(function)
let result = try await function.call([:])
let data = try XCTUnwrap(result.data) as? [String: Int]
XCTAssertEqual(data, [:])
}
#endif
func testFCMToken() {
let expectation = expectation(description: #function)
let function = functions.httpsCallable("FCMTokenTest")
XCTAssertNotNil(function)
function.call([:]) { result, error in
do {
XCTAssertNil(error)
let data = try XCTUnwrap(result?.data) as? [String: Int]
XCTAssertEqual(data, [:])
expectation.fulfill()
} catch {
XCTAssert(false, "Failed to unwrap the function result: \(error)")
}
}
waitForExpectations(timeout: 5)
}
#if compiler(>=5.5) && canImport(_Concurrency)
@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testFCMTokenAsync() async throws {
let function = functions.httpsCallable("FCMTokenTest")
XCTAssertNotNil(function)
let result = try await function.call([:])
let data = try XCTUnwrap(result.data) as? [String: Int]
XCTAssertEqual(data, [:])
}
#endif
func testNull() {
let expectation = expectation(description: #function)
let function = functions.httpsCallable("nullTest")
XCTAssertNotNil(function)
function.call(nil) { result, error in
do {
XCTAssertNil(error)
let data = try XCTUnwrap(result?.data) as? NSNull
XCTAssertEqual(data, NSNull())
expectation.fulfill()
} catch {
XCTAssert(false, "Failed to unwrap the function result: \(error)")
}
}
waitForExpectations(timeout: 5)
}
#if compiler(>=5.5) && canImport(_Concurrency)
@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testNullAsync() async throws {
let function = functions.httpsCallable("nullTest")
XCTAssertNotNil(function)
let result = try await function.call(nil)
let data = try XCTUnwrap(result.data) as? NSNull
XCTAssertEqual(data, NSNull())
}
#endif
// No parameters to call should be the same as passing nil.
func testParameterless() {
let expectation = expectation(description: #function)
let function = functions.httpsCallable("nullTest")
XCTAssertNotNil(function)
function.call { result, error in
do {
XCTAssertNil(error)
let data = try XCTUnwrap(result?.data) as? NSNull
XCTAssertEqual(data, NSNull())
expectation.fulfill()
} catch {
XCTAssert(false, "Failed to unwrap the function result: \(error)")
}
}
waitForExpectations(timeout: 5)
}
#if compiler(>=5.5) && canImport(_Concurrency)
@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testParameterlessAsync() async throws {
let function = functions.httpsCallable("nullTest")
XCTAssertNotNil(function)
let result = try await function.call()
let data = try XCTUnwrap(result.data) as? NSNull
XCTAssertEqual(data, NSNull())
}
#endif
func testMissingResult() {
let expectation = expectation(description: #function)
let function = functions.httpsCallable("missingResultTest")
XCTAssertNotNil(function)
function.call(nil) { result, error in
do {
XCTAssertNotNil(error)
let error = try XCTUnwrap(error) as NSError
XCTAssertEqual(FunctionsErrorCode.internal.rawValue, error.code)
XCTAssertEqual("Response is missing data field.", error.localizedDescription)
expectation.fulfill()
} catch {
XCTAssert(false, "Failed to unwrap the function result: \(error)")
}
}
XCTAssert(true)
waitForExpectations(timeout: 5)
}
#if compiler(>=5.5) && canImport(_Concurrency)
@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testMissingResultAsync() async throws {
let function = functions.httpsCallable("missingResultTest")
XCTAssertNotNil(function)
do {
_ = try await function.call(nil)
} catch {
let error = try XCTUnwrap(error) as NSError
XCTAssertEqual(FunctionsErrorCode.internal.rawValue, error.code)
XCTAssertEqual("Response is missing data field.", error.localizedDescription)
return
}
XCTAssertFalse(true, "Failed to throw error for missing result")
}
#endif
func testUnhandledError() {
let expectation = expectation(description: #function)
let function = functions.httpsCallable("unhandledErrorTest")
XCTAssertNotNil(function)
function.call([]) { result, error in
do {
XCTAssertNotNil(error)
let error = try XCTUnwrap(error! as NSError)
XCTAssertEqual(FunctionsErrorCode.internal.rawValue, error.code)
XCTAssertEqual("INTERNAL", error.localizedDescription)
expectation.fulfill()
} catch {
XCTAssert(false, "Failed to unwrap the function result: \(error)")
}
}
XCTAssert(true)
waitForExpectations(timeout: 5)
}
#if compiler(>=5.5) && canImport(_Concurrency)
@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testUnhandledErrorAsync() async throws {
let function = functions.httpsCallable("unhandledErrorTest")
XCTAssertNotNil(function)
do {
_ = try await function.call([])
} catch {
let error = try XCTUnwrap(error) as NSError
XCTAssertEqual(FunctionsErrorCode.internal.rawValue, error.code)
XCTAssertEqual("INTERNAL", error.localizedDescription)
return
}
XCTAssertFalse(true, "Failed to throw error for missing result")
}
#endif
func testUnknownError() {
let expectation = expectation(description: #function)
let function = functions.httpsCallable("unknownErrorTest")
XCTAssertNotNil(function)
function.call([]) { result, error in
do {
XCTAssertNotNil(error)
let error = try XCTUnwrap(error! as NSError)
XCTAssertEqual(FunctionsErrorCode.internal.rawValue, error.code)
XCTAssertEqual("INTERNAL", error.localizedDescription)
expectation.fulfill()
} catch {
XCTAssert(false, "Failed to unwrap the function result: \(error)")
}
}
XCTAssert(true)
waitForExpectations(timeout: 5)
}
#if compiler(>=5.5) && canImport(_Concurrency)
@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testUnknownErrorAsync() async throws {
let function = functions.httpsCallable("unknownErrorTest")
XCTAssertNotNil(function)
do {
_ = try await function.call([])
} catch {
let error = try XCTUnwrap(error) as NSError
XCTAssertEqual(FunctionsErrorCode.internal.rawValue, error.code)
XCTAssertEqual("INTERNAL", error.localizedDescription)
return
}
XCTAssertFalse(true, "Failed to throw error for missing result")
}
#endif
func testExplicitError() {
let expectation = expectation(description: #function)
let function = functions.httpsCallable("explicitErrorTest")
XCTAssertNotNil(function)
function.call([]) { result, error in
do {
XCTAssertNotNil(error)
let error = try XCTUnwrap(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[FunctionsErrorDetailsKey] as! [String: Int32])
expectation.fulfill()
} catch {
XCTAssert(false, "Failed to unwrap the function result: \(error)")
}
}
XCTAssert(true)
waitForExpectations(timeout: 5)
}
#if compiler(>=5.5) && canImport(_Concurrency)
@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testExplicitErrorAsync() async throws {
let function = functions.httpsCallable("explicitErrorTest")
XCTAssertNotNil(function)
do {
_ = try await function.call([])
} catch {
let error = try XCTUnwrap(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[FunctionsErrorDetailsKey] as! [String: Int32])
return
}
XCTAssertFalse(true, "Failed to throw error for missing result")
}
#endif
func testHttpError() {
let expectation = expectation(description: #function)
let function = functions.httpsCallable("httpErrorTest")
XCTAssertNotNil(function)
function.call([]) { result, error in
do {
XCTAssertNotNil(error)
let error = try XCTUnwrap(error! as NSError)
XCTAssertEqual(FunctionsErrorCode.invalidArgument.rawValue, error.code)
expectation.fulfill()
} catch {
XCTAssert(false, "Failed to unwrap the function result: \(error)")
}
}
XCTAssert(true)
waitForExpectations(timeout: 5)
}
#if compiler(>=5.5) && canImport(_Concurrency)
@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testHttpErrorAsync() async throws {
let function = functions.httpsCallable("httpErrorTest")
XCTAssertNotNil(function)
do {
_ = try await function.call([])
} catch {
let error = try XCTUnwrap(error) as NSError
XCTAssertEqual(FunctionsErrorCode.invalidArgument.rawValue, error.code)
return
}
XCTAssertFalse(true, "Failed to throw error for missing result")
}
#endif
func testTimeout() {
let expectation = expectation(description: #function)
let function = functions.httpsCallable("timeoutTest")
XCTAssertNotNil(function)
function.timeoutInterval = 0.05
function.call([]) { result, error in
do {
XCTAssertNotNil(error)
let error = try XCTUnwrap(error! as NSError)
XCTAssertEqual(FunctionsErrorCode.deadlineExceeded.rawValue, error.code)
XCTAssertEqual("DEADLINE EXCEEDED", error.localizedDescription)
XCTAssertNil(error.userInfo[FunctionsErrorDetailsKey])
expectation.fulfill()
} catch {
XCTAssert(false, "Failed to unwrap the function result: \(error)")
}
}
XCTAssert(true)
waitForExpectations(timeout: 5)
}
#if compiler(>=5.5) && canImport(_Concurrency)
@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testTimeoutAsync() async throws {
let function = functions.httpsCallable("timeoutTest")
XCTAssertNotNil(function)
function.timeoutInterval = 0.05
do {
_ = try await function.call([])
} catch {
let error = try XCTUnwrap(error) as NSError
XCTAssertEqual(FunctionsErrorCode.deadlineExceeded.rawValue, error.code)
XCTAssertEqual("DEADLINE EXCEEDED", error.localizedDescription)
XCTAssertNil(error.userInfo[FunctionsErrorDetailsKey])
return
}
XCTAssertFalse(true, "Failed to throw error for missing result")
}
#endif
}