SessionCoordinatorTests.swift 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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. import XCTest
  16. @testable import FirebaseSessions
  17. private class SendableBox<Value>: @unchecked Sendable {
  18. var value: Value
  19. init(value: Value) {
  20. self.value = value
  21. }
  22. }
  23. class SessionCoordinatorTests: XCTestCase {
  24. var installations = MockInstallationsProtocol()
  25. var time = MockTimeProvider()
  26. var fireLogger = MockGDTLogger()
  27. var appInfo = MockApplicationInfo()
  28. var coordinator: SessionCoordinator!
  29. override func setUp() {
  30. super.setUp()
  31. coordinator = SessionCoordinator(
  32. installations: installations,
  33. fireLogger: fireLogger
  34. )
  35. }
  36. override func tearDown() {
  37. installations.authTokenFinished = false
  38. installations.installationIdFinished = false
  39. }
  40. var defaultSessionInfo: SessionInfo {
  41. return SessionInfo(
  42. sessionId: "test_session_id",
  43. firstSessionId: "test_first_session_id",
  44. dispatchEvents: true,
  45. sessionIndex: 0
  46. )
  47. }
  48. func test_attemptLoggingSessionStart_logsToGDT() throws {
  49. let event = SessionStartEvent(sessionInfo: defaultSessionInfo, appInfo: appInfo, time: time)
  50. let resultSuccess = SendableBox(value: false)
  51. coordinator.attemptLoggingSessionStart(event: event) { result in
  52. switch result {
  53. case .success(()):
  54. resultSuccess.value = true
  55. case .failure:
  56. resultSuccess.value = false
  57. }
  58. }
  59. // Make sure we've set the Installation ID
  60. assertEqualProtoString(
  61. event.proto.session_data.firebase_installation_id,
  62. expected: MockInstallationsProtocol.testInstallationId,
  63. fieldName: "installation_id"
  64. )
  65. XCTAssertTrue(installations.authTokenFinished)
  66. XCTAssertTrue(installations.installationIdFinished)
  67. // We should have logged successfully
  68. XCTAssertEqual(fireLogger.loggedEvent, event)
  69. XCTAssert(resultSuccess.value)
  70. }
  71. func test_attemptLoggingSessionStart_handlesGDTError() throws {
  72. fireLogger.result = .failure(NSError(domain: "TestError", code: -1))
  73. let event = SessionStartEvent(sessionInfo: defaultSessionInfo, appInfo: appInfo, time: time)
  74. // Start success so it must be set to false
  75. let resultSuccess = SendableBox(value: true)
  76. coordinator.attemptLoggingSessionStart(event: event) { result in
  77. switch result {
  78. case .success(()):
  79. resultSuccess.value = true
  80. case .failure:
  81. resultSuccess.value = false
  82. }
  83. }
  84. XCTAssertTrue(installations.authTokenFinished)
  85. XCTAssertTrue(installations.installationIdFinished)
  86. // Make sure we've set the Installation ID
  87. assertEqualProtoString(
  88. event.proto.session_data.firebase_installation_id,
  89. expected: MockInstallationsProtocol.testInstallationId,
  90. fieldName: "installation_id"
  91. )
  92. // We should have logged the event, but with a failed result
  93. XCTAssertEqual(fireLogger.loggedEvent, event)
  94. XCTAssertFalse(resultSuccess.value)
  95. }
  96. func test_attemptLoggingSessionStart_handlesInstallationsError() throws {
  97. installations.result = .failure(NSError(domain: "TestInstallationsError", code: -1))
  98. let event = SessionStartEvent(sessionInfo: defaultSessionInfo, appInfo: appInfo, time: time)
  99. // Start success so it must be set to false
  100. let resultSuccess = SendableBox(value: true)
  101. coordinator.attemptLoggingSessionStart(event: event) { result in
  102. switch result {
  103. case .success(()):
  104. resultSuccess.value = true
  105. case .failure:
  106. resultSuccess.value = false
  107. }
  108. }
  109. XCTAssertTrue(installations.authTokenFinished)
  110. XCTAssertTrue(installations.installationIdFinished)
  111. // We should have logged the event, but with a failed result
  112. XCTAssertNotNil(fireLogger.loggedEvent)
  113. XCTAssertFalse(resultSuccess.value)
  114. }
  115. func test_attemptLoggingSessionStart_handlesGDTAndInstallationsError() throws {
  116. let fireLogError = NSError(domain: "DataTransportError", code: -2)
  117. fireLogger.result = .failure(fireLogError)
  118. installations
  119. .result = .failure(FirebaseSessionsError
  120. .SessionInstallationsError(NSError(domain: "TestInstallationsError", code: -1)))
  121. let event = SessionStartEvent(sessionInfo: defaultSessionInfo, appInfo: appInfo, time: time)
  122. // Start success so it must be set to false
  123. let resultSuccess = SendableBox(value: true)
  124. coordinator.attemptLoggingSessionStart(event: event) { result in
  125. switch result {
  126. case .success(()):
  127. resultSuccess.value = true
  128. case let .failure(err):
  129. resultSuccess.value = false
  130. // Result should use the FireLog error if there's an error in both
  131. // Installations and FireLog
  132. XCTAssertEqual(err, FirebaseSessionsError.DataTransportError(fireLogError))
  133. }
  134. }
  135. XCTAssertTrue(installations.authTokenFinished)
  136. XCTAssertTrue(installations.installationIdFinished)
  137. // Make sure we've set the Installation ID to empty because the FIID
  138. // fetch failed
  139. assertEqualProtoString(
  140. event.proto.session_data.firebase_installation_id,
  141. expected: "",
  142. fieldName: "installation_id"
  143. )
  144. // We should have logged the event, but with a failed result
  145. XCTAssertEqual(fireLogger.loggedEvent, event)
  146. XCTAssertFalse(resultSuccess.value)
  147. }
  148. }