1616
1717#import " GoogleSignIn/Sources/GIDAuthStateMigration.h"
1818#import " GoogleSignIn/Sources/GIDSignInCallbackSchemes.h"
19+ #if TARGET_OS_OSX || TARGET_OS_MACCATALYST
20+ #import " GoogleSignIn/Tests/Unit/OIDAuthState+Testing.h"
21+ #endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
1922
2023@import GTMAppAuth;
2124
4952static NSString *const kRedirectURI =
5053 @" com.googleusercontent.apps.223520599684-kg64hfn0h950oureqacja2fltg00msv3:/callback/path" ;
5154
52- static NSString *const kMigrationCheckPerformedKey = @" GID_MigrationCheckPerformed" ;
55+ static NSString *const kGTMAppAuthMigrationCheckPerformedKey = @" GID_MigrationCheckPerformed" ;
56+ static NSString *const kDataProtectedMigrationCheckPerformedKey =
57+ @" GID_DataProtectedMigrationCheckPerformed" ;
5358static NSString *const kFingerprintService = @" fingerprint" ;
5459
5560NS_ASSUME_NONNULL_BEGIN
@@ -79,6 +84,9 @@ @implementation GIDAuthStateMigrationTest {
7984 id _mockNSBundle;
8085 id _mockGIDSignInCallbackSchemes;
8186 id _mockGTMOAuth2Compatibility;
87+ #if TARGET_OS_OSX || TARGET_OS_MACCATALYST
88+ id _realLegacyGTMKeychainStore;
89+ #endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
8290}
8391
8492- (void )setUp {
@@ -92,6 +100,12 @@ - (void)setUp {
92100 _mockNSBundle = OCMStrictClassMock ([NSBundle class ]);
93101 _mockGIDSignInCallbackSchemes = OCMStrictClassMock ([GIDSignInCallbackSchemes class ]);
94102 _mockGTMOAuth2Compatibility = OCMStrictClassMock ([GTMOAuth2Compatibility class ]);
103+ #if TARGET_OS_OSX || TARGET_OS_MACCATALYST
104+ GTMKeychainAttribute *fileBasedKeychain = [GTMKeychainAttribute useFileBasedKeychain ];
105+ NSSet *attributes = [NSSet setWithArray: @[fileBasedKeychain]];
106+ _realLegacyGTMKeychainStore = [[GTMKeychainStore alloc ] initWithItemName: kKeychainName
107+ keychainAttributes: attributes];
108+ #endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
95109}
96110
97111- (void )tearDown {
@@ -111,48 +125,72 @@ - (void)tearDown {
111125 [_mockGIDSignInCallbackSchemes stopMocking ];
112126 [_mockGTMOAuth2Compatibility verify ];
113127 [_mockGTMOAuth2Compatibility stopMocking ];
128+ #if TARGET_OS_OSX || TARGET_OS_MACCATALYST
129+ [_realLegacyGTMKeychainStore removeAuthSessionWithError: nil ];
130+ #endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
114131
115132 [super tearDown ];
116133}
117134
118135#pragma mark - Tests
119136
120- - (void )testMigrateIfNeeded_NoPreviousMigration {
137+ #if TARGET_OS_OSX || TARGET_OS_MACCATALYST
138+ - (void )testMigrateIfNeeded_NoPreviousMigration_DataProtectedMigration {
121139 [[[_mockUserDefaults stub ] andReturn: _mockUserDefaults] standardUserDefaults ];
122- [[[_mockUserDefaults expect ] andReturnValue: @NO ] boolForKey: kMigrationCheckPerformedKey ];
123- [[_mockUserDefaults expect ] setBool: YES forKey: kMigrationCheckPerformedKey ];
140+ [[[_mockUserDefaults expect ] andReturnValue: @NO ] boolForKey: kDataProtectedMigrationCheckPerformedKey ];
141+ [[_mockUserDefaults expect ] setBool: YES forKey: kDataProtectedMigrationCheckPerformedKey ];
124142
125143 [[_mockGTMKeychainStore expect ] saveAuthSession: OCMOCK_ANY error: OCMArg.anyObjectRef];
144+ [[[_mockGTMKeychainStore expect ] andReturn: kKeychainName ] itemName ];
126145
127- [self setUpCommonExtractAuthorizationMocksWithFingerPrint: kSavedFingerprint ];
146+ // set the auth session that will be migrated
147+ OIDAuthState *authState = [OIDAuthState testInstance ];
148+ GTMAuthSession *authSession = [[GTMAuthSession alloc ] initWithAuthState: authState];
149+ NSError *err;
150+ [_realLegacyGTMKeychainStore saveAuthSession: authSession error: &err];
151+ XCTAssertNil (err);
128152
129153 GIDAuthStateMigration *migration =
130154 [[GIDAuthStateMigration alloc ] initWithKeychainStore: _mockGTMKeychainStore];
131155 [migration migrateIfNeededWithTokenURL: [NSURL URLWithString: kTokenURL ]
132156 callbackPath: kCallbackPath
133157 keychainName: kKeychainName
134158 isFreshInstall: NO ];
159+
160+ // verify that the auth session was removed during migration
161+ XCTAssertNil ([_realLegacyGTMKeychainStore retrieveAuthSessionWithError: nil ]);
135162}
136163
137- - (void )testMigrateIfNeeded_HasPreviousMigration {
164+ - (void )testMigrateIfNeeded_KeychainFailure_DataProtectedMigration {
138165 [[[_mockUserDefaults stub ] andReturn: _mockUserDefaults] standardUserDefaults ];
139- [[[_mockUserDefaults expect ] andReturnValue: @YES ] boolForKey: kMigrationCheckPerformedKey ];
140- [[_mockUserDefaults reject ] setBool: YES forKey: kMigrationCheckPerformedKey ];
166+ [[[_mockUserDefaults expect ] andReturnValue: @NO ] boolForKey: kDataProtectedMigrationCheckPerformedKey ];
167+
168+ NSError *keychainSaveError = [NSError new ];
169+ OCMStub ([_mockGTMKeychainStore saveAuthSession: OCMOCK_ANY error: [OCMArg setTo: keychainSaveError]]);
170+
171+ [[[_mockGTMKeychainStore expect ] andReturn: kKeychainName ] itemName ];
172+ OIDAuthState *authState = [OIDAuthState testInstance ];
173+ GTMAuthSession *authSession = [[GTMAuthSession alloc ] initWithAuthState: authState];
174+ NSError *err;
175+ [_realLegacyGTMKeychainStore saveAuthSession: authSession error: &err];
176+ XCTAssertNil (err);
141177
142178 GIDAuthStateMigration *migration =
143179 [[GIDAuthStateMigration alloc ] initWithKeychainStore: _mockGTMKeychainStore];
144180 [migration migrateIfNeededWithTokenURL: [NSURL URLWithString: kTokenURL ]
145181 callbackPath: kCallbackPath
146182 keychainName: kKeychainName
147183 isFreshInstall: NO ];
184+ XCTAssertNotNil ([_realLegacyGTMKeychainStore retrieveAuthSessionWithError: nil ]);
148185}
149186
150- - (void )testMigrateIfNeeded_KeychainFailure {
187+ #else
188+ - (void )testMigrateIfNeeded_NoPreviousMigration_GTMAppAuthMigration {
151189 [[[_mockUserDefaults stub ] andReturn: _mockUserDefaults] standardUserDefaults ];
152- [[[_mockUserDefaults expect ] andReturnValue: @NO ] boolForKey: kMigrationCheckPerformedKey ];
190+ [[[_mockUserDefaults expect ] andReturnValue: @NO ] boolForKey: kGTMAppAuthMigrationCheckPerformedKey ];
191+ [[_mockUserDefaults expect ] setBool: YES forKey: kGTMAppAuthMigrationCheckPerformedKey ];
153192
154- NSError *keychainSaveError = [NSError new ];
155- OCMStub ([_mockGTMKeychainStore saveAuthSession: OCMOCK_ANY error: [OCMArg setTo: keychainSaveError]]);
193+ [[_mockGTMKeychainStore expect ] saveAuthSession: OCMOCK_ANY error: OCMArg.anyObjectRef];
156194
157195 [self setUpCommonExtractAuthorizationMocksWithFingerPrint: kSavedFingerprint ];
158196
@@ -164,18 +202,21 @@ - (void)testMigrateIfNeeded_KeychainFailure {
164202 isFreshInstall: NO ];
165203}
166204
167- - (void )testMigrateIfNeeded_isFreshInstall {
205+ - (void )testMigrateIfNeeded_KeychainFailure_GTMAppAuthMigration {
168206 [[[_mockUserDefaults stub ] andReturn: _mockUserDefaults] standardUserDefaults ];
169- [[[_mockUserDefaults expect ] andReturnValue: @NO ]
170- boolForKey: kMigrationCheckPerformedKey ];
171- [[_mockUserDefaults expect ] setBool: YES forKey: kMigrationCheckPerformedKey ];
207+ [[[_mockUserDefaults expect ] andReturnValue: @NO ] boolForKey: kGTMAppAuthMigrationCheckPerformedKey ];
208+
209+ NSError *keychainSaveError = [NSError new ];
210+ OCMStub ([_mockGTMKeychainStore saveAuthSession: OCMOCK_ANY error: [OCMArg setTo: keychainSaveError]]);
211+
212+ [self setUpCommonExtractAuthorizationMocksWithFingerPrint: kSavedFingerprint ];
172213
173214 GIDAuthStateMigration *migration =
174215 [[GIDAuthStateMigration alloc ] initWithKeychainStore: _mockGTMKeychainStore];
175216 [migration migrateIfNeededWithTokenURL: [NSURL URLWithString: kTokenURL ]
176217 callbackPath: kCallbackPath
177218 keychainName: kKeychainName
178- isFreshInstall: YES ];
219+ isFreshInstall: NO ];
179220}
180221
181222- (void )testExtractAuthorization {
@@ -201,6 +242,43 @@ - (void)testExtractAuthorization_HostedDomain {
201242
202243 XCTAssertNotNil (authorization);
203244}
245+ #endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
246+
247+ - (void )testMigrateIfNeeded_HasPreviousMigration {
248+ [[[_mockUserDefaults stub ] andReturn: _mockUserDefaults] standardUserDefaults ];
249+ #if TARGET_OS_OSX || TARGET_OS_MACCATALYST
250+ [[[_mockUserDefaults expect ] andReturnValue: @YES ] boolForKey: kDataProtectedMigrationCheckPerformedKey ];
251+ [[_mockUserDefaults reject ] setBool: YES forKey: kDataProtectedMigrationCheckPerformedKey ];
252+ #else
253+ [[[_mockUserDefaults expect ] andReturnValue: @YES ] boolForKey: kGTMAppAuthMigrationCheckPerformedKey ];
254+ [[_mockUserDefaults reject ] setBool: YES forKey: kGTMAppAuthMigrationCheckPerformedKey ];
255+ #endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
256+
257+ GIDAuthStateMigration *migration =
258+ [[GIDAuthStateMigration alloc ] initWithKeychainStore: _mockGTMKeychainStore];
259+ [migration migrateIfNeededWithTokenURL: [NSURL URLWithString: kTokenURL ]
260+ callbackPath: kCallbackPath
261+ keychainName: kKeychainName
262+ isFreshInstall: NO ];
263+ }
264+
265+ - (void )testMigrateIfNeeded_isFreshInstall {
266+ [[[_mockUserDefaults stub ] andReturn: _mockUserDefaults] standardUserDefaults ];
267+ #if TARGET_OS_OSX || TARGET_OS_MACCATALYST
268+ [[_mockUserDefaults expect ] setBool: YES forKey: kDataProtectedMigrationCheckPerformedKey ];
269+ #else
270+ [[_mockUserDefaults expect ] setBool: YES forKey: kGTMAppAuthMigrationCheckPerformedKey ];
271+ #endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
272+
273+ GIDAuthStateMigration *migration =
274+ [[GIDAuthStateMigration alloc ] initWithKeychainStore: _mockGTMKeychainStore];
275+ [migration migrateIfNeededWithTokenURL: [NSURL URLWithString: kTokenURL ]
276+ callbackPath: kCallbackPath
277+ keychainName: kKeychainName
278+ isFreshInstall: YES ];
279+ }
280+
281+
204282
205283#pragma mark - Helpers
206284
0 commit comments