FirebaseAppTests.swift 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. // Copyright 2020 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. @testable import FirebaseCore
  15. import XCTest
  16. private extension Constants {
  17. static let testAppName1 = "test_app_name_1"
  18. static let testAppName2 = "test_app_name_2"
  19. }
  20. class FirebaseAppTests: XCTestCase {
  21. override func setUp() {
  22. super.setUp()
  23. FIROptionsMock.mockFIROptions()
  24. }
  25. override func tearDown() {
  26. super.tearDown()
  27. FirebaseApp.resetApps()
  28. }
  29. func testConfigure() throws {
  30. expectAppConfigurationNotification(appName: Constants.App.defaultName, isDefaultApp: true)
  31. let configurationAttempt = {
  32. try ExceptionCatcher.catchException {
  33. FirebaseApp.configure()
  34. }
  35. }
  36. XCTAssertNoThrow(try configurationAttempt())
  37. let app = try XCTUnwrap(FirebaseApp.app(), "Failed to unwrap default app")
  38. XCTAssertEqual(app.name, Constants.App.defaultName)
  39. XCTAssertEqual(app.options.clientID, Constants.Options.clientID)
  40. XCTAssertEqual(FirebaseApp.allApps?.count, 1)
  41. // TODO: check registered libraries instances available
  42. waitForExpectations(timeout: 1)
  43. }
  44. func testIsDefaultAppConfigured() {
  45. XCTAssertFalse(FirebaseApp.isDefaultAppConfigured())
  46. expectAppConfigurationNotification(appName: Constants.App.defaultName, isDefaultApp: true)
  47. let configurationAttempt = {
  48. try ExceptionCatcher.catchException {
  49. FirebaseApp.configure()
  50. }
  51. }
  52. XCTAssertNoThrow(try configurationAttempt())
  53. XCTAssertTrue(FirebaseApp.isDefaultAppConfigured())
  54. waitForExpectations(timeout: 1)
  55. }
  56. func testConfigureDefaultAppTwice() {
  57. let firstConfigurationAttempt = {
  58. try ExceptionCatcher.catchException {
  59. FirebaseApp.configure()
  60. }
  61. }
  62. XCTAssertNoThrow(try firstConfigurationAttempt())
  63. let secondConfigurationAttempt = {
  64. try ExceptionCatcher.catchException {
  65. FirebaseApp.configure()
  66. }
  67. }
  68. XCTAssertThrowsError(try secondConfigurationAttempt())
  69. }
  70. func testConfigureWithOptions() throws {
  71. expectAppConfigurationNotification(appName: Constants.App.defaultName, isDefaultApp: true)
  72. let options = FirebaseOptions(googleAppID: Constants.Options.googleAppID,
  73. gcmSenderID: Constants.Options.gcmSenderID)
  74. options.clientID = Constants.Options.clientID
  75. let configurationAttempt = {
  76. try ExceptionCatcher.catchException {
  77. FirebaseApp.configure(options: options)
  78. }
  79. }
  80. XCTAssertNoThrow(try configurationAttempt())
  81. let app = try XCTUnwrap(FirebaseApp.app(), "Failed to unwrap default app")
  82. XCTAssertEqual(app.name, Constants.App.defaultName)
  83. XCTAssertEqual(app.options.googleAppID, Constants.Options.googleAppID)
  84. XCTAssertEqual(app.options.gcmSenderID, Constants.Options.gcmSenderID)
  85. XCTAssertEqual(app.options.clientID, Constants.Options.clientID)
  86. XCTAssertTrue(FirebaseApp.allApps?.count == 1)
  87. waitForExpectations(timeout: 1)
  88. }
  89. func testConfigureWithNameAndOptions() throws {
  90. expectAppConfigurationNotification(appName: Constants.testAppName1, isDefaultApp: false)
  91. let options = FirebaseOptions(googleAppID: Constants.Options.googleAppID,
  92. gcmSenderID: Constants.Options.gcmSenderID)
  93. options.clientID = Constants.Options.clientID
  94. let configurationAttempt = {
  95. try ExceptionCatcher.catchException {
  96. FirebaseApp.configure(name: Constants.testAppName1, options: options)
  97. }
  98. }
  99. XCTAssertNoThrow(try configurationAttempt())
  100. let app = try XCTUnwrap(
  101. FirebaseApp.app(name: Constants.testAppName1),
  102. "Failed to unwrap custom named app"
  103. )
  104. XCTAssertEqual(app.name, Constants.testAppName1)
  105. XCTAssertEqual(app.options.googleAppID, Constants.Options.googleAppID)
  106. XCTAssertEqual(app.options.gcmSenderID, Constants.Options.gcmSenderID)
  107. XCTAssertEqual(app.options.clientID, Constants.Options.clientID)
  108. XCTAssertTrue(FirebaseApp.allApps?.count == 1)
  109. let configureAppAgain = {
  110. try ExceptionCatcher.catchException {
  111. FirebaseApp.configure(name: Constants.testAppName1, options: options)
  112. }
  113. }
  114. XCTAssertThrowsError(try configureAppAgain())
  115. waitForExpectations(timeout: 1)
  116. }
  117. func testConfigureMultipleApps() throws {
  118. let options1 = FirebaseOptions(googleAppID: Constants.Options.googleAppID,
  119. gcmSenderID: Constants.Options.gcmSenderID)
  120. expectAppConfigurationNotification(appName: Constants.testAppName1, isDefaultApp: false)
  121. XCTAssertNoThrow(FirebaseApp.configure(name: Constants.testAppName1, options: options1))
  122. let app1 = try XCTUnwrap(FirebaseApp.app(name: Constants.testAppName1), "Failed to unwrap app1")
  123. XCTAssertEqual(app1.name, Constants.testAppName1)
  124. XCTAssertEqual(app1.options.googleAppID, Constants.Options.googleAppID)
  125. XCTAssertEqual(app1.options.gcmSenderID, Constants.Options.gcmSenderID)
  126. XCTAssertTrue(FirebaseApp.allApps?.count == 1)
  127. // Configure a different app with valid customized options.
  128. let options2 = FirebaseOptions(googleAppID: Constants.Options.googleAppID,
  129. gcmSenderID: Constants.Options.gcmSenderID)
  130. options2.bundleID = Constants.Options.bundleID
  131. options2.apiKey = Constants.Options.apiKey
  132. expectAppConfigurationNotification(appName: Constants.testAppName2, isDefaultApp: false)
  133. let configureApp2Attempt = {
  134. try ExceptionCatcher.catchException {
  135. FirebaseApp.configure(name: Constants.testAppName2, options: options2)
  136. }
  137. }
  138. XCTAssertNoThrow(try configureApp2Attempt())
  139. let app2 = try XCTUnwrap(FirebaseApp.app(name: Constants.testAppName2), "Failed to unwrap app2")
  140. XCTAssertEqual(app2.name, Constants.testAppName2)
  141. XCTAssertEqual(app2.options.googleAppID, Constants.Options.googleAppID)
  142. XCTAssertEqual(app2.options.gcmSenderID, Constants.Options.gcmSenderID)
  143. XCTAssertEqual(app2.options.bundleID, Constants.Options.bundleID)
  144. XCTAssertEqual(app2.options.apiKey, Constants.Options.apiKey)
  145. XCTAssertTrue(FirebaseApp.allApps?.count == 2)
  146. waitForExpectations(timeout: 1)
  147. }
  148. func testGetUninitializedDefaultApp() {
  149. let app = FirebaseApp.app()
  150. XCTAssertNil(app)
  151. }
  152. func testGetInitializedDefaultApp() {
  153. FirebaseApp.configure()
  154. let app = FirebaseApp.app()
  155. XCTAssertNotNil(app)
  156. }
  157. func testGetExistingAppWithName() throws {
  158. // Configure a different app with valid customized options.
  159. let options = try XCTUnwrap(FirebaseOptions.defaultOptions(), "Could not load default options")
  160. FirebaseApp.configure(name: Constants.testAppName1, options: options)
  161. let app = FirebaseApp.app(name: Constants.testAppName1)
  162. XCTAssertNotNil(app, "Failed to get app")
  163. }
  164. func testAttemptToGetNonExistingAppWithName() {
  165. let unknownAppName = "The Missing App"
  166. let app = FirebaseApp.app(name: unknownAppName)
  167. XCTAssertNil(app)
  168. }
  169. func testAllApps() throws {
  170. XCTAssertNil(FirebaseApp.allApps)
  171. let options1 = FirebaseOptions(googleAppID: Constants.Options.googleAppID,
  172. gcmSenderID: Constants.Options.gcmSenderID)
  173. FirebaseApp.configure(name: Constants.testAppName1, options: options1)
  174. let app1 = try XCTUnwrap(
  175. FirebaseApp.app(name: Constants.testAppName1),
  176. "App1 could not be unwrapped"
  177. )
  178. let options2 = FirebaseOptions(googleAppID: Constants.Options.googleAppID,
  179. gcmSenderID: Constants.Options.gcmSenderID)
  180. FirebaseApp.configure(name: Constants.testAppName2, options: options2)
  181. let app2 = try XCTUnwrap(
  182. FirebaseApp.app(name: Constants.testAppName2),
  183. "App2 could not be unwrapped"
  184. )
  185. let apps = try XCTUnwrap(FirebaseApp.allApps, "Could not retrieve apps")
  186. XCTAssertEqual(apps.count, 2)
  187. XCTAssertTrue(apps.keys.contains(Constants.testAppName1))
  188. XCTAssertEqual(apps[Constants.testAppName1], app1)
  189. XCTAssertTrue(apps.keys.contains(Constants.testAppName2))
  190. XCTAssertEqual(apps[Constants.testAppName2], app2)
  191. }
  192. func testDeleteApp() throws {
  193. XCTAssertNil(FirebaseApp.app(name: Constants.testAppName1))
  194. XCTAssertNil(FirebaseApp.allApps)
  195. expectAppConfigurationNotification(appName: Constants.testAppName1, isDefaultApp: false)
  196. let options = FirebaseOptions(googleAppID: Constants.Options.googleAppID,
  197. gcmSenderID: Constants.Options.gcmSenderID)
  198. FirebaseApp.configure(name: Constants.testAppName1, options: options)
  199. let app = try XCTUnwrap(FirebaseApp.app(name: Constants.testAppName1), "Could not unwrap app")
  200. let apps = try XCTUnwrap(FirebaseApp.allApps, "Could not retrieve app dictionary")
  201. XCTAssertTrue(apps.keys.contains(app.name))
  202. let appDeletedExpectation = expectation(description: #function)
  203. app.delete { success in
  204. XCTAssertTrue(success)
  205. XCTAssertFalse(FirebaseApp.allApps?.keys.contains(Constants.testAppName1) ?? false)
  206. appDeletedExpectation.fulfill()
  207. }
  208. waitForExpectations(timeout: 1)
  209. }
  210. func testGetNameOfDefaultApp() throws {
  211. FirebaseApp.configure()
  212. let defaultApp = try XCTUnwrap(FirebaseApp.app(), "Could not unwrap default app")
  213. XCTAssertEqual(defaultApp.name, Constants.App.defaultName)
  214. }
  215. func testGetNameOfApp() throws {
  216. XCTAssertNil(FirebaseApp.app(name: Constants.testAppName1))
  217. let options = FirebaseOptions(googleAppID: Constants.Options.googleAppID,
  218. gcmSenderID: Constants.Options.gcmSenderID)
  219. FirebaseApp.configure(name: Constants.testAppName1, options: options)
  220. let app = try XCTUnwrap(
  221. FirebaseApp.app(name: Constants.testAppName1),
  222. "Failed to unwrap custom named app"
  223. )
  224. XCTAssertEqual(app.name, Constants.testAppName1)
  225. }
  226. func testOptionsForApp() throws {
  227. FirebaseApp.configure()
  228. let defaultApp = try XCTUnwrap(FirebaseApp.app(), "Could not unwrap default app")
  229. let defaultOptions = FirebaseOptions.defaultOptions()
  230. XCTAssertEqual(defaultApp.options, defaultOptions)
  231. let options = FirebaseOptions(googleAppID: Constants.Options.googleAppID,
  232. gcmSenderID: Constants.Options.gcmSenderID)
  233. FirebaseApp.configure(name: Constants.testAppName1, options: options)
  234. let app = try XCTUnwrap(
  235. FirebaseApp.app(name: Constants.testAppName1),
  236. "Could not unwrap custom named app"
  237. )
  238. XCTAssertEqual(app.name, Constants.testAppName1)
  239. XCTAssertEqual(app.options.googleAppID, Constants.Options.googleAppID)
  240. XCTAssertEqual(app.options.gcmSenderID, Constants.Options.gcmSenderID)
  241. }
  242. func testFirebaseDataCollectionDefaultEnabled() throws {
  243. let app = FirebaseApp(instanceWithName: "emptyApp",
  244. options: FirebaseOptions(googleAppID: Constants.Options.googleAppID,
  245. gcmSenderID: Constants.Options.gcmSenderID))
  246. // defaults to true unless otherwise set to no in app's Info.plist
  247. XCTAssertTrue(app.isDataCollectionDefaultEnabled)
  248. app.isDataCollectionDefaultEnabled = false
  249. XCTAssertFalse(app.isDataCollectionDefaultEnabled)
  250. // Cleanup
  251. app.isDataCollectionDefaultEnabled = true
  252. let expectation = expectation(description: #function)
  253. app.delete { success in
  254. expectation.fulfill()
  255. }
  256. waitForExpectations(timeout: 1)
  257. }
  258. // MARK: - Firebase User Agent
  259. func testUserAgent() {
  260. let agent = FirebaseApp.firebaseUserAgent()
  261. XCTAssertTrue(agent.contains("apple-platform"))
  262. XCTAssertTrue(agent.contains("apple-sdk"))
  263. XCTAssertTrue(agent.contains("appstore"))
  264. XCTAssertTrue(agent.contains("deploy"))
  265. XCTAssertTrue(agent.contains("device"))
  266. XCTAssertTrue(agent.contains("os-version"))
  267. XCTAssertTrue(agent.contains("xcode"))
  268. }
  269. // MARK: - Helpers
  270. private func expectAppConfigurationNotification(appName: String, isDefaultApp: Bool) {
  271. let expectedUserInfo: [String: Any] = [
  272. "FIRAppNameKey": appName,
  273. "FIRAppIsDefaultAppKey": NSNumber(value: isDefaultApp),
  274. "FIRGoogleAppIDKey": Constants.Options.googleAppID,
  275. ]
  276. expectation(forNotification: NSNotification.Name.firAppReadyToConfigureSDK,
  277. object: FirebaseApp.self, handler: { notification -> Bool in
  278. guard let userInfo = notification.userInfo else {
  279. XCTFail("Failed to unwrap notification user info")
  280. return false
  281. }
  282. return NSDictionary(dictionary: expectedUserInfo) ==
  283. NSDictionary(dictionary: userInfo)
  284. })
  285. }
  286. }