diff --git a/Example/Auth/ApiTests/FirebaseAuthApiTests.m b/Example/Auth/ApiTests/FirebaseAuthApiTests.m index 5aa51708ba1..91275b6c419 100644 --- a/Example/Auth/ApiTests/FirebaseAuthApiTests.m +++ b/Example/Auth/ApiTests/FirebaseAuthApiTests.m @@ -69,7 +69,7 @@ /** Error message for invalid custom token sign in. */ NSString *kInvalidTokenErrorMessage = - @"The custom token format is incorrect. Please check the documentation."; + @"Invalid assertion format. 3 dot separated segments required."; NSString *kGoogleCliendId = KGOOGLE_CLIENT_ID; diff --git a/Example/Auth/Tests/FIRAuthLifeCycleTests.m b/Example/Auth/Tests/FIRAuthLifeCycleTests.m new file mode 100644 index 00000000000..daa77991bdb --- /dev/null +++ b/Example/Auth/Tests/FIRAuthLifeCycleTests.m @@ -0,0 +1,177 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import +#import +#import +#import + +#import "FIRApp+FIRAuthUnitTests.h" +#import "FIRAuthRequestConfiguration.h" +#import "FIRAuth_Internal.h" + +/** @var kFirebaseAppName1 + @brief A fake Firebase app name. + */ +static NSString *const kFirebaseAppName1 = @"FIREBASE_APP_NAME_1"; + +/** @var kFirebaseAppName2 + @brief Another fake Firebase app name. + */ +static NSString *const kFirebaseAppName2 = @"FIREBASE_APP_NAME_2"; + +/** @var kAPIKey + @brief The fake API key. + */ +static NSString *const kAPIKey = @"FAKE_API_KEY"; + +/** @var kExpectationTimeout + @brief The maximum time waiting for expectations to fulfill. + */ +static const NSTimeInterval kExpectationTimeout = 2; + +/** @var kWaitInterval + @brief The time waiting for background tasks to finish before continue when necessary. + */ +static const NSTimeInterval kWaitInterval = .5; + +@interface FIRAuthLifeCycleTests : XCTestCase + +@end + +@implementation FIRAuthLifeCycleTests + +- (void)setUp { + [super setUp]; + + [FIRApp resetAppForAuthUnitTests]; +} + +- (void)tearDown { + [super tearDown]; +} + +/** @fn testSingleton + @brief Verifies the @c auth method behaves like a singleton. + */ +- (void)testSingleton { + FIRAuth *auth1 = [FIRAuth auth]; + XCTAssertNotNil(auth1); + FIRAuth *auth2 = [FIRAuth auth]; + XCTAssertEqual(auth1, auth2); +} + +/** @fn testDefaultAuth + @brief Verifies the @c auth method associates with the default Firebase app. + */ +- (void)testDefaultAuth { + FIRAuth *auth1 = [FIRAuth auth]; + FIRAuth *auth2 = [FIRAuth authWithApp:[FIRApp defaultApp]]; + XCTAssertEqual(auth1, auth2); + XCTAssertEqual(auth1.app, [FIRApp defaultApp]); +} + +/** @fn testNilAppException + @brief Verifies the @c auth method raises an exception if the default FIRApp is not configured. + */ +- (void)testNilAppException { + [FIRApp resetApps]; + XCTAssertThrows([FIRAuth auth]); +} + +/** @fn testAppAPIkey + @brief Verifies the API key is correctly copied from @c FIRApp to @c FIRAuth . + */ +- (void)testAppAPIkey { + FIRAuth *auth = [FIRAuth auth]; + XCTAssertEqualObjects(auth.requestConfiguration.APIKey, kAPIKey); +} + +/** @fn testAppAssociation + @brief Verifies each @c FIRApp instance associates with a @c FIRAuth . + */ +- (void)testAppAssociation { + FIRApp *app1 = [self app1]; + FIRAuth *auth1 = [FIRAuth authWithApp:app1]; + XCTAssertNotNil(auth1); + XCTAssertEqual(auth1.app, app1); + + FIRApp *app2 = [self app2]; + FIRAuth *auth2 = [FIRAuth authWithApp:app2]; + XCTAssertNotNil(auth2); + XCTAssertEqual(auth2.app, app2); + + XCTAssertNotEqual(auth1, auth2); +} + +/** @fn testLifeCycle + @brief Verifies the life cycle of @c FIRAuth is the same as its associated @c FIRApp . + */ +- (void)testLifeCycle { + __weak FIRApp *app; + __weak FIRAuth *auth; + @autoreleasepool { + FIRApp *app1 = [self app1]; + app = app1; + auth = [FIRAuth authWithApp:app1]; + // Verify that neither the app nor the auth is released yet, i.e., the app owns the auth + // because nothing else retains the auth. + XCTAssertNotNil(app); + XCTAssertNotNil(auth); + } + [self waitForTimeIntervel:kWaitInterval]; + // Verify that both the app and the auth are released upon exit of the autorelease pool, + // i.e., the app is the sole owner of the auth. + XCTAssertNil(app); + XCTAssertNil(auth); +} + +/** @fn app1 + @brief Creates a Firebase app. + @return A @c FIRApp with some name. + */ +- (FIRApp *)app1 { + return [FIRApp appForAuthUnitTestsWithName:kFirebaseAppName1]; +} + +/** @fn app2 + @brief Creates another Firebase app. + @return A @c FIRApp with some other name. + */ +- (FIRApp *)app2 { + return [FIRApp appForAuthUnitTestsWithName:kFirebaseAppName2]; +} + +/** @fn waitForTimeInterval: + @brief Wait for a particular time interval. + @remarks This method also waits for all other pending @c XCTestExpectation instances. + */ +- (void)waitForTimeIntervel:(NSTimeInterval)timeInterval { + static dispatch_queue_t queue; + static dispatch_once_t onceToken; + XCTestExpectation *expectation = [self expectationWithDescription:@"waitForTimeIntervel:"]; + dispatch_once(&onceToken, ^{ + queue = dispatch_queue_create("com.google.FIRAuthUnitTests.waitForTimeIntervel", NULL); + }); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timeInterval * NSEC_PER_SEC), queue, ^() { + [expectation fulfill]; + }); + [self waitForExpectationsWithTimeout:timeInterval + kExpectationTimeout handler:nil]; +} + +@end diff --git a/Example/Auth/Tests/FIRAuthTests.m b/Example/Auth/Tests/FIRAuthTests.m index 23518cd51ac..3ca17aedf49 100644 --- a/Example/Auth/Tests/FIRAuthTests.m +++ b/Example/Auth/Tests/FIRAuthTests.m @@ -68,16 +68,6 @@ #import "FIRPhoneAuthProvider.h" #endif -/** @var kFirebaseAppName1 - @brief A fake Firebase app name. - */ -static NSString *const kFirebaseAppName1 = @"FIREBASE_APP_NAME_1"; - -/** @var kFirebaseAppName2 - @brief Another fake Firebase app name. - */ -static NSString *const kFirebaseAppName2 = @"FIREBASE_APP_NAME_2"; - /** @var kAPIKey @brief The fake API key. */ @@ -288,83 +278,6 @@ - (void)tearDown { [super tearDown]; } -#pragma mark - Life Cycle Tests - -/** @fn testSingleton - @brief Verifies the @c auth method behaves like a singleton. - */ -- (void)testSingleton { - FIRAuth *auth1 = [FIRAuth auth]; - XCTAssertNotNil(auth1); - FIRAuth *auth2 = [FIRAuth auth]; - XCTAssertEqual(auth1, auth2); -} - -/** @fn testDefaultAuth - @brief Verifies the @c auth method associates with the default Firebase app. - */ -- (void)testDefaultAuth { - FIRAuth *auth1 = [FIRAuth auth]; - FIRAuth *auth2 = [FIRAuth authWithApp:[FIRApp defaultApp]]; - XCTAssertEqual(auth1, auth2); - XCTAssertEqual(auth1.app, [FIRApp defaultApp]); -} - -/** @fn testNilAppException - @brief Verifies the @c auth method raises an exception if the default FIRApp is not configured. - */ -- (void)testNilAppException { - [FIRApp resetApps]; - XCTAssertThrows([FIRAuth auth]); -} - -/** @fn testAppAPIkey - @brief Verifies the API key is correctly copied from @c FIRApp to @c FIRAuth . - */ -- (void)testAppAPIkey { - FIRAuth *auth = [FIRAuth auth]; - XCTAssertEqualObjects(auth.requestConfiguration.APIKey, kAPIKey); -} - -/** @fn testAppAssociation - @brief Verifies each @c FIRApp instance associates with a @c FIRAuth . - */ -- (void)testAppAssociation { - FIRApp *app1 = [self app1]; - FIRAuth *auth1 = [FIRAuth authWithApp:app1]; - XCTAssertNotNil(auth1); - XCTAssertEqual(auth1.app, app1); - - FIRApp *app2 = [self app2]; - FIRAuth *auth2 = [FIRAuth authWithApp:app2]; - XCTAssertNotNil(auth2); - XCTAssertEqual(auth2.app, app2); - - XCTAssertNotEqual(auth1, auth2); -} - -/** @fn testLifeCycle - @brief Verifies the life cycle of @c FIRAuth is the same as its associated @c FIRApp . - */ -- (void)testLifeCycle { - __weak FIRApp *app; - __weak FIRAuth *auth; - @autoreleasepool { - FIRApp *app1 = [self app1]; - app = app1; - auth = [FIRAuth authWithApp:app1]; - // Verify that neither the app nor the auth is released yet, i.e., the app owns the auth - // because nothing else retains the auth. - XCTAssertNotNil(app); - XCTAssertNotNil(auth); - } - [self waitForTimeIntervel:kWaitInterval]; - // Verify that both the app and the auth are released upon exit of the autorelease pool, - // i.e., the app is the sole owner of the auth. - XCTAssertNil(app); - XCTAssertNil(auth); -} - #pragma mark - Server API Tests /** @fn testFetchProvidersForEmailSuccess @@ -2276,22 +2189,6 @@ - (void)enableAutoTokenRefresh { [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil]; } -/** @fn app1 - @brief Creates a Firebase app. - @return A @c FIRApp with some name. - */ -- (FIRApp *)app1 { - return [FIRApp appForAuthUnitTestsWithName:kFirebaseAppName1]; -} - -/** @fn app2 - @brief Creates another Firebase app. - @return A @c FIRApp with some other name. - */ -- (FIRApp *)app2 { - return [FIRApp appForAuthUnitTestsWithName:kFirebaseAppName2]; -} - /** @fn stubSecureTokensWithMockResponse @brief Creates stubs on the mock response object with access and refresh tokens @param mockResponse The mock response object. diff --git a/Example/Firebase.xcodeproj/project.pbxproj b/Example/Firebase.xcodeproj/project.pbxproj index 2d8cf5da68e..cb19ad1d5ce 100644 --- a/Example/Firebase.xcodeproj/project.pbxproj +++ b/Example/Firebase.xcodeproj/project.pbxproj @@ -103,6 +103,9 @@ 0672F2F31EBBA7D900818E87 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0672F2F11EBBA7D900818E87 /* GoogleService-Info.plist */; }; 069428831EC3B38C00F7BC69 /* 1mb.dat in Resources */ = {isa = PBXBuildFile; fileRef = 069428801EC3B35A00F7BC69 /* 1mb.dat */; }; 06C24A061EC39BCB005208CA /* FIRStorageIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 06121ECA1EC39A0B0008D70E /* FIRStorageIntegrationTests.m */; }; + 405EEF4C2216518B00B08FF4 /* FIRAuthLifeCycleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 405EEF4B2216518A00B08FF4 /* FIRAuthLifeCycleTests.m */; }; + 405EEF4D2216518B00B08FF4 /* FIRAuthLifeCycleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 405EEF4B2216518A00B08FF4 /* FIRAuthLifeCycleTests.m */; }; + 405EEF4E2216518B00B08FF4 /* FIRAuthLifeCycleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 405EEF4B2216518A00B08FF4 /* FIRAuthLifeCycleTests.m */; }; 408870AB21AE0218008AAE73 /* FIRSignInWithGameCenterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 408870AA21AE0218008AAE73 /* FIRSignInWithGameCenterTests.m */; }; 409E1130219FA260000E6CFC /* FIRVerifyIOSClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 409E112F219FA260000E6CFC /* FIRVerifyIOSClientTests.m */; }; 7E9485421F578AC4005A3939 /* FIRAuthURLPresenterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E94853F1F578A9D005A3939 /* FIRAuthURLPresenterTests.m */; }; @@ -914,6 +917,7 @@ 069428801EC3B35A00F7BC69 /* 1mb.dat */ = {isa = PBXFileReference; lastKnownFileType = file; path = 1mb.dat; sourceTree = ""; }; 0697B1201EC13D8A00542174 /* Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64.h; sourceTree = ""; }; 0697B1211EC13D8A00542174 /* Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Base64.m; sourceTree = ""; }; + 405EEF4B2216518A00B08FF4 /* FIRAuthLifeCycleTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIRAuthLifeCycleTests.m; sourceTree = ""; }; 408870AA21AE0218008AAE73 /* FIRSignInWithGameCenterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIRSignInWithGameCenterTests.m; sourceTree = ""; }; 409E112F219FA260000E6CFC /* FIRVerifyIOSClientTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIRVerifyIOSClientTests.m; sourceTree = ""; }; 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -2174,6 +2178,7 @@ DE9314FF1E86C6FF0083EDBF /* FIRAuthDispatcherTests.m */, DE9315001E86C6FF0083EDBF /* FIRAuthGlobalWorkQueueTests.m */, DE9315011E86C6FF0083EDBF /* FIRAuthKeychainTests.m */, + 405EEF4B2216518A00B08FF4 /* FIRAuthLifeCycleTests.m */, DE750DB81EB3DD4000A75E47 /* FIRAuthNotificationManagerTests.m */, DE9315021E86C6FF0083EDBF /* FIRAuthSerialTaskQueueTests.m */, DE9315031E86C6FF0083EDBF /* FIRAuthTests.m */, @@ -3763,6 +3768,7 @@ buildActionMask = 2147483647; files = ( D018538D1EDAD364003A645C /* FIRGetOOBConfirmationCodeResponseTests.m in Sources */, + 405EEF4D2216518B00B08FF4 /* FIRAuthLifeCycleTests.m in Sources */, D018538E1EDAD364003A645C /* FIRGetAccountInfoRequestTests.m in Sources */, D018538F1EDAD364003A645C /* FIRSignUpNewUserResponseTests.m in Sources */, D01853901EDAD364003A645C /* FIRGetOOBConfirmationCodeRequestTests.m in Sources */, @@ -4126,6 +4132,7 @@ DEF6C3191FBCE775005D0740 /* FIRAuthKeychainTests.m in Sources */, DEF6C32A1FBCE775005D0740 /* FIRGitHubAuthProviderTests.m in Sources */, DEF6C3321FBCE775005D0740 /* FIRSignUpNewUserRequestTests.m in Sources */, + 405EEF4E2216518B00B08FF4 /* FIRAuthLifeCycleTests.m in Sources */, DEF6C30F1FBCE775005D0740 /* FIRAdditionalUserInfoTests.m in Sources */, DEF6C31B1FBCE775005D0740 /* FIRAuthSerialTaskQueueTests.m in Sources */, DEF6C3251FBCE775005D0740 /* FIRGetAccountInfoResponseTests.m in Sources */, @@ -4235,6 +4242,7 @@ DE9315741E86C71C0083EDBF /* FIRTwitterAuthProviderTests.m in Sources */, DE750DC01EB3DD6F00A75E47 /* FIRAuthNotificationManagerTests.m in Sources */, DE93156A1E86C71C0083EDBF /* FIRGitHubAuthProviderTests.m in Sources */, + 405EEF4C2216518B00B08FF4 /* FIRAuthLifeCycleTests.m in Sources */, DE9315761E86C71C0083EDBF /* FIRVerifyAssertionRequestTests.m in Sources */, DE9315781E86C71C0083EDBF /* FIRVerifyCustomTokenRequestTests.m in Sources */, DE93157C1E86C71C0083EDBF /* FIRVerifyPhoneNumberRequestTests.m in Sources */,