// 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 FirebaseRemoteConfig import FirebaseRemoteConfigSwift import XCTest #if compiler(>=5.5.2) && canImport(_Concurrency) @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *) class ValueTests: APITestBase { func testFetchAndActivateAllTypes() async throws { let status = try await config.fetchAndActivate() XCTAssertEqual(status, .successFetchedFromRemote) XCTAssertEqual(config[Constants.stringKey].stringValue, Constants.stringValue) XCTAssertEqual(config[Constants.intKey].numberValue.intValue, Constants.intValue) XCTAssertEqual(config[Constants.intKey].numberValue.int8Value, Int8(Constants.intValue)) XCTAssertEqual(config[Constants.intKey].numberValue.int16Value, Int16(Constants.intValue)) XCTAssertEqual(config[Constants.intKey].numberValue.int32Value, Int32(Constants.intValue)) XCTAssertEqual(config[Constants.intKey].numberValue.int64Value, Int64(Constants.intValue)) XCTAssertEqual(config[Constants.intKey].numberValue.uintValue, UInt(Constants.intValue)) XCTAssertEqual(config[Constants.intKey].numberValue.uint8Value, UInt8(Constants.intValue)) XCTAssertEqual(config[Constants.intKey].numberValue.uint16Value, UInt16(Constants.intValue)) XCTAssertEqual(config[Constants.intKey].numberValue.uint32Value, UInt32(Constants.intValue)) XCTAssertEqual(config[Constants.intKey].numberValue.uint64Value, UInt64(Constants.intValue)) XCTAssertEqual( config[Constants.floatKey].numberValue.decimalValue, Decimal(Constants.doubleValue) ) XCTAssertEqual(config[Constants.floatKey].numberValue.floatValue, Constants.floatValue) XCTAssertEqual(config[Constants.floatKey].numberValue.doubleValue, Constants.doubleValue) XCTAssertEqual(config[Constants.trueKey].boolValue, true) XCTAssertEqual(config[Constants.falseKey].boolValue, false) XCTAssertEqual( config[Constants.stringKey].dataValue, Constants.stringValue.data(using: .utf8) ) XCTAssertEqual( config[Constants.jsonKey].jsonValue as! [String: AnyHashable], Constants.jsonValue ) } func testStrongTypingViaSubscriptApi() async throws { let status = try await config.fetchAndActivate() XCTAssertEqual(status, .successFetchedFromRemote) XCTAssertEqual(config[decodedValue: Constants.stringKey], Constants.stringValue) XCTAssertEqual(config[decodedValue: Constants.intKey], Constants.intValue) XCTAssertEqual(config[decodedValue: Constants.floatKey], Constants.floatValue) XCTAssertEqual(config[decodedValue: Constants.floatKey], Constants.doubleValue) XCTAssertEqual(config[decodedValue: Constants.trueKey], true) XCTAssertEqual(config[decodedValue: Constants.falseKey], false) XCTAssertEqual( config[decodedValue: Constants.stringKey], Constants.stringValue.data(using: .utf8) ) XCTAssertEqual(try XCTUnwrap(config[jsonValue: Constants.jsonKey]), Constants.jsonValue) } func testStrongTypingViaDecoder() async throws { let status = try await config.fetchAndActivate() XCTAssertEqual(status, .successFetchedFromRemote) XCTAssertEqual( try config[Constants.stringKey].decoded(asType: String.self), Constants.stringValue ) XCTAssertEqual(try config[Constants.intKey].decoded(asType: Int.self), Constants.intValue) XCTAssertEqual( try config[Constants.intKey].decoded(asType: Int8.self), Int8(Constants.intValue) ) XCTAssertEqual( try config[Constants.intKey].decoded(asType: Int16.self), Int16(Constants.intValue) ) XCTAssertEqual( try config[Constants.intKey].decoded(asType: Int32.self), Int32(Constants.intValue) ) XCTAssertEqual( try config[Constants.intKey].decoded(asType: Int64.self), Int64(Constants.intValue) ) XCTAssertEqual( try config[Constants.intKey].decoded(asType: UInt.self), UInt(Constants.intValue) ) XCTAssertEqual( try config[Constants.intKey].decoded(asType: UInt8.self), UInt8(Constants.intValue) ) XCTAssertEqual( try config[Constants.intKey].decoded(asType: UInt16.self), UInt16(Constants.intValue) ) XCTAssertEqual( try config[Constants.intKey].decoded(asType: UInt32.self), UInt32(Constants.intValue) ) XCTAssertEqual( try config[Constants.intKey].decoded(asType: UInt64.self), UInt64(Constants.intValue) ) XCTAssertEqual( try config[Constants.floatKey].decoded(asType: Decimal.self), Decimal(Constants.doubleValue) ) XCTAssertEqual( try config[Constants.floatKey].decoded(asType: Float.self), Constants.floatValue ) XCTAssertEqual( try config[Constants.floatKey].decoded(asType: Double.self), Constants.doubleValue ) XCTAssertEqual(try config[Constants.trueKey].decoded(asType: Bool.self), true) XCTAssertEqual(try config[Constants.falseKey].decoded(asType: Bool.self), false) XCTAssertEqual( try config[Constants.stringKey].decoded(asType: Data.self), Constants.stringValue.data(using: .utf8) ) } func testStrongTypingViaDecoderAlternateDecoderApi() async throws { let status = try await config.fetchAndActivate() XCTAssertEqual(status, .successFetchedFromRemote) let myString: String = try config[Constants.stringKey].decoded() XCTAssertEqual(myString, Constants.stringValue) let myInt: Int = try config[Constants.intKey].decoded() XCTAssertEqual(myInt, Constants.intValue) let myInt8: Int8 = try config[Constants.intKey].decoded() XCTAssertEqual(myInt8, Int8(Constants.intValue)) let myInt16: Int16 = try config[Constants.intKey].decoded() XCTAssertEqual(myInt16, Int16(Constants.intValue)) let myInt32: Int32 = try config[Constants.intKey].decoded() XCTAssertEqual(myInt32, Int32(Constants.intValue)) let myInt64: Int64 = try config[Constants.intKey].decoded() XCTAssertEqual(myInt64, Int64(Constants.intValue)) let myUInt: UInt = try config[Constants.intKey].decoded() XCTAssertEqual(myUInt, UInt(Constants.intValue)) let myUInt8: UInt8 = try config[Constants.intKey].decoded() XCTAssertEqual(myUInt8, UInt8(Constants.intValue)) let myUInt16: UInt16 = try config[Constants.intKey].decoded() XCTAssertEqual(myUInt16, UInt16(Constants.intValue)) let myUInt32: UInt32 = try config[Constants.intKey].decoded() XCTAssertEqual(myUInt32, UInt32(Constants.intValue)) let myUInt64: UInt64 = try config[Constants.intKey].decoded() XCTAssertEqual(myUInt64, UInt64(Constants.intValue)) let myDecimal: Decimal = try config[Constants.floatKey].decoded() XCTAssertEqual(myDecimal, Decimal(Constants.doubleValue)) let myFloat: Float = try config[Constants.floatKey].decoded() XCTAssertEqual(myFloat, Constants.floatValue) let myDouble: Double = try config[Constants.floatKey].decoded() XCTAssertEqual(myDouble, Constants.doubleValue) let myTrue: Bool = try config[Constants.trueKey].decoded() XCTAssertEqual(myTrue, true) let myFalse: Bool = try config[Constants.falseKey].decoded() XCTAssertEqual(myFalse, false) let myData: Data = try config[Constants.stringKey].decoded() XCTAssertEqual(myData, Constants.stringValue.data(using: .utf8)) } func testStringFails() { XCTAssertEqual(config[decodedValue: "UndefinedKey"], "") } func testJSONFails() { XCTAssertNil(config[jsonValue: "UndefinedKey"]) XCTAssertNil(config[jsonValue: Constants.stringKey]) } func testDateDecodingNotYetSupported() async throws { let status = try await config.fetchAndActivate() XCTAssertEqual(status, .successFetchedFromRemote) do { let _: Date = try config[Constants.stringKey].decoded() } catch let RemoteConfigValueCodableError.unsupportedType(message) { XCTAssertEqual(message, "Date type is not currently supported for Remote Config Value decoding. " + "Please file a feature request") return } XCTFail("Failed to throw unsupported Date error.") } } #endif