SessionStartEventTests.swift 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  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. #if SWIFT_PACKAGE
  17. import FirebaseSessionsObjC
  18. #endif // SWIFT_PACKAGE
  19. #if SWIFT_PACKAGE
  20. @_implementationOnly import GoogleUtilities_Environment
  21. #else
  22. @_implementationOnly import GoogleUtilities
  23. #endif // SWIFT_PACKAGE
  24. @testable import FirebaseSessions
  25. class SessionStartEventTests: XCTestCase {
  26. var identifiers: MockIdentifierProvider!
  27. var time: MockTimeProvider!
  28. var appInfo: MockApplicationInfo!
  29. override func setUp() {
  30. super.setUp()
  31. identifiers = MockIdentifierProvider()
  32. time = MockTimeProvider()
  33. appInfo = MockApplicationInfo()
  34. }
  35. /// This function runs the `testCase` twice, once for the proto object stored in
  36. /// the event, and once after encoding and decoding the proto. This is useful for
  37. /// testing cases where the proto hasn't been encoded correctly.
  38. func testProtoAndDecodedProto(sessionEvent: SessionStartEvent,
  39. testCase: (firebase_appquality_sessions_SessionEvent) -> Void) {
  40. let proto = sessionEvent.proto
  41. testCase(proto)
  42. /// If you are getting failures in this test case, and not the one above, the
  43. /// problem likely lies in encoding the proto
  44. let decodedProto = sessionEvent.encodeDecodeEvent()
  45. testCase(decodedProto)
  46. }
  47. func test_init_setsSessionIDs() {
  48. identifiers.mockAllValidIDs()
  49. let event = SessionStartEvent(identifiers: identifiers, appInfo: appInfo, time: time)
  50. testProtoAndDecodedProto(sessionEvent: event) { proto in
  51. assertEqualProtoString(
  52. proto.session_data.session_id,
  53. expected: MockIdentifierProvider.testSessionID,
  54. fieldName: "session_id"
  55. )
  56. assertEqualProtoString(
  57. proto.session_data.previous_session_id,
  58. expected: MockIdentifierProvider.testPreviousSessionID,
  59. fieldName: "previous_session_id"
  60. )
  61. XCTAssertEqual(proto.session_data.event_timestamp_us, 123)
  62. }
  63. }
  64. func test_init_setsApplicationInfo() {
  65. appInfo.mockAllInfo()
  66. let event = SessionStartEvent(identifiers: identifiers, appInfo: appInfo, time: time)
  67. testProtoAndDecodedProto(sessionEvent: event) { proto in
  68. assertEqualProtoString(
  69. proto.application_info.app_id,
  70. expected: MockApplicationInfo.testAppID,
  71. fieldName: "app_id"
  72. )
  73. assertEqualProtoString(
  74. proto.application_info.session_sdk_version,
  75. expected: MockApplicationInfo.testSDKVersion,
  76. fieldName: "session_sdk_version"
  77. )
  78. assertEqualProtoString(
  79. proto.application_info.apple_app_info.bundle_short_version,
  80. expected: MockApplicationInfo.testAppDisplayVersion,
  81. fieldName: "bundle_short_version"
  82. )
  83. assertEqualProtoString(
  84. proto.application_info.device_model,
  85. expected: MockApplicationInfo.testDeviceModel,
  86. fieldName: "device_model"
  87. )
  88. assertEqualProtoString(
  89. proto.application_info.apple_app_info.mcc_mnc,
  90. expected: MockApplicationInfo.testMCCMNC,
  91. fieldName: "mcc_mnc"
  92. )
  93. // Ensure we convert the test OS name into the enum.
  94. XCTAssertEqual(
  95. proto.application_info.apple_app_info.os_name,
  96. firebase_appquality_sessions_OsName_IOS
  97. )
  98. }
  99. }
  100. func test_setInstallationID_setsInstallationID() {
  101. identifiers.mockAllValidIDs()
  102. let event = SessionStartEvent(identifiers: identifiers, appInfo: appInfo, time: time)
  103. event.setInstallationID(installationId: "testInstallationID")
  104. testProtoAndDecodedProto(sessionEvent: event) { proto in
  105. assertEqualProtoString(
  106. proto.session_data.firebase_installation_id,
  107. expected: MockIdentifierProvider.testInstallationID,
  108. fieldName: "firebase_installation_id"
  109. )
  110. }
  111. }
  112. func test_convertOSName_convertsCorrectly() {
  113. let expectations: [(given: String, expected: firebase_appquality_sessions_OsName)] = [
  114. ("macos", firebase_appquality_sessions_OsName_MACOS),
  115. ("maccatalyst", firebase_appquality_sessions_OsName_MACCATALYST),
  116. ("ios_on_mac", firebase_appquality_sessions_OsName_IOS_ON_MAC),
  117. ("ios", firebase_appquality_sessions_OsName_IOS),
  118. ("tvos", firebase_appquality_sessions_OsName_TVOS),
  119. ("watchos", firebase_appquality_sessions_OsName_WATCHOS),
  120. ("ipados", firebase_appquality_sessions_OsName_IPADOS),
  121. ("something unknown", firebase_appquality_sessions_OsName_UNKNOWN_OSNAME),
  122. ]
  123. expectations.forEach { (given: String, expected: firebase_appquality_sessions_OsName) in
  124. appInfo.osName = given
  125. let event = SessionStartEvent(identifiers: identifiers, appInfo: appInfo, time: time)
  126. testProtoAndDecodedProto(sessionEvent: event) { proto in
  127. XCTAssertEqual(event.proto.application_info.apple_app_info.os_name, expected)
  128. }
  129. }
  130. }
  131. func test_convertLogEnvironment_convertsCorrectly() {
  132. let expectations: [(given: DevEnvironment,
  133. expected: firebase_appquality_sessions_LogEnvironment)] = [
  134. (.prod, firebase_appquality_sessions_LogEnvironment_LOG_ENVIRONMENT_PROD),
  135. (
  136. .staging,
  137. firebase_appquality_sessions_LogEnvironment_LOG_ENVIRONMENT_STAGING
  138. ),
  139. (
  140. .autopush,
  141. firebase_appquality_sessions_LogEnvironment_LOG_ENVIRONMENT_AUTOPUSH
  142. ),
  143. ]
  144. expectations.forEach { (given: DevEnvironment,
  145. expected: firebase_appquality_sessions_LogEnvironment) in
  146. appInfo.environment = given
  147. let event = SessionStartEvent(identifiers: identifiers, appInfo: appInfo, time: time)
  148. XCTAssertEqual(event.proto.application_info.log_environment, expected)
  149. }
  150. }
  151. func test_dataCollectionState_defaultIsUnknown() {
  152. identifiers.mockAllValidIDs()
  153. let event = SessionStartEvent(identifiers: identifiers, appInfo: appInfo, time: time)
  154. testProtoAndDecodedProto(sessionEvent: event) { proto in
  155. XCTAssertEqual(
  156. proto.session_data.data_collection_status.performance,
  157. firebase_appquality_sessions_DataCollectionState_COLLECTION_UNKNOWN
  158. )
  159. XCTAssertEqual(
  160. proto.session_data.data_collection_status.crashlytics,
  161. firebase_appquality_sessions_DataCollectionState_COLLECTION_UNKNOWN
  162. )
  163. }
  164. }
  165. func test_convertNetworkType_convertsCorrectly() {
  166. let expectations: [(
  167. given: GULNetworkType,
  168. expected: firebase_appquality_sessions_NetworkConnectionInfo_NetworkType
  169. )] = [
  170. (
  171. .WIFI,
  172. firebase_appquality_sessions_NetworkConnectionInfo_NetworkType_WIFI
  173. ),
  174. (
  175. .mobile,
  176. firebase_appquality_sessions_NetworkConnectionInfo_NetworkType_MOBILE
  177. ),
  178. (
  179. .none,
  180. firebase_appquality_sessions_NetworkConnectionInfo_NetworkType_DUMMY
  181. ),
  182. ]
  183. expectations.forEach { (
  184. given: GULNetworkType,
  185. expected: firebase_appquality_sessions_NetworkConnectionInfo_NetworkType
  186. ) in
  187. let mockNetworkInfo = MockNetworkInfo()
  188. mockNetworkInfo.networkType = given
  189. appInfo.networkInfo = mockNetworkInfo
  190. let event = SessionStartEvent(identifiers: identifiers, appInfo: appInfo, time: time)
  191. testProtoAndDecodedProto(sessionEvent: event) { proto in
  192. XCTAssertEqual(
  193. event.proto.application_info.apple_app_info.network_connection_info.network_type,
  194. expected
  195. )
  196. }
  197. }
  198. }
  199. /// Following tests can be run only in iOS environment
  200. #if os(iOS) && !targetEnvironment(macCatalyst)
  201. func test_convertMobileSubtype_convertsCorrectlyPreOS14() {
  202. let expectations: [(
  203. given: String,
  204. expected: firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype
  205. )] = [
  206. (
  207. CTRadioAccessTechnologyGPRS,
  208. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_GPRS
  209. ),
  210. (
  211. CTRadioAccessTechnologyEdge,
  212. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_EDGE
  213. ),
  214. (
  215. CTRadioAccessTechnologyWCDMA,
  216. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_CDMA
  217. ),
  218. (
  219. CTRadioAccessTechnologyCDMA1x,
  220. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_CDMA
  221. ),
  222. (
  223. CTRadioAccessTechnologyHSDPA,
  224. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_HSDPA
  225. ),
  226. (
  227. CTRadioAccessTechnologyHSUPA,
  228. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_HSUPA
  229. ),
  230. (
  231. CTRadioAccessTechnologyCDMAEVDORev0,
  232. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_EVDO_0
  233. ),
  234. (
  235. CTRadioAccessTechnologyCDMAEVDORevA,
  236. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_EVDO_A
  237. ),
  238. (
  239. CTRadioAccessTechnologyCDMAEVDORevB,
  240. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_EVDO_B
  241. ),
  242. (
  243. CTRadioAccessTechnologyeHRPD,
  244. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_EHRPD
  245. ),
  246. (
  247. CTRadioAccessTechnologyLTE,
  248. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_LTE
  249. ),
  250. (
  251. "random",
  252. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE
  253. ),
  254. ]
  255. expectations
  256. .forEach { (
  257. given: String,
  258. expected: firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype
  259. ) in
  260. let mockNetworkInfo = MockNetworkInfo()
  261. mockNetworkInfo.mobileSubtype = given
  262. appInfo.networkInfo = mockNetworkInfo
  263. let event = SessionStartEvent(identifiers: identifiers, appInfo: appInfo, time: time)
  264. testProtoAndDecodedProto(sessionEvent: event) { proto in
  265. XCTAssertEqual(
  266. event.proto.application_info.apple_app_info.network_connection_info.mobile_subtype,
  267. expected
  268. )
  269. }
  270. }
  271. }
  272. #endif
  273. #if os(iOS) && !targetEnvironment(macCatalyst)
  274. @available(iOS 14.1, *)
  275. func test_convertMobileSubtype_convertsCorrectlyPostOS14() {
  276. let expectations: [(
  277. given: String,
  278. expected: firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype
  279. )] = [
  280. (
  281. CTRadioAccessTechnologyGPRS,
  282. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_GPRS
  283. ),
  284. (
  285. CTRadioAccessTechnologyEdge,
  286. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_EDGE
  287. ),
  288. (
  289. CTRadioAccessTechnologyWCDMA,
  290. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_CDMA
  291. ),
  292. (
  293. CTRadioAccessTechnologyCDMA1x,
  294. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_CDMA
  295. ),
  296. (
  297. CTRadioAccessTechnologyHSDPA,
  298. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_HSDPA
  299. ),
  300. (
  301. CTRadioAccessTechnologyHSUPA,
  302. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_HSUPA
  303. ),
  304. (
  305. CTRadioAccessTechnologyCDMAEVDORev0,
  306. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_EVDO_0
  307. ),
  308. (
  309. CTRadioAccessTechnologyCDMAEVDORevA,
  310. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_EVDO_A
  311. ),
  312. (
  313. CTRadioAccessTechnologyCDMAEVDORevB,
  314. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_EVDO_B
  315. ),
  316. (
  317. CTRadioAccessTechnologyeHRPD,
  318. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_EHRPD
  319. ),
  320. (
  321. CTRadioAccessTechnologyLTE,
  322. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_LTE
  323. ),
  324. (
  325. CTRadioAccessTechnologyNRNSA,
  326. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_NR
  327. ),
  328. (
  329. CTRadioAccessTechnologyNR,
  330. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_NR
  331. ),
  332. (
  333. "random",
  334. firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE
  335. ),
  336. ]
  337. expectations
  338. .forEach { (
  339. given: String,
  340. expected: firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype
  341. ) in
  342. let mockNetworkInfo = MockNetworkInfo()
  343. mockNetworkInfo.mobileSubtype = given
  344. appInfo.networkInfo = mockNetworkInfo
  345. let event = SessionStartEvent(identifiers: identifiers, appInfo: appInfo, time: time)
  346. testProtoAndDecodedProto(sessionEvent: event) { proto in
  347. XCTAssertEqual(
  348. event.proto.application_info.apple_app_info.network_connection_info.mobile_subtype,
  349. expected
  350. )
  351. }
  352. }
  353. }
  354. #endif
  355. }