ContextProviderTests.swift 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // Copyright 2022 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. import Foundation
  15. import FirebaseCore
  16. @testable import FirebaseFunctions
  17. import FirebaseAppCheckInterop
  18. import FirebaseAuthInterop
  19. import FirebaseMessagingInterop
  20. import SharedTestUtilities
  21. import XCTest
  22. class ContextProviderTests: XCTestCase {
  23. let appCheckFake = FIRAppCheckFake()
  24. let appCheckTokenError = FIRAppCheckTokenResultFake(token: "dummy token",
  25. error: NSError(
  26. domain: "testAppCheckError",
  27. code: -1,
  28. userInfo: nil
  29. ))
  30. let appCheckTokenSuccess = FIRAppCheckTokenResultFake(token: "valid_token", error: nil)
  31. let messagingFake = FIRMessagingInteropFake()
  32. func testContextWithAuth() {
  33. let auth = FIRAuthInteropFake(token: "token", userID: "userID", error: nil)
  34. let provider = FunctionsContextProvider(auth: auth, messaging: messagingFake, appCheck: nil)
  35. let expectation = expectation(description: "Context should have auth keys.")
  36. provider.getContext { context, error in
  37. XCTAssertNotNil(context)
  38. XCTAssertEqual(context.authToken, "token")
  39. XCTAssertEqual(context.fcmToken, self.messagingFake.fcmToken)
  40. XCTAssertNil(error)
  41. expectation.fulfill()
  42. }
  43. waitForExpectations(timeout: 0.1)
  44. }
  45. func testContextWithAuthError() {
  46. let authError = NSError(domain: "com.functions.tests", code: 4, userInfo: nil)
  47. let auth = FIRAuthInteropFake(token: nil, userID: "userID", error: authError)
  48. let provider = FunctionsContextProvider(auth: auth, messaging: messagingFake, appCheck: nil)
  49. let expectation = expectation(description: "Completion handler should fail with Auth error.")
  50. provider.getContext { context, error in
  51. XCTAssertNotNil(context)
  52. XCTAssertNil(context.authToken)
  53. XCTAssertEqual(error as NSError?, authError)
  54. expectation.fulfill()
  55. }
  56. waitForExpectations(timeout: 0.1)
  57. }
  58. func testContextWithoutAuth() {
  59. let provider = FunctionsContextProvider(auth: nil, messaging: nil, appCheck: nil)
  60. let expectation = expectation(description: "Completion handler should succeed without Auth.")
  61. provider.getContext { context, error in
  62. XCTAssertNotNil(context)
  63. XCTAssertNil(error)
  64. XCTAssertNil(context.authToken)
  65. XCTAssertNil(context.fcmToken)
  66. expectation.fulfill()
  67. }
  68. waitForExpectations(timeout: 0.1)
  69. }
  70. func testContextWithAppCheckOnlySuccess() {
  71. appCheckFake.tokenResult = appCheckTokenSuccess
  72. let provider = FunctionsContextProvider(auth: nil, messaging: nil, appCheck: appCheckFake)
  73. let expectation = expectation(description: "Verify app check.")
  74. provider.getContext { context, error in
  75. XCTAssertNotNil(context)
  76. XCTAssertNil(error)
  77. XCTAssertNil(context.authToken)
  78. XCTAssertNil(context.fcmToken)
  79. XCTAssertEqual(context.appCheckToken, self.appCheckTokenSuccess.token)
  80. expectation.fulfill()
  81. }
  82. waitForExpectations(timeout: 0.1)
  83. }
  84. func testContextWithAppCheckOnlyError() {
  85. appCheckFake.tokenResult = appCheckTokenError
  86. let provider = FunctionsContextProvider(auth: nil, messaging: nil, appCheck: appCheckFake)
  87. let expectation = expectation(description: "Verify bad app check token")
  88. provider.getContext { context, error in
  89. XCTAssertNotNil(context)
  90. XCTAssertNil(error)
  91. XCTAssertNil(context.authToken)
  92. XCTAssertNil(context.fcmToken)
  93. // Don't expect any token in the case of App Check error.
  94. XCTAssertNil(context.appCheckToken)
  95. expectation.fulfill()
  96. }
  97. waitForExpectations(timeout: 0.1)
  98. }
  99. func testContextWithAppCheckWithoutOptionalMethods() {
  100. let appCheck = AppCheckFakeWithoutOptionalMethods(tokenResult: appCheckTokenSuccess)
  101. let provider = FunctionsContextProvider(auth: nil, messaging: nil, appCheck: appCheck)
  102. let expectation =
  103. expectation(description: "Verify non-implemented method for limited-use tokens")
  104. provider.getContext(options: .init(requireLimitedUseAppCheckTokens: true)) { context, error in
  105. XCTAssertNotNil(context)
  106. XCTAssertNil(error)
  107. XCTAssertNil(context.authToken)
  108. XCTAssertNil(context.fcmToken)
  109. XCTAssertNil(context.appCheckToken)
  110. // If the method for limited-use tokens is not implemented, the value should be `nil`:
  111. XCTAssertNil(context.limitedUseAppCheckToken)
  112. expectation.fulfill()
  113. }
  114. // Importantly, `getContext(options:_:)` must still finish in a timely manner:
  115. waitForExpectations(timeout: 0.1)
  116. }
  117. func testAllContextsAvailableSuccess() {
  118. appCheckFake.tokenResult = appCheckTokenSuccess
  119. let auth = FIRAuthInteropFake(token: "token", userID: "userID", error: nil)
  120. let provider = FunctionsContextProvider(
  121. auth: auth,
  122. messaging: messagingFake,
  123. appCheck: appCheckFake
  124. )
  125. let expectation = expectation(description: "All contexts available")
  126. provider.getContext { context, error in
  127. XCTAssertNotNil(context)
  128. XCTAssertNil(error)
  129. XCTAssertEqual(context.authToken, "token")
  130. XCTAssertEqual(context.fcmToken, self.messagingFake.fcmToken)
  131. XCTAssertEqual(context.appCheckToken, self.appCheckTokenSuccess.token)
  132. expectation.fulfill()
  133. }
  134. waitForExpectations(timeout: 0.1)
  135. }
  136. func testAllContextsAuthAndAppCheckError() {
  137. appCheckFake.tokenResult = appCheckTokenError
  138. let authError = NSError(domain: "com.functions.tests", code: 4, userInfo: nil)
  139. let auth = FIRAuthInteropFake(token: nil, userID: "userID", error: authError)
  140. let provider = FunctionsContextProvider(
  141. auth: auth,
  142. messaging: messagingFake,
  143. appCheck: appCheckFake
  144. )
  145. let expectation = expectation(description: "All contexts with errors")
  146. provider.getContext { context, error in
  147. XCTAssertNotNil(context)
  148. XCTAssertEqual(error as NSError?, authError)
  149. XCTAssertNil(context.authToken)
  150. XCTAssertEqual(context.fcmToken, self.messagingFake.fcmToken)
  151. // Don't expect any token in the case of App Check error.
  152. XCTAssertNil(context.appCheckToken)
  153. expectation.fulfill()
  154. }
  155. waitForExpectations(timeout: 0.1)
  156. }
  157. }
  158. // MARK: - Utilities
  159. private class AppCheckFakeWithoutOptionalMethods: NSObject, AppCheckInterop {
  160. let tokenResult: FIRAppCheckTokenResultInterop
  161. init(tokenResult: FIRAppCheckTokenResultInterop) {
  162. self.tokenResult = tokenResult
  163. }
  164. func getToken(forcingRefresh: Bool, completion handler: @escaping AppCheckTokenHandlerInterop) {
  165. handler(tokenResult)
  166. }
  167. func tokenDidChangeNotificationName() -> String { "AppCheckFakeTokenDidChangeNotification" }
  168. func notificationTokenKey() -> String { "AppCheckFakeTokenNotificationKey" }
  169. func notificationAppNameKey() -> String { "AppCheckFakeAppNameNotificationKey" }
  170. }