SessionStartEventTests.swift 13 KB

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