FIRCLSInstallIdentifierModelTests.m 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. // Copyright 2019 Google
  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 "Crashlytics/Crashlytics/Models/FIRCLSInstallIdentifierModel.h"
  15. #import <XCTest/XCTest.h>
  16. #import "Crashlytics/Crashlytics/FIRCLSUserDefaults/FIRCLSUserDefaults.h"
  17. #import "Crashlytics/UnitTests/Mocks/FIRMockInstallations.h"
  18. static NSString *const FABInstallationUUIDKey = @"com.crashlytics.iuuid";
  19. static NSString *const FABInstallationADIDKey = @"com.crashlytics.install.adid";
  20. static NSString *const FIRCLSInstallationIIDHashKey = @"com.crashlytics.install.iid";
  21. static NSString *const FIRCLSTestHashOfInstanceID =
  22. @"ed0cf273a55b731a50c3356e8c5a9887b96e7a1a7b233967bff23676bcea896d";
  23. static NSString *const FIRCLSTestHashOfTestInstanceID =
  24. @"a5da68191a6ce5247c37b6dc93775891b3c4fc183d9c84f7a1c8670e680b9cd4";
  25. @interface FIRCLSInstallIdentifierModelTests : XCTestCase {
  26. FIRCLSUserDefaults *_defaults;
  27. }
  28. @end
  29. @implementation FIRCLSInstallIdentifierModelTests
  30. - (void)setUp {
  31. _defaults = [FIRCLSUserDefaults standardUserDefaults];
  32. [_defaults removeObjectForKey:FABInstallationUUIDKey];
  33. [_defaults removeObjectForKey:FABInstallationADIDKey];
  34. [_defaults removeObjectForKey:FIRCLSInstallationIIDHashKey];
  35. }
  36. - (void)tearDown {
  37. [_defaults removeObjectForKey:FABInstallationUUIDKey];
  38. [_defaults removeObjectForKey:FABInstallationADIDKey];
  39. [_defaults removeObjectForKey:FIRCLSInstallationIIDHashKey];
  40. }
  41. - (void)testCreateUUID {
  42. FIRMockInstallations *iid = [[FIRMockInstallations alloc] initWithFID:@"test_instance_id"];
  43. FIRCLSInstallIdentifierModel *model =
  44. [[FIRCLSInstallIdentifierModel alloc] initWithInstallations:iid];
  45. XCTAssertNotNil(model.installID);
  46. XCTAssertEqualObjects([_defaults objectForKey:FABInstallationUUIDKey], model.installID);
  47. XCTAssertNil([_defaults objectForKey:FABInstallationADIDKey]);
  48. }
  49. - (void)testCreateUUIDAndRotate {
  50. FIRMockInstallations *iid = [[FIRMockInstallations alloc] initWithFID:@"test_instance_id"];
  51. FIRCLSInstallIdentifierModel *model =
  52. [[FIRCLSInstallIdentifierModel alloc] initWithInstallations:iid];
  53. XCTAssertNotNil(model.installID);
  54. BOOL didRotate = [model
  55. regenerateInstallIDIfNeededWithBlock:^(NSString *_Nonnull fiid, NSString *_Nonnull authToken){
  56. }];
  57. sleep(1);
  58. XCTAssertTrue(iid.authTokenFinished);
  59. XCTAssertTrue(iid.installationIDFinished);
  60. XCTAssertFalse(didRotate);
  61. XCTAssertEqualObjects([_defaults objectForKey:FABInstallationUUIDKey], model.installID);
  62. XCTAssertNil([_defaults objectForKey:FABInstallationADIDKey]);
  63. XCTAssertEqualObjects(FIRCLSTestHashOfTestInstanceID,
  64. [_defaults objectForKey:FIRCLSInstallationIIDHashKey]);
  65. }
  66. - (void)testCreateUUIDAndErrorGettingInstanceID {
  67. NSError *fakeError = [NSError errorWithDomain:NSCocoaErrorDomain code:-1 userInfo:@{}];
  68. FIRMockInstallations *iid = [[FIRMockInstallations alloc] initWithError:fakeError];
  69. FIRCLSInstallIdentifierModel *model =
  70. [[FIRCLSInstallIdentifierModel alloc] initWithInstallations:iid];
  71. XCTAssertNotNil(model.installID);
  72. BOOL didRotate = [model
  73. regenerateInstallIDIfNeededWithBlock:^(NSString *_Nonnull fiid, NSString *_Nonnull authToken){
  74. }];
  75. XCTAssertFalse(didRotate);
  76. XCTAssertTrue(iid.authTokenFinished);
  77. XCTAssertTrue(iid.installationIDFinished);
  78. XCTAssertEqualObjects([_defaults objectForKey:FABInstallationUUIDKey], model.installID);
  79. XCTAssertNil([_defaults objectForKey:FABInstallationADIDKey]);
  80. XCTAssertEqualObjects(nil, [_defaults objectForKey:FIRCLSInstallationIIDHashKey]);
  81. }
  82. - (void)testCreateUUIDNoIID {
  83. FIRMockInstallations *iid = [[FIRMockInstallations alloc] initWithFID:nil];
  84. FIRCLSInstallIdentifierModel *model =
  85. [[FIRCLSInstallIdentifierModel alloc] initWithInstallations:iid];
  86. XCTAssertNotNil(model.installID);
  87. XCTAssertEqualObjects([_defaults objectForKey:FABInstallationUUIDKey], model.installID);
  88. XCTAssertNil([_defaults objectForKey:FABInstallationADIDKey]);
  89. XCTAssertEqualObjects(nil, [_defaults objectForKey:FIRCLSInstallationIIDHashKey]);
  90. }
  91. - (void)testIIDBecomesNil {
  92. // Set up the initial state with a valid iid and uuid.
  93. [_defaults setObject:@"old_uuid" forKey:FABInstallationUUIDKey];
  94. [_defaults setObject:@"old_instance_id" forKey:FIRCLSInstallationIIDHashKey];
  95. // Initialize the model with the a nil IID.
  96. FIRMockInstallations *iid = [[FIRMockInstallations alloc] initWithFID:nil];
  97. FIRCLSInstallIdentifierModel *model =
  98. [[FIRCLSInstallIdentifierModel alloc] initWithInstallations:iid];
  99. XCTAssertNotNil(model.installID);
  100. // Test that the UUID did not change. The FIID can be nil if
  101. // there's no FIID cached, so we can't say whether to regenerate
  102. XCTAssertEqualObjects(model.installID, @"old_uuid");
  103. XCTAssertEqualObjects([_defaults objectForKey:FABInstallationUUIDKey], model.installID);
  104. XCTAssertNil([_defaults objectForKey:FABInstallationADIDKey]);
  105. }
  106. - (void)testIIDChanges {
  107. // Set up the initial state with a valid iid and uuid.
  108. [_defaults setObject:@"old_uuid" forKey:FABInstallationUUIDKey];
  109. [_defaults setObject:@"old_instance_id" forKey:FIRCLSInstallationIIDHashKey];
  110. // Initialize the model with the a new IID.
  111. FIRMockInstallations *iid = [[FIRMockInstallations alloc] initWithFID:@"new_instance_id"];
  112. FIRCLSInstallIdentifierModel *model =
  113. [[FIRCLSInstallIdentifierModel alloc] initWithInstallations:iid];
  114. XCTAssertNotNil(model.installID);
  115. BOOL didRotate = [model
  116. regenerateInstallIDIfNeededWithBlock:^(NSString *_Nonnull fiid, NSString *_Nonnull authToken){
  117. }];
  118. XCTAssertTrue(didRotate);
  119. XCTAssertTrue(iid.authTokenFinished);
  120. XCTAssertTrue(iid.installationIDFinished);
  121. // Test that the UUID changed.
  122. XCTAssertNotEqualObjects(model.installID, @"old_uuid");
  123. XCTAssertEqualObjects([_defaults objectForKey:FABInstallationUUIDKey], model.installID);
  124. XCTAssertNil([_defaults objectForKey:FABInstallationADIDKey]);
  125. XCTAssertEqualObjects(FIRCLSTestHashOfInstanceID,
  126. [_defaults objectForKey:FIRCLSInstallationIIDHashKey]);
  127. }
  128. - (void)testIIDDoesntChange {
  129. // Set up the initial state with a valid iid and uuid.
  130. [_defaults setObject:@"test_uuid" forKey:FABInstallationUUIDKey];
  131. [_defaults setObject:FIRCLSTestHashOfTestInstanceID forKey:FIRCLSInstallationIIDHashKey];
  132. // Initialize the model with the a new IID.
  133. FIRMockInstallations *iid = [[FIRMockInstallations alloc] initWithFID:@"test_instance_id"];
  134. FIRCLSInstallIdentifierModel *model =
  135. [[FIRCLSInstallIdentifierModel alloc] initWithInstallations:iid];
  136. XCTAssertNotNil(model.installID);
  137. BOOL didRotate = [model
  138. regenerateInstallIDIfNeededWithBlock:^(NSString *_Nonnull fiid, NSString *_Nonnull authToken){
  139. }];
  140. XCTAssertFalse(didRotate);
  141. XCTAssertTrue(iid.authTokenFinished);
  142. XCTAssertTrue(iid.installationIDFinished);
  143. // Test that the UUID changed.
  144. XCTAssertEqualObjects(model.installID, @"test_uuid");
  145. XCTAssertEqualObjects([_defaults objectForKey:FABInstallationUUIDKey], model.installID);
  146. XCTAssertNil([_defaults objectForKey:FABInstallationADIDKey]);
  147. XCTAssertEqualObjects(FIRCLSTestHashOfTestInstanceID,
  148. [_defaults objectForKey:FIRCLSInstallationIIDHashKey]);
  149. }
  150. - (void)testUUIDSetButNeverIIDNilIID {
  151. // Set up the initial state with a valid iid and uuid.
  152. [_defaults setObject:@"old_uuid" forKey:FABInstallationUUIDKey];
  153. // Initialize the model with the a nil IID.
  154. FIRMockInstallations *iid = [[FIRMockInstallations alloc] initWithFID:nil];
  155. FIRCLSInstallIdentifierModel *model =
  156. [[FIRCLSInstallIdentifierModel alloc] initWithInstallations:iid];
  157. XCTAssertNotNil(model.installID);
  158. BOOL didRotate = [model
  159. regenerateInstallIDIfNeededWithBlock:^(NSString *_Nonnull fiid, NSString *_Nonnull authToken){
  160. }];
  161. XCTAssertFalse(didRotate);
  162. XCTAssertTrue(iid.authTokenFinished);
  163. XCTAssertTrue(iid.installationIDFinished);
  164. // Test that the UUID did not change. The FIID can be nil if
  165. // there's no FIID cached, so we can't say whether to regenerate
  166. XCTAssertEqualObjects(model.installID, @"old_uuid");
  167. XCTAssertEqualObjects([_defaults objectForKey:FABInstallationUUIDKey], model.installID);
  168. XCTAssertNil([_defaults objectForKey:FABInstallationADIDKey]);
  169. XCTAssertEqualObjects([_defaults objectForKey:FIRCLSInstallationIIDHashKey], nil);
  170. }
  171. - (void)testUUIDSetButNeverIIDWithIID {
  172. // Set up the initial state with a valid iid and uuid.
  173. [_defaults setObject:@"old_uuid" forKey:FABInstallationUUIDKey];
  174. // Initialize the model with the a nil IID.
  175. FIRMockInstallations *iid = [[FIRMockInstallations alloc] initWithFID:@"test_instance_id"];
  176. FIRCLSInstallIdentifierModel *model =
  177. [[FIRCLSInstallIdentifierModel alloc] initWithInstallations:iid];
  178. XCTAssertNotNil(model.installID);
  179. BOOL didRotate = [model
  180. regenerateInstallIDIfNeededWithBlock:^(NSString *_Nonnull fiid, NSString *_Nonnull authToken){
  181. }];
  182. XCTAssertFalse(didRotate);
  183. XCTAssertTrue(iid.authTokenFinished);
  184. XCTAssertTrue(iid.installationIDFinished);
  185. // Test that the UUID did not change. The FIID can be nil if
  186. // there's no FIID cached, so we can't say whether to regenerate
  187. XCTAssertEqualObjects(model.installID, @"old_uuid");
  188. XCTAssertEqualObjects([_defaults objectForKey:FABInstallationUUIDKey], model.installID);
  189. XCTAssertNil([_defaults objectForKey:FABInstallationADIDKey]);
  190. XCTAssertEqualObjects([_defaults objectForKey:FIRCLSInstallationIIDHashKey],
  191. FIRCLSTestHashOfTestInstanceID);
  192. }
  193. - (void)testADIDWasSetButNeverIID {
  194. // Set up the initial state with a valid adid and uuid.
  195. [_defaults setObject:@"test_uuid" forKey:FABInstallationUUIDKey];
  196. [_defaults setObject:@"test_adid" forKey:FABInstallationADIDKey];
  197. // Initialize the model with the a new IID.
  198. FIRMockInstallations *iid = [[FIRMockInstallations alloc] initWithFID:nil];
  199. FIRCLSInstallIdentifierModel *model =
  200. [[FIRCLSInstallIdentifierModel alloc] initWithInstallations:iid];
  201. XCTAssertNotNil(model.installID);
  202. BOOL didRotate = [model
  203. regenerateInstallIDIfNeededWithBlock:^(NSString *_Nonnull fiid, NSString *_Nonnull authToken){
  204. }];
  205. XCTAssertFalse(didRotate);
  206. XCTAssertTrue(iid.authTokenFinished);
  207. XCTAssertTrue(iid.installationIDFinished);
  208. // Test that the UUID didn't change.
  209. XCTAssertEqualObjects(model.installID, @"test_uuid");
  210. XCTAssertEqualObjects([_defaults objectForKey:FABInstallationUUIDKey], model.installID);
  211. XCTAssertNil([_defaults objectForKey:FABInstallationADIDKey]);
  212. XCTAssertNil([_defaults objectForKey:FIRCLSInstallationIIDHashKey]);
  213. }
  214. - (void)testADIDWasSetAndIIDBecomesSet {
  215. // Set up the initial state with a valid adid and uuid.
  216. [_defaults setObject:@"test_uuid" forKey:FABInstallationUUIDKey];
  217. [_defaults setObject:@"test_adid" forKey:FABInstallationADIDKey];
  218. // Initialize the model with the a new IID.
  219. FIRMockInstallations *iid = [[FIRMockInstallations alloc] initWithFID:@"test_instance_id"];
  220. FIRCLSInstallIdentifierModel *model =
  221. [[FIRCLSInstallIdentifierModel alloc] initWithInstallations:iid];
  222. XCTAssertNotNil(model.installID);
  223. BOOL didRotate = [model
  224. regenerateInstallIDIfNeededWithBlock:^(NSString *_Nonnull fiid, NSString *_Nonnull authToken){
  225. }];
  226. XCTAssertFalse(didRotate);
  227. XCTAssertTrue(iid.authTokenFinished);
  228. XCTAssertTrue(iid.installationIDFinished);
  229. // Test that the UUID didn't change.
  230. XCTAssertEqualObjects(model.installID, @"test_uuid");
  231. XCTAssertEqualObjects([_defaults objectForKey:FABInstallationUUIDKey], model.installID);
  232. XCTAssertNil([_defaults objectForKey:FABInstallationADIDKey]);
  233. XCTAssertEqualObjects(FIRCLSTestHashOfTestInstanceID,
  234. [_defaults objectForKey:FIRCLSInstallationIIDHashKey]);
  235. }
  236. - (void)testADIDAndIIDWereSet {
  237. // Set up the initial state with a valid iid, adid, and uuid.
  238. [_defaults setObject:@"test_uuid" forKey:FABInstallationUUIDKey];
  239. [_defaults setObject:@"test_adid" forKey:FABInstallationADIDKey];
  240. [_defaults setObject:FIRCLSTestHashOfTestInstanceID forKey:FIRCLSInstallationIIDHashKey];
  241. // Initialize the model with the a new IID.
  242. FIRMockInstallations *iid = [[FIRMockInstallations alloc] initWithFID:@"test_instance_id"];
  243. FIRCLSInstallIdentifierModel *model =
  244. [[FIRCLSInstallIdentifierModel alloc] initWithInstallations:iid];
  245. XCTAssertNotNil(model.installID);
  246. BOOL didRotate = [model
  247. regenerateInstallIDIfNeededWithBlock:^(NSString *_Nonnull fiid, NSString *_Nonnull authToken){
  248. }];
  249. XCTAssertFalse(didRotate);
  250. // Test that the UUID didn't change.
  251. XCTAssertEqualObjects(model.installID, @"test_uuid");
  252. XCTAssertEqualObjects([_defaults objectForKey:FABInstallationUUIDKey], model.installID);
  253. XCTAssertNil([_defaults objectForKey:FABInstallationADIDKey]);
  254. XCTAssertEqualObjects(FIRCLSTestHashOfTestInstanceID,
  255. [_defaults objectForKey:FIRCLSInstallationIIDHashKey]);
  256. }
  257. - (void)testADIDAndIIDWereSet2 {
  258. // Set up the initial state with a valid iid, adid, and uuid.
  259. [_defaults setObject:@"test_uuid" forKey:FABInstallationUUIDKey];
  260. [_defaults setObject:@"test_adid" forKey:FABInstallationADIDKey];
  261. [_defaults setObject:FIRCLSTestHashOfTestInstanceID forKey:FIRCLSInstallationIIDHashKey];
  262. // Initialize the model with the a new IID.
  263. FIRMockInstallations *iid =
  264. [[FIRMockInstallations alloc] initWithFID:@"test_changed_instance_id"];
  265. FIRCLSInstallIdentifierModel *model =
  266. [[FIRCLSInstallIdentifierModel alloc] initWithInstallations:iid];
  267. XCTAssertNotNil(model.installID);
  268. BOOL didRotate = [model
  269. regenerateInstallIDIfNeededWithBlock:^(NSString *_Nonnull fiid, NSString *_Nonnull authToken){
  270. }];
  271. XCTAssertTrue(didRotate);
  272. XCTAssertTrue(iid.authTokenFinished);
  273. XCTAssertTrue(iid.installationIDFinished);
  274. // Test that the UUID change.
  275. XCTAssertNotEqualObjects(model.installID, @"test_uuid");
  276. XCTAssertEqualObjects([_defaults objectForKey:FABInstallationUUIDKey], model.installID);
  277. XCTAssertNil([_defaults objectForKey:FABInstallationADIDKey]);
  278. XCTAssertEqualObjects(@"f1e1e3969cd926d57448fcd02f6fd4e979739a87256a652a1781cfa0510408b3",
  279. [_defaults objectForKey:FIRCLSInstallationIIDHashKey]);
  280. }
  281. @end