Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions FirebaseAuth/Sources/User/FIRUser.m
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,10 @@ - (void)reauthenticateWithProvider:(id<FIRFederatedAuthProvider>)provider
[provider getCredentialWithUIDelegate:UIDelegate
completion:^(FIRAuthCredential *_Nullable credential,
NSError *_Nullable error) {
if (error) {
completion(nil, error);
return;
}
[self reauthenticateWithCredential:credential
completion:completion];
}];
Expand Down Expand Up @@ -1335,6 +1339,10 @@ - (void)linkWithProvider:(id<FIRFederatedAuthProvider>)provider
[provider getCredentialWithUIDelegate:UIDelegate
completion:^(FIRAuthCredential *_Nullable credential,
NSError *_Nullable error) {
if (error) {
completion(nil, error);
return;
}
[self linkWithCredential:credential completion:completion];
}];
});
Expand Down
146 changes: 146 additions & 0 deletions FirebaseAuth/Tests/Unit/FIRUserTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
#import <OCMock/OCMock.h>
#import <XCTest/XCTest.h>

#import "FirebaseAuth/Sources/AuthProvider/OAuth/FIROAuthCredential_Internal.h"
#import "FirebaseAuth/Sources/Public/FirebaseAuth/FIRAuthTokenResult.h"
#import "FirebaseAuth/Sources/Public/FirebaseAuth/FIREmailAuthProvider.h"
#import "FirebaseAuth/Sources/Public/FirebaseAuth/FIRFacebookAuthProvider.h"
#import "FirebaseAuth/Sources/Public/FirebaseAuth/FIRGoogleAuthProvider.h"
#import "FirebaseAuth/Sources/Public/FirebaseAuth/FIROAuthCredential.h"
#import "FirebaseAuth/Sources/Public/FirebaseAuth/FIROAuthProvider.h"
#import "FirebaseAuth/Sources/Public/FirebaseAuth/FIRUserInfo.h"
#import "FirebaseAuth/Sources/Public/FirebaseAuth/FIRUserMetadata.h"

Expand Down Expand Up @@ -383,6 +386,21 @@
*/
static NSString *const kEnrolledAt = @"2022-08-01T18:31:15.426458Z";

/** @var kOAuthRequestURI
@brief Fake OAuthRequest URI for testing.
*/
static NSString *const kOAuthRequestURI = @"requestURI";

/** @var kOAuthSessionID
@brief Fake session ID for testing.
*/
static NSString *const kOAuthSessionID = @"sessionID";

/** @var kFakeWebSignInUserInteractionFailureReason
@brief Fake reason for FIRAuthErrorCodeWebSignInUserInteractionFailure error while testing.
*/
static NSString *const kFakeWebSignInUserInteractionFailureReason = @"fake_reason";

/** @extention FIRSecureTokenService
@brief Extends the FIRSecureTokenService class to expose one private method for testing only.
*/
Expand Down Expand Up @@ -2643,6 +2661,134 @@ - (void)testlinkCredentialProviderAlreadyLinkedError {
}

#if TARGET_OS_IOS
/** @fn testlinkProviderFailure
@brief Tests the flow of a failed @c linkWithProvider:completion:
call.
*/
- (void)testlinkProviderFailure {
[self expectVerifyAssertionRequest:FIRFacebookAuthProviderID
federatedID:kFacebookID
displayName:kFacebookDisplayName
profile:[[self class] googleProfile]
providerIDToken:kFacebookIDToken
providerAccessToken:kFacebookAccessToken];

XCTestExpectation *expectation = [self expectationWithDescription:@"callback"];
[[FIRAuth auth] signOut:NULL];
FIRAuthCredential *facebookCredential =
[FIRFacebookAuthProvider credentialWithAccessToken:kFacebookAccessToken];
[[FIRAuth auth]
signInWithCredential:facebookCredential
completion:^(FIRAuthDataResult *_Nullable authResult, NSError *_Nullable error) {
XCTAssertTrue([NSThread isMainThread]);
[self assertUserFacebook:authResult.user];
XCTAssertEqualObjects(authResult.additionalUserInfo.profile,
[[self class] googleProfile]);
XCTAssertEqualObjects(authResult.additionalUserInfo.username, kUserName);
XCTAssertEqualObjects(authResult.additionalUserInfo.providerID,
FIRFacebookAuthProviderID);
XCTAssertNil(error);

OCMExpect([self->_mockBackend verifyAssertion:[OCMArg any] callback:[OCMArg any]])
.andDispatchError2(
[FIRAuthErrorUtils webSignInUserInteractionFailureWithReason:
kFakeWebSignInUserInteractionFailureReason]);
id mockProvider = OCMClassMock([FIROAuthProvider class]);
OCMExpect([mockProvider getCredentialWithUIDelegate:[OCMArg any]
completion:[OCMArg any]])
.andCallBlock2(^(id<FIRAuthUIDelegate> delegate,
FIRAuthCredentialCallback callback) {
dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
FIROAuthCredential *credential =
[[FIROAuthCredential alloc] initWithProviderID:FIRGoogleAuthProviderID
sessionID:kOAuthSessionID
OAuthResponseURLString:kOAuthRequestURI];
callback(credential, nil);
});
});

[authResult.user
linkWithProvider:mockProvider
UIDelegate:nil
completion:^(FIRAuthDataResult *_Nullable result,
NSError *_Nullable error) {
XCTAssertTrue([NSThread isMainThread]);
XCTAssertEqual(error.code,
FIRAuthErrorCodeWebSignInUserInteractionFailure);
XCTAssertEqualObjects(
error.userInfo[NSLocalizedFailureReasonErrorKey],
kFakeWebSignInUserInteractionFailureReason);
[expectation fulfill];
}];
}];
[self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
OCMVerifyAll(_mockBackend);
}

/** @fn testReauthenticateWithProviderFailure
@brief Tests the flow of a failed @c reauthenticateWithProvider:completion: call.
*/
- (void)testReauthenticateWithProviderFailure {
[self expectVerifyAssertionRequest:FIRFacebookAuthProviderID
federatedID:kFacebookID
displayName:kFacebookDisplayName
profile:[[self class] googleProfile]
providerIDToken:kFacebookIDToken
providerAccessToken:kFacebookAccessToken];

XCTestExpectation *expectation = [self expectationWithDescription:@"callback"];
[[FIRAuth auth] signOut:NULL];
FIRAuthCredential *facebookCredential =
[FIRFacebookAuthProvider credentialWithAccessToken:kFacebookAccessToken];
[[FIRAuth auth]
signInWithCredential:facebookCredential
completion:^(FIRAuthDataResult *_Nullable authResult, NSError *_Nullable error) {
XCTAssertTrue([NSThread isMainThread]);
[self assertUserFacebook:authResult.user];
XCTAssertEqualObjects(authResult.additionalUserInfo.profile,
[[self class] googleProfile]);
XCTAssertEqualObjects(authResult.additionalUserInfo.username, kUserName);
XCTAssertEqualObjects(authResult.additionalUserInfo.providerID,
FIRFacebookAuthProviderID);
XCTAssertNil(error);

OCMExpect([self->_mockBackend verifyAssertion:[OCMArg any] callback:[OCMArg any]])
.andDispatchError2(
[FIRAuthErrorUtils webSignInUserInteractionFailureWithReason:
kFakeWebSignInUserInteractionFailureReason]);
id mockProvider = OCMClassMock([FIROAuthProvider class]);
OCMExpect([mockProvider getCredentialWithUIDelegate:[OCMArg any]
completion:[OCMArg any]])
.andCallBlock2(^(id<FIRAuthUIDelegate> delegate,
FIRAuthCredentialCallback callback) {
dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
FIROAuthCredential *credential =
[[FIROAuthCredential alloc] initWithProviderID:FIRGoogleAuthProviderID
sessionID:kOAuthSessionID
OAuthResponseURLString:kOAuthRequestURI];
callback(credential, nil);
});
});

[authResult.user
reauthenticateWithProvider:mockProvider
UIDelegate:nil
completion:^(FIRAuthDataResult *_Nullable result,
NSError *_Nullable error) {
XCTAssertTrue([NSThread isMainThread]);
XCTAssertEqual(
error.code,
FIRAuthErrorCodeWebSignInUserInteractionFailure);
XCTAssertEqualObjects(
error.userInfo[NSLocalizedFailureReasonErrorKey],
kFakeWebSignInUserInteractionFailureReason);
[expectation fulfill];
}];
}];
[self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
OCMVerifyAll(_mockBackend);
}

/** @fn testlinkPhoneAuthCredentialSuccess
@brief Tests the flow of a successful @c linkWithCredential:completion:
call using a phoneAuthCredential.
Expand Down