mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-11 22:55:59 +05:45
483 lines
16 KiB
Swift
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
|
|
}
|