| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- // Copyright 2024 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.
- @testable import FirebaseFunctions
- import XCTest
- final class FunctionsErrorTests: XCTestCase {
- func testInitWithCode() {
- let error = FunctionsError(.permissionDenied)
- let nsError = error as NSError
- XCTAssertEqual(nsError.domain, "com.firebase.functions")
- XCTAssertEqual(nsError.code, 7)
- XCTAssertEqual(nsError.localizedDescription, "PERMISSION DENIED")
- XCTAssertEqual(nsError.userInfo.count, 1)
- }
- func testInitWithCodeAndUserInfo() {
- let error = FunctionsError(.unimplemented, userInfo: ["TEST_Key": "TEST_Value"])
- let nsError = error as NSError
- XCTAssertEqual(nsError.domain, "com.firebase.functions")
- XCTAssertEqual(nsError.code, 12)
- XCTAssertEqual(
- nsError.localizedDescription,
- "The operation couldn’t be completed. (com.firebase.functions error 12.)"
- )
- XCTAssertEqual(nsError.userInfo.count, 1)
- XCTAssertEqual(nsError.userInfo["TEST_Key"] as? String, "TEST_Value")
- }
- func testInitWithOKStatusCodeAndNoErrorBody() {
- // The error should be `nil`.
- let error = FunctionsError(
- httpStatusCode: 200,
- region: "my-region",
- url: URL(string: "https://example.com/fake_func")!,
- body: nil,
- serializer: FunctionsSerializer()
- )
- XCTAssertNil(error)
- }
- func testInitWithErrorStatusCodeAndNoErrorBody() {
- // The error should be inferred from the HTTP status code.
- let error = FunctionsError(
- httpStatusCode: 429,
- region: "my-region",
- url: URL(string: "https://example.com/fake_func")!,
- body: nil,
- serializer: FunctionsSerializer()
- )
- guard let error else { return XCTFail("Unexpected `nil` value") }
- let nsError = error as NSError
- XCTAssertEqual(nsError.domain, "com.firebase.functions")
- XCTAssertEqual(nsError.code, 8)
- XCTAssertEqual(nsError.localizedDescription, "RESOURCE EXHAUSTED")
- XCTAssertEqual(nsError.userInfo.count, 3)
- }
- func testInitWithOKStatusCodeAndIncompleteErrorBody() {
- // The status code in the error body takes precedence over the HTTP status code.
- let responseData = #"{ "error": { "status": "OUT_OF_RANGE" } }"#.data(using: .utf8)!
- let error = FunctionsError(
- httpStatusCode: 200,
- region: "my-region",
- url: URL(string: "https://example.com/fake_func")!,
- body: responseData,
- serializer: FunctionsSerializer()
- )
- guard let error else { return XCTFail("Unexpected `nil` value") }
- let nsError = error as NSError
- XCTAssertEqual(nsError.domain, "com.firebase.functions")
- XCTAssertEqual(nsError.code, 11)
- XCTAssertEqual(nsError.localizedDescription, "OUT OF RANGE")
- XCTAssertEqual(nsError.userInfo.count, 3)
- }
- func testInitWithErrorStatusCodeAndErrorBody() {
- // The status code in the error body takes precedence over the HTTP status code.
- let responseData =
- #"{ "error": { "status": "OUT_OF_RANGE", "message": "TEST_ErrorMessage", "details": 123 } }"#
- .data(using: .utf8)!
- let error = FunctionsError(
- httpStatusCode: 499,
- region: "my-region",
- url: URL(string: "https://example.com/fake_func")!,
- body: responseData,
- serializer: FunctionsSerializer()
- )
- guard let error else { return XCTFail("Unexpected `nil` value") }
- let nsError = error as NSError
- XCTAssertEqual(nsError.domain, "com.firebase.functions")
- XCTAssertEqual(nsError.code, 11)
- XCTAssertEqual(nsError.localizedDescription, "TEST_ErrorMessage")
- XCTAssertEqual(nsError.userInfo.count, 4)
- XCTAssertEqual(nsError.userInfo["details"] as? Int, 123)
- }
- func testInitWithErrorStatusCodeAndOKErrorBody() {
- // When the status code in the error body is `OK`, error should be `nil` regardless of the HTTP
- // status code.
- let responseData =
- #"{ "error": { "status": "OK", "message": "TEST_ErrorMessage", "details": 123 } }"#
- .data(using: .utf8)!
- let error = FunctionsError(
- httpStatusCode: 401,
- region: "my-region",
- url: URL(string: "https://example.com/fake_func")!,
- body: responseData,
- serializer: FunctionsSerializer()
- )
- XCTAssertNil(error)
- }
- func testInitWithErrorStatusCodeAndIncompleteErrorBody() {
- // The error name is not in the body; it should be inferred from the HTTP status code.
- let responseData = #"{ "error": { "message": "TEST_ErrorMessage", "details": null } }"#
- .data(using: .utf8)!
- let error = FunctionsError(
- httpStatusCode: 403,
- region: "my-region",
- url: URL(string: "https://example.com/fake_func")!,
- body: responseData,
- serializer: FunctionsSerializer()
- )
- guard let error else { return XCTFail("Unexpected `nil` value") }
- let nsError = error as NSError
- XCTAssertEqual(nsError.domain, "com.firebase.functions")
- XCTAssertEqual(nsError.code, 7) // `permissionDenied`, inferred from the HTTP status code
- XCTAssertEqual(nsError.localizedDescription, "TEST_ErrorMessage")
- XCTAssertEqual(nsError.userInfo.count, 4)
- XCTAssertEqual(nsError.userInfo["details"] as? NSNull, NSNull())
- }
- func testInitWithErrorStatusCodeAndInvalidErrorBody() {
- // An unsupported status code in the error body should result in the rest of the body ignored.
- let responseData =
- #"{ "error": { "status": "TEST_UNKNOWN_ERROR", "message": "TEST_ErrorMessage", "details": 123 } }"#
- .data(using: .utf8)!
- let error = FunctionsError(
- httpStatusCode: 503,
- region: "my-region",
- url: URL(string: "https://example.com/fake_func")!,
- body: responseData,
- serializer: FunctionsSerializer()
- )
- guard let error else { return XCTFail("Unexpected `nil` value") }
- let nsError = error as NSError
- XCTAssertEqual(nsError.domain, "com.firebase.functions")
- // Currently, `internal` is used as the fallback error code. Is this correct?
- // Seems like we could get more information from the HTTP status code in such cases.
- XCTAssertEqual(nsError.code, 13)
- XCTAssertEqual(nsError.localizedDescription, "INTERNAL")
- XCTAssertEqual(nsError.userInfo.count, 1)
- }
- }
|