ExchangeTokenRequestTests.swift 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // Copyright 2023 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 XCTest
  16. @testable import FirebaseAuth
  17. import FirebaseCore
  18. /// Tests for `ExchangeTokenRequest`
  19. @available(iOS 13, *)
  20. class ExchangeTokenRequestTests: XCTestCase {
  21. // MARK: - Constants for Testing
  22. let kAPIKey = "test-api-key"
  23. let kProjectID = "test-project-id"
  24. let kLocation = "us-east1"
  25. let kTenantID = "test-tenant-id-123"
  26. let kIdToken = "a-very-long-and-secure-oidc-token-string"
  27. let kIdpConfigId = "oidc.my-test-provider"
  28. let kProductionHost = "identityplatform.googleapis.com"
  29. let kStagingHost = "staging-identityplatform.sandbox.googleapis.com"
  30. // MARK: - Test Cases
  31. /// Tests that the production URL is correctly formed for a specific region.
  32. func testProductionURLIsCorrectlyConstructed() {
  33. let (auth, app) = createTestAuthInstance(
  34. projectID: kProjectID,
  35. location: kLocation,
  36. tenantId: kTenantID
  37. )
  38. let request = ExchangeTokenRequest(
  39. idToken: kIdToken,
  40. idpConfigID: kIdpConfigId,
  41. config: auth.requestConfiguration,
  42. useStaging: false
  43. )
  44. let expectedHost = "\(kLocation)-\(kProductionHost)"
  45. let expectedURL = "https://\(expectedHost)/v2beta/projects/\(kProjectID)" +
  46. "/locations/\(kLocation)/tenants/\(kTenantID)/idpConfigs/\(kIdpConfigId):exchangeOidcToken?key=\(kAPIKey)"
  47. XCTAssertEqual(request.requestURL().absoluteString, expectedURL)
  48. }
  49. /// Tests that the production URL is correctly formed for the "prod-global" location.
  50. func testProductionURLIsCorrectlyConstructedForGlobalLocation() {
  51. let (auth, app) = createTestAuthInstance(
  52. projectID: kProjectID,
  53. location: "prod-global",
  54. tenantId: kTenantID
  55. )
  56. _ = app
  57. let request = ExchangeTokenRequest(
  58. idToken: kIdToken,
  59. idpConfigID: kIdpConfigId,
  60. config: auth.requestConfiguration,
  61. useStaging: false
  62. )
  63. let expectedHost = kProductionHost
  64. let expectedURL = "https://\(expectedHost)/v2beta/projects/\(kProjectID)" +
  65. "/locations/global/tenants/\(kTenantID)/idpConfigs/\(kIdpConfigId):exchangeOidcToken?key=\(kAPIKey)"
  66. XCTAssertEqual(request.requestURL().absoluteString, expectedURL)
  67. }
  68. /// Tests that the staging URL is correctly formed.
  69. func testStagingURLIsCorrectlyConstructed() {
  70. let (auth, app) = createTestAuthInstance(
  71. projectID: kProjectID,
  72. location: kLocation,
  73. tenantId: kTenantID
  74. )
  75. _ = app
  76. let request = ExchangeTokenRequest(
  77. idToken: kIdToken,
  78. idpConfigID: kIdpConfigId,
  79. config: auth.requestConfiguration,
  80. useStaging: true
  81. )
  82. let expectedHost = "\(kLocation)-\(kStagingHost)"
  83. let expectedURL = "https://\(expectedHost)/v2beta/projects/\(kProjectID)" +
  84. "/locations/\(kLocation)/tenants/\(kTenantID)/idpConfigs/\(kIdpConfigId):exchangeOidcToken?key=\(kAPIKey)"
  85. XCTAssertEqual(request.requestURL().absoluteString, expectedURL)
  86. }
  87. /// Tests that the unencoded HTTP body contains the correct id_token.
  88. func testUnencodedHTTPBodyIsCorrect() {
  89. let (auth, app) = createTestAuthInstance(
  90. projectID: kProjectID,
  91. location: kLocation,
  92. tenantId: kTenantID
  93. )
  94. _ = app
  95. let request = ExchangeTokenRequest(
  96. idToken: kIdToken,
  97. idpConfigID: kIdpConfigId,
  98. config: auth.requestConfiguration
  99. )
  100. let body = request.unencodedHTTPRequestBody
  101. XCTAssertNotNil(body)
  102. XCTAssertEqual(body?.count, 1)
  103. XCTAssertEqual(body?["id_token"] as? String, kIdToken)
  104. }
  105. // MARK: - Helper Function
  106. /// Creates a test FirebaseApp and Auth instance with specified configurations.
  107. private func createTestAuthInstance(projectID: String?, location: String?,
  108. tenantId: String?) -> (auth: Auth, app: FirebaseApp) {
  109. let appName = "TestApp-\(UUID().uuidString)"
  110. let options = FirebaseOptions(
  111. googleAppID: "1:1234567890:ios:abcdef123456",
  112. gcmSenderID: "1234567890"
  113. )
  114. options.apiKey = kAPIKey
  115. if let projectID = projectID {
  116. options.projectID = projectID
  117. }
  118. if FirebaseApp.app(name: appName) != nil {
  119. FirebaseApp.app(name: appName)?.delete { _ in }
  120. }
  121. let app = FirebaseApp(instanceWithName: appName, options: options)
  122. let auth = Auth(app: app)
  123. auth.app = app
  124. auth.requestConfiguration.location = location
  125. auth.requestConfiguration.tenantId = tenantId
  126. return (auth, app)
  127. }
  128. }