SignInWithGameCenterTests.swift 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright 2021 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 Combine
  16. import XCTest
  17. import FirebaseAuth
  18. class SignInWithGameCenterTests: XCTestCase {
  19. override class func setUp() {
  20. FirebaseApp.configureForTests()
  21. }
  22. override class func tearDown() {
  23. FirebaseApp.app()?.delete { success in
  24. if success {
  25. print("Shut down app successfully.")
  26. } else {
  27. print("💥 There was a problem when shutting down the app..")
  28. }
  29. }
  30. }
  31. fileprivate static let expectedAPIURL =
  32. "https://www.googleapis.com/identitytoolkit/v3/relyingparty/signInWithGameCenter?key=APIKEY"
  33. fileprivate static let testAPI = "APIKEY"
  34. fileprivate static let idTokenKey = "idToken"
  35. fileprivate static let idToken = "IDTOKEN"
  36. fileprivate static let refreshTokenKey = "refreshToken"
  37. fileprivate static let refreshToken = "PUBLICKEYURL"
  38. fileprivate static let localIDKey = "localId"
  39. fileprivate static let localID = "LOCALID"
  40. fileprivate static let playerIDKey = "playerId"
  41. fileprivate static let playerID = "PLAYERID"
  42. fileprivate static let teamPlayerID = "TEAMPLAYERID"
  43. fileprivate static let gamePlayerID = "GAMEPLAYERID"
  44. fileprivate static let approximateExpirationDateKey = "expiresIn"
  45. fileprivate static let approximateExpirationDate = "3600"
  46. fileprivate static let isNewUserKey = "isNewUser"
  47. fileprivate static let isNewUser = true
  48. fileprivate static let displayNameKey = "displayName"
  49. fileprivate static let displayName = "DISPLAYNAME"
  50. fileprivate static let publicKeyURLKey = "publicKeyUrl"
  51. fileprivate static let publicKeyURL = "PUBLICKEYURL"
  52. fileprivate static let signatureKey = "signature"
  53. fileprivate static let signature = "AAAABBBBCCCC"
  54. fileprivate static let saltKey = "salt"
  55. fileprivate static let salt = "AAAA"
  56. fileprivate static let timestampKey = "timestamp"
  57. fileprivate static let timestamp: UInt64 = 12_345_678
  58. fileprivate static let accessTokenKey = "idToken"
  59. fileprivate static let accessToken = "ACCESSTOKEN"
  60. class MockBackendRPCIssuer: NSObject, FIRAuthBackendRPCIssuer {
  61. var requestURL: URL?
  62. var requestData: Data?
  63. var decodedRequest: [String: Any]?
  64. var contentType: String?
  65. var handler: FIRAuthBackendRPCIssuerCompletionHandler?
  66. func asyncCallToURL(with requestConfiguration: FIRAuthRequestConfiguration, url URL: URL,
  67. body: Data?, contentType: String,
  68. completionHandler handler: @escaping FIRAuthBackendRPCIssuerCompletionHandler) {
  69. requestURL = URL
  70. if let body = body {
  71. requestData = body
  72. let json = try! JSONSerialization
  73. .jsonObject(with: body, options: []) as! [String: Any]
  74. decodedRequest = json
  75. }
  76. self.contentType = contentType
  77. self.handler = handler
  78. }
  79. @discardableResult
  80. func respond(withJSON JSON: [String: Any]) throws -> Data {
  81. let data = try JSONSerialization.data(
  82. withJSONObject: JSON,
  83. options: JSONSerialization.WritingOptions.prettyPrinted
  84. )
  85. XCTAssertNotNil(handler)
  86. handler?(data, nil)
  87. return data
  88. }
  89. }
  90. override func setUp() {
  91. do {
  92. try Auth.auth().signOut()
  93. } catch {}
  94. }
  95. func testRequestResponseEncoding() {
  96. // given
  97. let RPCIssuer = MockBackendRPCIssuer()
  98. FIRAuthBackend.setDefaultBackendImplementationWith(RPCIssuer)
  99. let signature = Data(base64Encoded: Self.signature)!
  100. let salt = Data(base64Encoded: Self.salt)!
  101. let requestConfiguration = FIRAuthRequestConfiguration(apiKey: Self.testAPI, appID: "appID")!
  102. let request = FIRSignInWithGameCenterRequest(
  103. playerID: Self.playerID,
  104. teamPlayerID: Self.teamPlayerID,
  105. gamePlayerID: Self.gamePlayerID,
  106. publicKeyURL: URL(string: Self.publicKeyURL)!,
  107. signature: signature,
  108. salt: salt,
  109. timestamp: Self.timestamp,
  110. displayName: Self.displayName,
  111. requestConfiguration: requestConfiguration
  112. )!
  113. request.accessToken = Self.accessToken
  114. var cancellables = Set<AnyCancellable>()
  115. let signInWithGameCenterExpectation = expectation(description: "Sign in Game Center")
  116. // when
  117. FIRAuthBackend.signIn(withGameCenter: request)
  118. .sink { completion in
  119. switch completion {
  120. case .finished:
  121. print("Finished")
  122. case let .failure(error):
  123. XCTFail("💥 Something went wrong: \(error)")
  124. }
  125. } receiveValue: { response in
  126. XCTAssertEqual(RPCIssuer.requestURL?.absoluteString, Self.expectedAPIURL)
  127. XCTAssertNotNil(RPCIssuer.decodedRequest)
  128. XCTAssertEqual(
  129. RPCIssuer.decodedRequest?[Self.playerIDKey] as? String,
  130. Self.playerID
  131. )
  132. XCTAssertEqual(
  133. RPCIssuer.decodedRequest?[Self.publicKeyURLKey] as? String,
  134. Self.publicKeyURL
  135. )
  136. XCTAssertEqual(
  137. RPCIssuer.decodedRequest?[Self.signatureKey] as? String,
  138. Self.signature
  139. )
  140. XCTAssertEqual(RPCIssuer.decodedRequest?[Self.saltKey] as? String, Self.salt)
  141. XCTAssertEqual(
  142. RPCIssuer.decodedRequest?[Self.timestampKey] as? UInt64,
  143. Self.timestamp
  144. )
  145. XCTAssertEqual(
  146. RPCIssuer.decodedRequest?[Self.accessTokenKey] as? String,
  147. Self.accessToken
  148. )
  149. XCTAssertEqual(
  150. RPCIssuer.decodedRequest?[Self.displayNameKey] as? String,
  151. Self.displayName
  152. )
  153. XCTAssertNotNil(response)
  154. XCTAssertEqual(response.idToken, Self.idToken)
  155. XCTAssertEqual(response.refreshToken, Self.refreshToken)
  156. XCTAssertEqual(response.localID, Self.localID)
  157. XCTAssertEqual(response.playerID, Self.playerID)
  158. XCTAssertEqual(response.isNewUser, Self.isNewUser)
  159. XCTAssertEqual(response.displayName, Self.displayName)
  160. signInWithGameCenterExpectation.fulfill()
  161. }
  162. .store(in: &cancellables)
  163. let jsonDictionary: [String: Any] = [
  164. "idToken": Self.idToken,
  165. "refreshToken": Self.refreshToken,
  166. "localId": Self.localID,
  167. "playerId": Self.playerID,
  168. "expiresIn": Self.approximateExpirationDate,
  169. "isNewUser": Self.isNewUser,
  170. "displayName": Self.displayName,
  171. ]
  172. try! RPCIssuer.respond(withJSON: jsonDictionary)
  173. // then
  174. wait(for: [signInWithGameCenterExpectation], timeout: expectationTimeout)
  175. }
  176. }