Commit 75044a52 authored by Nohemi Fernandez's avatar Nohemi Fernandez Committed by Commit Bot

[iOS] Add a new option to non-managed account Sign-Out.

Adds a new option for users in non-managed accounts to clear synced
data from their local device when signing out.

Bug: 1005509
Change-Id: Iae3b599b3ca3698b2a176bd56b470c6787c74367
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2007695
Commit-Queue: Nohemi Fernandez <fernandex@chromium.org>
Reviewed-by: default avatarJérôme Lebel <jlebel@chromium.org>
Reviewed-by: default avatarSylvain Defresne <sdefresne@chromium.org>
Cr-Commit-Position: refs/heads/master@{#734681}
parent 3c557b70
......@@ -662,6 +662,9 @@ locale. The strings in this file are specific to iOS.
<message name="IDS_IOS_DISCONNECT_DIALOG_CONTINUE_BUTTON_MOBILE" desc="The title of the continue button on the disconnect dialog [Length: 20em].">
Sign Out
</message>
<message name="IDS_IOS_DISCONNECT_DIALOG_CONTINUE_AND_CLEAR_MOBILE" desc="The title of the continue and clear browsing data button on the disconnect dialog [iOS only].">
Sign Out and Clear Synced Data
</message>
<message name="IDS_IOS_DISCONNECT_DIALOG_INFO_MOBILE" desc="The information text on the disconnect dialog [Length: 400em].">
Changes to your bookmarks, history, passwords, and other settings will no longer be synced to your Google Account. However, your existing data will remain stored in your Google Account.
</message>
......
......@@ -11,6 +11,12 @@
@class FakeChromeIdentity;
typedef NS_ENUM(NSInteger, SignOutConfirmation) {
SignOutConfirmationManagedUser,
SignOutConfirmationNonManagedUser,
SignOutConfirmationNonManagedUserWithClearedData,
};
// Methods used for the EarlGrey tests, related to UI.
@interface SigninEarlGreyUI : NSObject
......@@ -57,9 +63,9 @@
// Checks that the sign-in promo view is not visible.
+ (void)checkSigninPromoNotVisible;
// Signs out from the current identity. if |isManagedAccount| is true, the
// confirmed managed dialog is confirmed while signing out.
+ (void)signOutWithManagedAccount:(BOOL)isManagedAccount;
// Taps the appropriate action label on the sign-out dialog for the given
// |signOutConfirmation| profile and signs out from the current identity.
+ (void)signOutWithSignOutConfirmation:(SignOutConfirmation)signOutConfirmation;
@end
......
......@@ -189,16 +189,31 @@ using chrome_test_util::UnifiedConsentAddAccountButton;
assertWithMatcher:grey_nil()];
}
+ (void)signOutWithManagedAccount:(BOOL)isManagedAccount {
+ (void)signOutWithSignOutConfirmation:
(SignOutConfirmation)signOutConfirmation {
[ChromeEarlGreyUI openSettingsMenu];
[ChromeEarlGreyUI tapSettingsMenuButton:SettingsAccountButton()];
[ChromeEarlGreyUI tapAccountsMenuButton:SignOutAccountsButton()];
int confirmationLabelID = 0;
if (isManagedAccount) {
confirmationLabelID = IDS_IOS_MANAGED_DISCONNECT_DIALOG_ACCEPT_UNITY;
} else {
confirmationLabelID = IDS_IOS_DISCONNECT_DIALOG_CONTINUE_BUTTON_MOBILE;
switch (signOutConfirmation) {
case SignOutConfirmationManagedUser: {
confirmationLabelID = IDS_IOS_MANAGED_DISCONNECT_DIALOG_ACCEPT_UNITY;
break;
}
case SignOutConfirmationNonManagedUser: {
confirmationLabelID = IDS_IOS_DISCONNECT_DIALOG_CONTINUE_BUTTON_MOBILE;
break;
}
case SignOutConfirmationNonManagedUserWithClearedData: {
confirmationLabelID = IDS_IOS_DISCONNECT_DIALOG_CONTINUE_AND_CLEAR_MOBILE;
break;
}
default: {
NOTREACHED();
break;
}
}
id<GREYMatcher> confirmationButtonMatcher = [ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:confirmationLabelID];
[[EarlGrey selectElementWithMatcher:confirmationButtonMatcher]
......
......@@ -111,7 +111,9 @@ source_set("eg_tests") {
":test_support",
"//ios/chrome/app/strings",
"//ios/chrome/browser/tabs",
"//ios/chrome/browser/ui:feature_flags",
"//ios/chrome/browser/ui/authentication:eg_test_support",
"//ios/chrome/browser/ui/bookmarks:eg_test_support",
"//ios/chrome/test/app:test_support",
"//ios/chrome/test/earl_grey:test_support",
"//ios/public/provider/chrome/browser/signin:fake_chrome_identity",
......@@ -180,7 +182,9 @@ source_set("eg2_tests") {
":eg_test_support+eg2",
"//base",
"//ios/chrome/app/strings",
"//ios/chrome/browser/ui:feature_flags",
"//ios/chrome/browser/ui/authentication:eg_test_support+eg2",
"//ios/chrome/browser/ui/bookmarks:eg_test_support+eg2",
"//ios/chrome/browser/ui/settings/google_services:constants",
"//ios/chrome/test/earl_grey:eg_test_support+eg2",
"//ios/public/provider/chrome/browser/signin:fake_chrome_identity",
......
......@@ -4,11 +4,19 @@
#import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui.h"
#import "ios/chrome/browser/ui/authentication/signin_earlgrey_utils.h"
#import "ios/chrome/browser/ui/authentication/signin_earlgrey_utils_app_interface.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_earl_grey.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_earl_grey_ui.h"
#import "ios/chrome/browser/ui/ui_feature_flags.h"
#import "ios/chrome/grit/ios_strings.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
#import "ios/chrome/test/earl_grey/chrome_matchers.h"
#import "ios/chrome/test/earl_grey/chrome_test_case.h"
#import "ios/public/provider/chrome/browser/signin/fake_chrome_identity.h"
#import "ios/testing/earl_grey/app_launch_manager.h"
#import "ios/testing/earl_grey/earl_grey_test.h"
#include "ui/base/l10n/l10n_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
......@@ -22,11 +30,18 @@ using chrome_test_util::PrimarySignInButton;
namespace {
// Constant for timeout while waiting for asynchronous sync operations.
const NSTimeInterval kSyncOperationTimeout = 10.0;
// Returns a matcher for a button that matches the userEmail in the given
// |fakeIdentity|.
id<GREYMatcher> ButtonWithFakeIdentity(FakeChromeIdentity* fakeIdentity) {
return ButtonWithAccessibilityLabel(fakeIdentity.userEmail);
}
id<GREYMatcher> NoBookmarksLabel() {
return grey_text(l10n_util::GetNSString(IDS_IOS_BOOKMARK_NO_BOOKMARKS_LABEL));
}
}
// Integration tests using the Account Settings screen.
......@@ -35,6 +50,25 @@ id<GREYMatcher> ButtonWithFakeIdentity(FakeChromeIdentity* fakeIdentity) {
@implementation AccountCollectionsTestCase
- (void)tearDown {
[ChromeEarlGrey waitForBookmarksToFinishLoading];
[ChromeEarlGrey clearBookmarks];
[BookmarkEarlGrey clearBookmarksPositionCache];
[ChromeEarlGrey clearSyncServerData];
[super tearDown];
}
- (void)setUp {
[super setUp];
[ChromeEarlGrey waitForBookmarksToFinishLoading];
[ChromeEarlGrey clearBookmarks];
GREYAssertEqual(
[ChromeEarlGrey numberOfSyncEntitiesWithType:syncer::BOOKMARKS], 0,
@"No bookmarks should exist before tests start.");
}
// Tests that the Sync and Account Settings screen are correctly popped if the
// signed in account is removed.
- (void)testSignInPopUpAccountOnSyncSettings {
......@@ -138,6 +172,74 @@ id<GREYMatcher> ButtonWithFakeIdentity(FakeChromeIdentity* fakeIdentity) {
performAction:grey_tap()];
}
// Tests that selecting sign-out from a non-managed account keeps the user's
// synced data.
- (void)testSignOutFromNonManagedAccountKeepsData {
// Earl Grey 1 does not enable experimental flags.
#if defined(CHROME_EARL_GREY_1)
EARL_GREY_TEST_SKIPPED(@"Test skipped on Earl Grey 1.");
#endif
[[AppLaunchManager sharedManager]
ensureAppLaunchedWithFeaturesEnabled:{kClearSyncedData}
disabled:{}
relaunchPolicy:NoForceRelaunchAndResetState];
FakeChromeIdentity* fakeIdentity = [SigninEarlGreyUtils fakeIdentity1];
// Sign In |fakeIdentity|.
[SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity];
// Add a bookmark after sync is initialized.
[ChromeEarlGrey waitForSyncInitialized:YES syncTimeout:kSyncOperationTimeout];
[ChromeEarlGrey waitForBookmarksToFinishLoading];
[SigninEarlGreyUtilsAppInterface addBookmark:@"youtube.com"
withTitle:@"cats"];
[SigninEarlGreyUI
signOutWithSignOutConfirmation:SignOutConfirmationNonManagedUser];
// Open the Bookmarks screen on the Tools menu.
[BookmarkEarlGreyUI openBookmarks];
[BookmarkEarlGreyUI openMobileBookmarks];
// Assert that the 'cats' bookmark is displayed.
[[EarlGrey selectElementWithMatcher:ButtonWithAccessibilityLabel(@"cats")]
assertWithMatcher:grey_notNil()];
}
// Tests that selecting sign-out and clear data from a non-managed user account
// clears the user's synced data.
- (void)testSignOutAndClearDataFromNonManagedAccountClearsData {
// Earl Grey 1 does not enable experimental flags.
#if defined(CHROME_EARL_GREY_1)
EARL_GREY_TEST_SKIPPED(@"Test skipped on Earl Grey 1.");
#endif
[[AppLaunchManager sharedManager]
ensureAppLaunchedWithFeaturesEnabled:{kClearSyncedData}
disabled:{}
relaunchPolicy:NoForceRelaunchAndResetState];
FakeChromeIdentity* fakeIdentity = [SigninEarlGreyUtils fakeIdentity1];
// Sign In |fakeIdentity|.
[SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity];
// Add a bookmark after sync is initialized.
[ChromeEarlGrey waitForSyncInitialized:YES syncTimeout:kSyncOperationTimeout];
[ChromeEarlGrey waitForBookmarksToFinishLoading];
[SigninEarlGreyUtilsAppInterface addBookmark:@"youtube.com"
withTitle:@"cats"];
[SigninEarlGreyUI signOutWithSignOutConfirmation:
SignOutConfirmationNonManagedUserWithClearedData];
// Open the Bookmarks screen on the Tools menu.
[BookmarkEarlGreyUI openBookmarks];
[BookmarkEarlGreyUI openMobileBookmarks];
// Assert that there are no bookmarks.
[[EarlGrey selectElementWithMatcher:NoBookmarksLabel()]
assertWithMatcher:grey_notNil()];
}
// Tests that the user isn't signed out and the UI is correct when the
// disconnect is cancelled in the Account Settings screen.
- (void)testSignInDisconnectCancelled {
......
......@@ -5,6 +5,7 @@
#import "ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.h"
#import "base/mac/foundation_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
......@@ -347,11 +348,11 @@ typedef NS_ENUM(NSInteger, ItemType) {
return;
}
NSString* title = l10n_util::GetNSString(IDS_IOS_DISCONNECT_DIALOG_TITLE);
NSString* message =
l10n_util::GetNSString(IDS_IOS_DISCONNECT_DIALOG_INFO_MOBILE);
NSString* continueButtonTitle =
l10n_util::GetNSString(IDS_IOS_DISCONNECT_DIALOG_CONTINUE_BUTTON_MOBILE);
NSString* title = nil;
NSString* message = nil;
NSString* continueButtonTitle = nil;
NSString* clearDataButtonTitle = nil;
if ([self authService] -> IsAuthenticatedIdentityManaged()) {
signin::IdentityManager* identityManager =
IdentityManagerFactory::GetForBrowserState(_browser->GetBrowserState());
......@@ -361,6 +362,7 @@ typedef NS_ENUM(NSInteger, ItemType) {
std::string hosted_domain = accountInfo.has_value()
? accountInfo.value().hosted_domain
: std::string();
title =
l10n_util::GetNSString(IDS_IOS_MANAGED_DISCONNECT_DIALOG_TITLE_UNITY);
message =
......@@ -374,7 +376,10 @@ typedef NS_ENUM(NSInteger, ItemType) {
l10n_util::GetNSString(IDS_IOS_DISCONNECT_DIALOG_INFO_MOBILE_UNITY);
continueButtonTitle = l10n_util::GetNSString(
IDS_IOS_DISCONNECT_DIALOG_CONTINUE_BUTTON_MOBILE);
clearDataButtonTitle = l10n_util::GetNSString(
IDS_IOS_DISCONNECT_DIALOG_CONTINUE_AND_CLEAR_MOBILE);
}
_alertCoordinator =
[[AlertCoordinator alloc] initWithBaseViewController:self
title:title
......@@ -384,28 +389,41 @@ typedef NS_ENUM(NSInteger, ItemType) {
action:nil
style:UIAlertActionStyleCancel];
__weak AccountsTableViewController* weakSelf = self;
[_alertCoordinator addItemWithTitle:continueButtonTitle
action:^{
[weakSelf handleDisconnect];
}
style:UIAlertActionStyleDefault];
[_alertCoordinator
addItemWithTitle:continueButtonTitle
action:^{
[weakSelf handleDisconnectWithForceClearSyncData:NO];
}
style:UIAlertActionStyleDefault];
if (base::FeatureList::IsEnabled(kClearSyncedData)) {
[_alertCoordinator
addItemWithTitle:clearDataButtonTitle
action:^{
[weakSelf handleDisconnectWithForceClearSyncData:YES];
}
style:UIAlertActionStyleDestructive];
}
[_alertCoordinator start];
}
- (void)handleDisconnect {
- (void)handleDisconnectWithForceClearSyncData:(BOOL)forceClearSyncData {
AuthenticationService* authService = [self authService];
if (authService->IsAuthenticated()) {
_authenticationOperationInProgress = YES;
[self preventUserInteraction];
authService->SignOut(
signin_metrics::USER_CLICKED_SIGNOUT_SETTINGS,
/*force_clear_browsing_data=*/false, ^{
signin_metrics::USER_CLICKED_SIGNOUT_SETTINGS, forceClearSyncData, ^{
[self allowUserInteraction];
_authenticationOperationInProgress = NO;
[base::mac::ObjCCastStrict<SettingsNavigationController>(
self.navigationController)
popViewControllerOrCloseSettingsAnimated:YES];
});
if (base::FeatureList::IsEnabled(kClearSyncedData)) {
UMA_HISTOGRAM_BOOLEAN("Signin.UserRequestedWipeDataOnSignout",
forceClearSyncData);
}
}
}
......
......@@ -95,7 +95,8 @@ void ChooseImportOrKeepDataSepareteDialog(id<GREYMatcher> choiceButtonMatcher) {
// Sign in to |fakeIdentity1|.
[SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity1];
[SigninEarlGreyUI signOutWithManagedAccount:NO];
[SigninEarlGreyUI
signOutWithSignOutConfirmation:SignOutConfirmationNonManagedUser];
// Sign in with |fakeIdentity2|.
[ChromeEarlGreyUI openSettingsMenu];
......@@ -170,7 +171,8 @@ void ChooseImportOrKeepDataSepareteDialog(id<GREYMatcher> choiceButtonMatcher) {
[SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity];
// Sign out.
[SigninEarlGreyUI signOutWithManagedAccount:NO];
[SigninEarlGreyUI
signOutWithSignOutConfirmation:SignOutConfirmationNonManagedUser];
}
// Tests that signing out of a managed account from the Settings works
......@@ -182,7 +184,8 @@ void ChooseImportOrKeepDataSepareteDialog(id<GREYMatcher> choiceButtonMatcher) {
[SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity isManagedAccount:YES];
// Sign out.
[SigninEarlGreyUI signOutWithManagedAccount:YES];
[SigninEarlGreyUI
signOutWithSignOutConfirmation:SignOutConfirmationManagedUser];
// Check that there is no signed in user.
[SigninEarlGreyUtils checkSignedOut];
......@@ -266,8 +269,8 @@ void ChooseImportOrKeepDataSepareteDialog(id<GREYMatcher> choiceButtonMatcher) {
[SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity2];
// Sign out.
[SigninEarlGreyUI signOutWithManagedAccount:NO];
[SigninEarlGreyUI
signOutWithSignOutConfirmation:SignOutConfirmationNonManagedUser];
// Sign in with |fakeIdentity1|.
[ChromeEarlGreyUI openSettingsMenu];
[[EarlGrey selectElementWithMatcher:SecondarySignInButton()]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment