瀏覽代碼

Adding Unit test for apple signIn flow in FIROAuthProviderTests and FIRAuthTest

Yvonne Cheng 3 年之前
父節點
當前提交
47fd1b5ea2

+ 1 - 0
FirebaseAuth/Sources/AuthProvider/OAuth/FIROAuthCredential.m

@@ -113,6 +113,7 @@ NS_ASSUME_NONNULL_BEGIN
   request.sessionID = _sessionID;
   request.providerOAuthTokenSecret = _secret;
   request.pendingToken = _pendingToken;
+  request.displayName = _displayName;
 }
 
 #pragma mark - NSSecureCoding

+ 5 - 0
FirebaseAuth/Sources/Backend/RPC/FIRVerifyAssertionRequest.h

@@ -96,6 +96,11 @@ NS_ASSUME_NONNULL_BEGIN
  */
 @property(nonatomic, assign) BOOL autoCreate;
 
+/** @property displayName
+    @brief A displayName linked to its provider
+ */
+@property(nonatomic, copy, nullable) NSString *displayName;
+
 /** @fn initWithEndpoint:requestConfiguration:
     @brief Please use initWithProviderID:requestConfifuration instead.
  */

+ 142 - 0
FirebaseAuth/Tests/Unit/FIRAuthTests.m

@@ -160,6 +160,36 @@ static NSString *const kGoogleAccessToken = @"GOOGLE_ACCESS_TOKEN";
  */
 static NSString *const kGoogleIDToken = @"GOOGLE_ID_TOKEN";
 
+/** @var FIRAppleAuthProviderID
+    @brief The provider ID for Apple Sign-In.
+ */
+NSString *const FIRAppleAuthProviderID = @"apple.com";
+
+/** @var kAppleUD
+    @brief The fake user ID under Apple Sign-In.
+ */
+static NSString *const kAppleID = @"APPLE_ID";
+
+/** @var kAppleEmail
+    @brief The fake user email under Apple Sign-In.
+ */
+static NSString *const kAppleEmail = @"user@icloud.com";
+
+/** @var kAppleDisplayName
+    @brief The fake user display name under Apple Sign-In.
+ */
+static NSString *const kAppleDisplayName = @"Apple Doe";
+
+/** @var kAppleAccessToken
+    @brief The fake access token from Apple Sign-In.
+ */
+static NSString *const kAppleAccessToken = @"Apple_ACCESS_TOKEN";
+
+/** @var kAppleIDToken
+    @brief The fake ID token from Apple Sign-In.
+ */
+static NSString *const kAppleIDToken = @"APPLE_ID_TOKEN";
+
 /** @var kCustomToken
     @brief The fake custom token to sign in.
  */
@@ -321,6 +351,23 @@ static const NSTimeInterval kWaitInterval = .5;
   return kGoogleProfile;
 }
 
+/** @fn appleProfile
+    @brief The fake user profile under additional user data in @c FIRVerifyAssertionResponse.
+ */
++ (NSDictionary *)appleProfile {
+  static NSDictionary *kAppleProfile = nil;
+  static dispatch_once_t onceToken;
+  dispatch_once(&onceToken, ^{
+    kAppleProfile = @{
+      @"iss" : @"https://accounts.apple.com\\",
+      @"email" : kAppleEmail,
+      @"given_name" : @"User",
+      @"family_name" : @"Doe"
+    };
+  });
+  return kAppleProfile;
+}
+
 - (void)setUp {
   [super setUp];
 
@@ -1374,6 +1421,54 @@ static const NSTimeInterval kWaitInterval = .5;
   OCMVerifyAll(_mockBackend);
 }
 
+/** @fn testSignInWithAppleCredentialSuccess
+    @brief Tests the flow of a successful @c signInWithCredential:completion: call
+        with an Apple Sign-In credential.
+ */
+- (void)testSignInWithAppleCredentialSuccess {
+  OCMExpect([_mockBackend verifyAssertion:[OCMArg any] callback:[OCMArg any]])
+      .andCallBlock2(^(FIRVerifyAssertionRequest *_Nullable request,
+                       FIRVerifyAssertionResponseCallback callback) {
+        XCTAssertEqualObjects(request.APIKey, kAPIKey);
+        XCTAssertEqualObjects(request.providerID, FIRAppleAuthProviderID);
+        XCTAssertEqualObjects(request.providerIDToken, kAppleIDToken);
+        XCTAssertEqualObjects(request.providerAccessToken, kAppleAccessToken);
+        XCTAssertTrue(request.returnSecureToken);
+        dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
+          id mockVerifyAssertionResponse = OCMClassMock([FIRVerifyAssertionResponse class]);
+          OCMStub([mockVerifyAssertionResponse federatedID]).andReturn(kAppleID);
+          OCMStub([mockVerifyAssertionResponse providerID]).andReturn(FIRAppleAuthProviderID);
+          OCMStub([mockVerifyAssertionResponse localID]).andReturn(kLocalID);
+          OCMStub([mockVerifyAssertionResponse displayName]).andReturn(kAppleDisplayName);
+          OCMStub([mockVerifyAssertionResponse profile]).andReturn([[self class] appleProfile]);
+          OCMStub([mockVerifyAssertionResponse username]).andReturn(kDisplayName);
+          [self stubTokensWithMockResponse:mockVerifyAssertionResponse];
+          callback(mockVerifyAssertionResponse, nil);
+        });
+      });
+  [self expectGetAccountInfoApple];
+  XCTestExpectation *expectation = [self expectationWithDescription:@"callback"];
+  [[FIRAuth auth] signOut:NULL];
+  FIRAuthCredential *appleCredential =
+      [FIROAuthProvider credentialWithProviderID:FIRAppleAuthProviderID IDToken:kAppleIDToken rawNonce:nil accessToken:kAppleAccessToken displayName:kAppleDisplayName];
+  [[FIRAuth auth]
+      signInWithCredential:appleCredential
+                completion:^(FIRAuthDataResult *_Nullable authResult, NSError *_Nullable error) {
+                  XCTAssertTrue([NSThread isMainThread]);
+                  [self assertUserApple:authResult.user];
+                  XCTAssertEqualObjects(authResult.additionalUserInfo.profile,
+                                        [[self class] appleProfile]);
+                  XCTAssertEqualObjects(authResult.additionalUserInfo.username, kDisplayName);
+                  XCTAssertEqualObjects(authResult.additionalUserInfo.providerID,
+                                        FIRAppleAuthProviderID);
+                  XCTAssertNil(error);
+                  [expectation fulfill];
+                }];
+  [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
+  [self assertUserApple:[FIRAuth auth].currentUser];
+  OCMVerifyAll(_mockBackend);
+}
+
 /** @fn testSignInAnonymouslySuccess
     @brief Tests the flow of a successful @c signInAnonymouslyWithCompletion: call.
  */
@@ -2584,6 +2679,53 @@ static const NSTimeInterval kWaitInterval = .5;
   XCTAssertEqualObjects(googleUserInfo.email, kGoogleEmail);
 }
 
+/** @fn expectGetAccountInfoApple
+    @brief Expects a GetAccountInfo request on the mock backend and calls back with fake account
+        data for a Apple Sign-In user.
+ */
+- (void)expectGetAccountInfoApple {
+  OCMExpect([_mockBackend getAccountInfo:[OCMArg any] callback:[OCMArg any]])
+      .andCallBlock2(^(FIRGetAccountInfoRequest *_Nullable request,
+                       FIRGetAccountInfoResponseCallback callback) {
+        XCTAssertEqualObjects(request.APIKey, kAPIKey);
+        XCTAssertEqualObjects(request.accessToken, kAccessToken);
+        dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
+          id mockAppleUserInfo = OCMClassMock([FIRGetAccountInfoResponseProviderUserInfo class]);
+          OCMStub([mockAppleUserInfo providerID]).andReturn(FIRAppleAuthProviderID);
+          OCMStub([mockAppleUserInfo displayName]).andReturn(kAppleDisplayName);
+          OCMStub([mockAppleUserInfo federatedID]).andReturn(kAppleID);
+          OCMStub([mockAppleUserInfo email]).andReturn(kAppleEmail);
+          id mockGetAccountInfoResponseUser = OCMClassMock([FIRGetAccountInfoResponseUser class]);
+          OCMStub([mockGetAccountInfoResponseUser localID]).andReturn(kLocalID);
+          OCMStub([mockGetAccountInfoResponseUser displayName]).andReturn(kDisplayName);
+          OCMStub([mockGetAccountInfoResponseUser providerUserInfo])
+              .andReturn((@[ mockAppleUserInfo ]));
+          id mockGetAccountInfoResponse = OCMClassMock([FIRGetAccountInfoResponse class]);
+          OCMStub([mockGetAccountInfoResponse users]).andReturn(@[
+            mockGetAccountInfoResponseUser
+          ]);
+          callback(mockGetAccountInfoResponse, nil);
+        });
+      });
+}
+
+/** @fn assertUserApple
+    @brief Asserts the given FIRUser matching the fake data returned by
+        @c expectGetAccountInfoApple.
+    @param user The user object to be verified.
+ */
+- (void)assertUserApple:(FIRUser *)user {
+  XCTAssertNotNil(user);
+  XCTAssertEqualObjects(user.uid, kLocalID);
+  XCTAssertEqualObjects(user.displayName, kDisplayName);
+  XCTAssertEqual(user.providerData.count, 1u);
+  id<FIRUserInfo> appleUserInfo = user.providerData[0];
+  XCTAssertEqualObjects(appleUserInfo.providerID, FIRAppleAuthProviderID);
+  XCTAssertEqualObjects(appleUserInfo.uid, kAppleID);
+  XCTAssertEqualObjects(appleUserInfo.displayName, kAppleDisplayName);
+  XCTAssertEqualObjects(appleUserInfo.email, kAppleEmail);
+}
+
 /** @fn expectGetAccountInfoAnonymous
     @brief Expects a GetAccountInfo request on the mock backend and calls back with fake anonymous
         account data.

+ 4 - 4
FirebaseAuth/Tests/Unit/FIROAuthProviderTests.m

@@ -243,18 +243,18 @@ static NSString *const kUnknownErrorString =
   XCTAssertNil(OAuthCredential.IDToken);
 }
 
-/** @fn testObtainingOAuthCredentialNoIDToken
-    @brief Tests the correct creation of an OAuthCredential without an IDToken.
+/** @fn testObtainingOAuthCredentialWithDisplayName
+    @brief Tests the correct creation of an OAuthCredential with a displayName.
  */
 - (void)testObtainingOAuthCredentialWithDisplayName {
   FIRAuthCredential *credential = [FIROAuthProvider credentialWithProviderID:kFakeProviderID
-                                                                 accessToken:kFakeAccessToken];
+                                   IDToken:kFakeIDToken rawNonce:nil accessToken:kFakeAccessToken displayName:kFakeDisplayName];
   XCTAssertTrue([credential isKindOfClass:[FIROAuthCredential class]]);
   FIROAuthCredential *OAuthCredential = (FIROAuthCredential *)credential;
   XCTAssertEqualObjects(OAuthCredential.accessToken, kFakeAccessToken);
   XCTAssertEqualObjects(OAuthCredential.provider, kFakeProviderID);
+  XCTAssertEqualObjects(OAuthCredential.IDToken, kFakeIDToken);
   XCTAssertEqualObjects(OAuthCredential.displayName,kFakeDisplayName);
-  XCTAssertNil(OAuthCredential.IDToken);
 }
 
 /** @fn testObtainingOAuthCredentialWithIDToken