[go: nahoru, domu]

blob: 1fa7d013bf8efa6bf88fce6eddd0b6d35c84e61c [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/authentication/signin/add_account_signin/add_account_signin_manager.h"
#import <UIKit/UIKit.h>
#import "base/apple/foundation_util.h"
#import "base/strings/sys_string_conversions.h"
#import "base/test/ios/wait_util.h"
#import "base/test/task_environment.h"
#import "base/test/test_timeouts.h"
#import "components/prefs/pref_registry_simple.h"
#import "components/prefs/testing_pref_service.h"
#import "components/signin/public/base/signin_pref_names.h"
#import "ios/chrome/browser/shared/model/application_context/application_context.h"
#import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
#import "ios/chrome/browser/signin/fake_system_identity.h"
#import "ios/chrome/browser/signin/fake_system_identity_interaction_manager.h"
#import "ios/chrome/browser/signin/fake_system_identity_manager.h"
#import "ios/chrome/browser/signin/identity_manager_factory.h"
#import "ios/web/common/uikit_ui_util.h"
#import "testing/gtest_mac.h"
#import "testing/platform_test.h"
#import "third_party/ocmock/OCMock/OCMock.h"
#import "third_party/ocmock/gtest_support.h"
namespace {
// Constants for configuring a FakeSystemIdentity.
const char kTestGaiaID[] = "fooID";
const char kTestEmail[] = "foo@gmail.com";
} // namespace
class AddAccountSigninManagerTest : public PlatformTest {
public:
AddAccountSigninManagerTest()
: browser_state_(TestChromeBrowserState::Builder().Build()) {
identity_interaction_manager_ = GetIdentityInteractionManager();
}
FakeSystemIdentityInteractionManager* GetIdentityInteractionManager() {
fake_identity_ = [FakeSystemIdentity
identityWithEmail:[NSString stringWithUTF8String:kTestEmail]
gaiaID:[NSString stringWithUTF8String:kTestGaiaID]
name:@"Foo"];
return base::apple::ObjCCastStrict<FakeSystemIdentityInteractionManager>(
fake_system_identity_manager()->CreateInteractionManager());
}
void WaitForFakeAddAccountViewPresented(NSString* expectedUserEmail) {
EXPECT_NSEQ(expectedUserEmail,
identity_interaction_manager_.lastStartAuthActivityUserEmail);
ASSERT_TRUE(base::test::ios::WaitUntilConditionOrTimeout(
TestTimeouts::action_timeout(), ^bool() {
return identity_interaction_manager_.isActivityViewPresented;
}));
}
void WaitForFakeAddAccountViewDismissed() {
ASSERT_TRUE(base::test::ios::WaitUntilConditionOrTimeout(
TestTimeouts::action_timeout(), ^bool() {
return !identity_interaction_manager_.isActivityViewPresented;
}));
}
FakeSystemIdentityManager* fake_system_identity_manager() {
return FakeSystemIdentityManager::FromSystemIdentityManager(
GetApplicationContext()->GetSystemIdentityManager());
}
protected:
void SetUp() override {
PlatformTest::SetUp();
PrefService* prefs = browser_state_->GetPrefs();
prefs->SetString(prefs::kGoogleServicesLastUsername, kTestEmail);
prefs->SetString(prefs::kGoogleServicesLastGaiaId, kTestGaiaID);
base_view_controller_ = [[UIViewController alloc] init];
base_view_controller_.view.backgroundColor = UIColor.blueColor;
GetAnyKeyWindow().rootViewController = base_view_controller_;
signin_manager_ = [[AddAccountSigninManager alloc]
initWithBaseViewController:base_view_controller_
identityInteractionManager:identity_interaction_manager_];
signin_manager_delegate_ =
OCMStrictProtocolMock(@protocol(AddAccountSigninManagerDelegate));
signin_manager_.delegate = signin_manager_delegate_;
}
void TearDown() override {
EXPECT_OCMOCK_VERIFY((id)signin_manager_delegate_);
PlatformTest::TearDown();
}
// Needed for test browser state created by TestChromeBrowserState().
base::test::TaskEnvironment environment_;
std::unique_ptr<TestChromeBrowserState> browser_state_;
UIViewController* base_view_controller_ = nil;
AddAccountSigninManager* signin_manager_ = nil;
id<AddAccountSigninManagerDelegate> signin_manager_delegate_ = nil;
FakeSystemIdentityInteractionManager* identity_interaction_manager_ = nil;
FakeSystemIdentity* fake_identity_ = nil;
};
// Verifies the following state in the successful add account flow:
// - Account is added to the identity service
// - Completion callback is called with success state
TEST_F(AddAccountSigninManagerTest, AddAccountWithEmail) {
// Verify that completion was called with success state.
FakeSystemIdentityInteractionManager.identity = fake_identity_;
OCMExpect([signin_manager_delegate_
addAccountSigninManagerFinishedWithSigninResult:
SigninCoordinatorResultSuccess
identity:fake_identity_]);
[signin_manager_ showSigninWithDefaultUserEmail:fake_identity_.userEmail];
WaitForFakeAddAccountViewPresented(
/*expectedUserEmail=*/fake_identity_.userEmail);
[identity_interaction_manager_ simulateDidTapAddAccount];
WaitForFakeAddAccountViewDismissed();
}
// Verifies the following state in the add account flow with a user cancel:
// - Account is not added to the identity service
// - Completion callback is called with user cancel state
TEST_F(AddAccountSigninManagerTest, AddAccountWithEmailIntentWithUserCancel) {
// Verify that completion was called with canceled result state.
OCMExpect([signin_manager_delegate_
addAccountSigninManagerFinishedWithSigninResult:
SigninCoordinatorResultCanceledByUser
identity:nil]);
[signin_manager_ showSigninWithDefaultUserEmail:@"email@example.com"];
WaitForFakeAddAccountViewPresented(
/*expectedUserEmail=*/@"email@example.com");
[identity_interaction_manager_ simulateDidTapCancel];
WaitForFakeAddAccountViewDismissed();
}
// Verifies the following state in the add account flow with an error handled by
// the view controller:
// - Account is not added to the identity service
// - Completion callback is called with user cancel state
TEST_F(AddAccountSigninManagerTest,
AddAccountWithEmailWithErrorHandledByViewController) {
// Verify that completion was called with canceled result state and an error
// is shown.
OCMExpect([signin_manager_delegate_
addAccountSigninManagerFailedWithError:[OCMArg any]]);
[signin_manager_ showSigninWithDefaultUserEmail:@"email@example.com"];
WaitForFakeAddAccountViewPresented(
/*expectedUserEmail=*/@"email@example.com");
[identity_interaction_manager_ simulateDidThrowUnhandledError];
WaitForFakeAddAccountViewDismissed();
}
TEST_F(AddAccountSigninManagerTest, AddAccountWithEmailSigninInterrupted) {
// Verify that completion was called with interrupted result state.
OCMExpect([signin_manager_delegate_
addAccountSigninManagerFinishedWithSigninResult:
SigninCoordinatorResultInterrupted
identity:nil]);
[signin_manager_ showSigninWithDefaultUserEmail:@"email@example.com"];
WaitForFakeAddAccountViewPresented(
/*expectedUserEmail=*/@"email@example.com");
__block BOOL completionCalled = NO;
[signin_manager_
interruptWithAction:SigninCoordinatorInterrupt::DismissWithAnimation
completion:^() {
completionCalled = YES;
}];
WaitForFakeAddAccountViewDismissed();
EXPECT_TRUE(completionCalled);
}
// Verifies the following state in the successful reauth flow:
// - Account is added to the identity service
// - Completion callback is called with success state
TEST_F(AddAccountSigninManagerTest, AddAccountWithoutEmailWithSuccess) {
// Verify that completion was called with canceled result state.
FakeSystemIdentityInteractionManager.identity = fake_identity_;
OCMExpect([signin_manager_delegate_
addAccountSigninManagerFinishedWithSigninResult:
SigninCoordinatorResultSuccess
identity:fake_identity_]);
[signin_manager_ showSigninWithDefaultUserEmail:nil];
WaitForFakeAddAccountViewPresented(/*expectedUserEmail=*/nil);
[identity_interaction_manager_ simulateDidTapAddAccount];
WaitForFakeAddAccountViewDismissed();
}
// Verifies the following state in the reauth flow with a user cancel:
// - Account is not added to the identity service
// - Completion callback is called with user cancel state
TEST_F(AddAccountSigninManagerTest, AddAccountWithoutEmailWithUserCancel) {
// Verify that completion was called with canceled result state.
OCMExpect([signin_manager_delegate_
addAccountSigninManagerFinishedWithSigninResult:
SigninCoordinatorResultCanceledByUser
identity:nil]);
[signin_manager_ showSigninWithDefaultUserEmail:nil];
WaitForFakeAddAccountViewPresented(/*expectedUserEmail=*/nil);
[identity_interaction_manager_ simulateDidTapCancel];
WaitForFakeAddAccountViewDismissed();
}
// Verifies the following state in the successful reauth flow:
// - No last know sync account in the identity service
// - Completion callback is called with success state
//
// Regression test for crbug/1443096
// TODO(crbug.com/1454101): This test is not relevant anymore in this class.
// This should be migrated in a EGTest or an unittest for
// AddAccountSigninCoordinator.
TEST_F(AddAccountSigninManagerTest,
AddAccountWithoutEmailWithSuccessNoLastKnowSyncAccount) {
PrefService* prefs = browser_state_->GetPrefs();
prefs->ClearPref(prefs::kGoogleServicesLastUsername);
prefs->ClearPref(prefs::kGoogleServicesLastGaiaId);
// Verify that completion was called with canceled result state.
FakeSystemIdentityInteractionManager.identity = fake_identity_;
OCMExpect([signin_manager_delegate_
addAccountSigninManagerFinishedWithSigninResult:
SigninCoordinatorResultSuccess
identity:fake_identity_]);
[signin_manager_ showSigninWithDefaultUserEmail:nil];
WaitForFakeAddAccountViewPresented(/*expectedUserEmail=*/nil);
[identity_interaction_manager_ simulateDidTapAddAccount];
WaitForFakeAddAccountViewDismissed();
}
// Verifies the following state in the reauth flow with an error handled by the
// view controller:
// - Account is not added to the identity service
// - Completion callback is called with user cancel state
TEST_F(AddAccountSigninManagerTest,
AddAccountWithoutEmailWithErrorHandledByViewController) {
// Verify that completion was called with canceled result state and an error
// is shown.
OCMExpect([signin_manager_delegate_
addAccountSigninManagerFailedWithError:[OCMArg any]]);
[signin_manager_ showSigninWithDefaultUserEmail:nil];
WaitForFakeAddAccountViewPresented(/*expectedUserEmail=*/nil);
[identity_interaction_manager_ simulateDidThrowUnhandledError];
WaitForFakeAddAccountViewDismissed();
}
TEST_F(AddAccountSigninManagerTest, AddAccountWithoutEmailSigninInterrupted) {
// Verify that completion was called with interrupted result state.
OCMExpect([signin_manager_delegate_
addAccountSigninManagerFinishedWithSigninResult:
SigninCoordinatorResultInterrupted
identity:nil]);
[signin_manager_ showSigninWithDefaultUserEmail:nil];
WaitForFakeAddAccountViewPresented(/*expectedUserEmail=*/nil);
__block BOOL completionCalled = NO;
[signin_manager_
interruptWithAction:SigninCoordinatorInterrupt::DismissWithAnimation
completion:^() {
completionCalled = YES;
}];
WaitForFakeAddAccountViewDismissed();
EXPECT_TRUE(completionCalled);
}