PropertyWrapperTests.swift 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. * Copyright 2022 Google LLC
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. import FirebaseRemoteConfig
  17. import XCTest
  18. @available(iOS 14.0, macOS 11.0, macCatalyst 14.0, tvOS 14.0, watchOS 7.0, *)
  19. class PropertyWrapperTests: APITestBase {
  20. // MARK: - Test fetching Remote Config JSON values into struct property
  21. struct Recipe: Decodable {
  22. var recipeName: String
  23. var ingredients: [String]
  24. var cookTime: Int
  25. }
  26. static let fallbackString = "fallback"
  27. static let fallbackInt = 50
  28. static let fallbackFloat: Float = 50.2
  29. static let fallbackDouble: Double = 16_777_216.333921
  30. static let fallbackDecimal: Decimal = 235
  31. static let fallbackData = "hello".data(using: .utf8)!
  32. static let fallbackArray = ["mango", "pineapple", "papaya"]
  33. static let fallbackDict = [
  34. "session 0": "breakfast", "session 1": "keynote", "session 2": "state of union",
  35. ]
  36. static let fallbackJSON = Recipe(
  37. recipeName: "muffin", ingredients: ["flour", "sugar"], cookTime: 45
  38. )
  39. struct PropertyWrapperTester {
  40. @RemoteConfigProperty(key: Constants.stringKey, fallback: "")
  41. var stringValue: String!
  42. var stringKeyName: String {
  43. return _stringValue.key
  44. }
  45. @RemoteConfigProperty(key: Constants.intKey, fallback: 0)
  46. var intValue: Int!
  47. var intKeyName: String {
  48. return _intValue.key
  49. }
  50. @RemoteConfigProperty(key: Constants.floatKey, fallback: 0)
  51. var floatValue: Float!
  52. var floatKeyName: String {
  53. return _floatValue.key
  54. }
  55. @RemoteConfigProperty(key: Constants.floatKey, fallback: 0)
  56. var doubleValue: Double!
  57. var doubleKeyName: String {
  58. return _doubleValue.key
  59. }
  60. @RemoteConfigProperty(key: Constants.decimalKey, fallback: 0)
  61. var decimalValue: Decimal!
  62. var decimalKeyName: String {
  63. return _decimalValue.key
  64. }
  65. @RemoteConfigProperty(key: Constants.trueKey, fallback: false)
  66. var trueValue: Bool!
  67. var trueKeyName: String {
  68. return _trueValue.key
  69. }
  70. @RemoteConfigProperty(key: Constants.falseKey, fallback: false)
  71. var falseValue: Bool!
  72. var falseKeyName: String {
  73. return _falseValue.key
  74. }
  75. @RemoteConfigProperty(key: Constants.dataKey, fallback: Data())
  76. var dataValue: Data!
  77. var dataKeyName: String {
  78. return _dataValue.key
  79. }
  80. @RemoteConfigProperty(key: Constants.jsonKey, fallback: nil)
  81. var recipeValue: Recipe!
  82. var recipeKeyName: String {
  83. _recipeValue.key
  84. }
  85. @RemoteConfigProperty(key: Constants.arrayKey, fallback: [])
  86. var arrayValue: [String]!
  87. var arrayKeyName: String {
  88. _arrayValue.key
  89. }
  90. @RemoteConfigProperty(key: Constants.dictKey, fallback: [:])
  91. var dictValue: [String: String]!
  92. var dictKeyName: String {
  93. _dictValue.key
  94. }
  95. }
  96. struct PlaceholderValueTester {
  97. @RemoteConfigProperty(key: "NewKeyNotInSystem", fallback: fallbackString)
  98. var stringValue: String
  99. @RemoteConfigProperty(key: "NewIntKeyNotInSystem", fallback: fallbackInt)
  100. var intValue: Int!
  101. @RemoteConfigProperty(key: "NewZeroKey", fallback: 0)
  102. var zeroIntValue: Int!
  103. @RemoteConfigProperty(key: "newFloatKey", fallback: fallbackFloat)
  104. var floatValue: Float!
  105. @RemoteConfigProperty(key: "newDoubleKey", fallback: fallbackDouble)
  106. var doubleValue: Double!
  107. @RemoteConfigProperty(key: "newDecimalKey", fallback: fallbackDecimal)
  108. var decimalValue: Decimal!
  109. @RemoteConfigProperty(key: "newTrueKey", fallback: false)
  110. var trueKeyFalseValue: Bool!
  111. @RemoteConfigProperty(key: "newTrueKey2", fallback: true)
  112. var trueKeyTrueValue: Bool!
  113. @RemoteConfigProperty(key: "newFalseKey", fallback: true)
  114. var falseKeyTrueValue: Bool!
  115. @RemoteConfigProperty(key: "newFalseKey2", fallback: false)
  116. var falseKeyFalseValue: Bool!
  117. @RemoteConfigProperty(key: "newDataKey", fallback: fallbackData)
  118. var dataValue: Data
  119. @RemoteConfigProperty(key: "newJSONKey", fallback: fallbackJSON)
  120. var recipeValue: Recipe!
  121. @RemoteConfigProperty(key: "newArrayKey", fallback: fallbackArray)
  122. var arrayValue: [String]!
  123. @RemoteConfigProperty(key: "newDictKey", fallback: fallbackDict)
  124. var dictValue: [String: String]!
  125. }
  126. func testFetchAndActivateWithPropertyWrapper() async throws {
  127. let status = try await config.fetchAndActivate()
  128. XCTAssertEqual(status, .successFetchedFromRemote)
  129. let tester = await PropertyWrapperTester()
  130. let stringValue = await tester.stringValue
  131. XCTAssertEqual(stringValue, Constants.stringValue)
  132. let intValue = await tester.intValue
  133. XCTAssertEqual(intValue, Constants.intValue)
  134. let floatValue = await tester.floatValue
  135. XCTAssertEqual(floatValue, Constants.floatValue)
  136. let doubleValue = await tester.doubleValue
  137. XCTAssertEqual(doubleValue, Constants.doubleValue)
  138. let decimalValue = await tester.decimalValue
  139. XCTAssertEqual(decimalValue, Constants.decimalValue)
  140. let trueValue = await tester.trueValue
  141. XCTAssertEqual(trueValue, true)
  142. let falseValue = await tester.falseValue
  143. XCTAssertEqual(falseValue, false)
  144. let dataValue = await tester.dataValue
  145. XCTAssertEqual(dataValue, Constants.dataValue)
  146. let recipe = try XCTUnwrap(config[Constants.jsonKey].decoded(asType: Recipe.self))
  147. let recipeValue = await tester.recipeValue
  148. XCTAssertEqual(recipeValue?.recipeName, recipe.recipeName)
  149. XCTAssertEqual(recipeValue?.ingredients, recipe.ingredients)
  150. XCTAssertEqual(recipeValue?.cookTime, recipe.cookTime)
  151. let arrayValue = await tester.arrayValue
  152. XCTAssertEqual(arrayValue, Constants.arrayValue)
  153. let dictValue = await tester.dictValue
  154. XCTAssertEqual(dictValue, Constants.dictValue)
  155. }
  156. func testPropertyWrapperInstanceValues() async {
  157. let tester = await PropertyWrapperTester()
  158. let stringKeyName = await tester.stringKeyName
  159. XCTAssertEqual(Constants.stringKey, stringKeyName)
  160. let intKeyName = await tester.intKeyName
  161. XCTAssertEqual(Constants.intKey, intKeyName)
  162. let floatKeyName = await tester.floatKeyName
  163. XCTAssertEqual(Constants.floatKey, floatKeyName)
  164. let doubleKeyName = await tester.doubleKeyName
  165. XCTAssertEqual(Constants.floatKey, doubleKeyName)
  166. let decimalKeyName = await tester.decimalKeyName
  167. XCTAssertEqual(Constants.decimalKey, decimalKeyName)
  168. let trueKeyName = await tester.trueKeyName
  169. XCTAssertEqual(Constants.trueKey, trueKeyName)
  170. let falseKeyName = await tester.falseKeyName
  171. XCTAssertEqual(Constants.falseKey, falseKeyName)
  172. let dataKeyName = await tester.dataKeyName
  173. XCTAssertEqual(Constants.dataKey, dataKeyName)
  174. let recipeKeyName = await tester.recipeKeyName
  175. XCTAssertEqual(Constants.jsonKey, recipeKeyName)
  176. let arrayKeyName = await tester.arrayKeyName
  177. XCTAssertEqual(Constants.arrayKey, arrayKeyName)
  178. let dictKeyName = await tester.dictKeyName
  179. XCTAssertEqual(Constants.dictKey, dictKeyName)
  180. }
  181. func testPlaceHolderValues() async throws {
  182. // Make sure the values below are consistent with the property wrapper
  183. // in PlaceholderValueTester
  184. let tester = await PlaceholderValueTester()
  185. let stringValue = await tester.stringValue
  186. XCTAssertEqual(stringValue, PropertyWrapperTests.fallbackString)
  187. let intValue = await tester.intValue
  188. XCTAssertEqual(intValue, PropertyWrapperTests.fallbackInt)
  189. let zeroValue = await tester.zeroIntValue
  190. XCTAssertEqual(zeroValue, 0)
  191. let floatValue = await tester.floatValue
  192. XCTAssertEqual(floatValue, PropertyWrapperTests.fallbackFloat)
  193. let doubleValue = await tester.doubleValue
  194. XCTAssertEqual(doubleValue, PropertyWrapperTests.fallbackDouble)
  195. let decimalValue = await tester.decimalValue
  196. XCTAssertEqual(decimalValue, PropertyWrapperTests.fallbackDecimal)
  197. let trueKeyFalseValue = await tester.trueKeyFalseValue
  198. XCTAssertEqual(trueKeyFalseValue, false)
  199. let trueKeyTrueValue = await tester.trueKeyTrueValue
  200. XCTAssertEqual(trueKeyTrueValue, true)
  201. let falseKeyTrueValue = await tester.falseKeyTrueValue
  202. XCTAssertEqual(falseKeyTrueValue, true)
  203. let falseKeyFalseValue = await tester.falseKeyFalseValue
  204. XCTAssertEqual(falseKeyFalseValue, false)
  205. let dataValue = await tester.dataValue
  206. XCTAssertEqual(dataValue, PropertyWrapperTests.fallbackData)
  207. let arrayValue = await tester.arrayValue
  208. XCTAssertEqual(arrayValue, PropertyWrapperTests.fallbackArray)
  209. let dictValue = await tester.dictValue
  210. XCTAssertEqual(dictValue, PropertyWrapperTests.fallbackDict)
  211. let recipeValue = await tester.recipeValue
  212. XCTAssertEqual(recipeValue?.recipeName, "muffin")
  213. XCTAssertEqual(recipeValue?.ingredients, ["flour", "sugar"])
  214. XCTAssertEqual(recipeValue?.cookTime, 45)
  215. }
  216. }