SessionStartEventTests.swift 15 KB

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