summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortim@chromium.org <tim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-15 17:54:25 +0000
committertim@chromium.org <tim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-15 17:54:25 +0000
commita47eeb53aefd86ed2f4f9864bdd7a5da6cca668a (patch)
tree78392c06916e514258d76e103e4b189700eb5ab6
parent64268ce6b86e7f46dba3313c93e823e544528666 (diff)
downloadchromium_src-a47eeb53aefd86ed2f4f9864bdd7a5da6cca668a.zip
chromium_src-a47eeb53aefd86ed2f4f9864bdd7a5da6cca668a.tar.gz
chromium_src-a47eeb53aefd86ed2f4f9864bdd7a5da6cca668a.tar.bz2
Add support for the "clear pending" server / storage backend state.
BUG=46807 TEST=SyncerThreadWithSyncerTest, SyncSetupWizardTest, SyncerProtoUtilTest Review URL: http://codereview.chromium.org/2976011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52502 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd3
-rw-r--r--chrome/browser/sync/engine/authenticator.cc4
-rw-r--r--chrome/browser/sync/engine/syncer_proto_util.cc9
-rw-r--r--chrome/browser/sync/engine/syncer_proto_util_unittest.cc3
-rw-r--r--chrome/browser/sync/profile_sync_service.cc14
-rw-r--r--chrome/browser/sync/profile_sync_service.h5
-rw-r--r--chrome/browser/sync/protocol/sync.proto3
-rw-r--r--chrome/browser/sync/resources/choose_datatypes.html36
-rw-r--r--chrome/browser/sync/sync_setup_flow.cc11
-rw-r--r--chrome/browser/sync/sync_setup_flow.h6
-rw-r--r--chrome/browser/sync/sync_setup_wizard.cc37
-rw-r--r--chrome/browser/sync/sync_setup_wizard.h3
-rw-r--r--chrome/browser/sync/sync_setup_wizard_unittest.cc57
13 files changed, 155 insertions, 36 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index ea31152..6322e68 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6846,6 +6846,9 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_SYNC_SETUP_ERROR" desc="The message displayed when an unspecified but unrecoverable error occurs during sync setup.">
An error occurred while trying to set up sync.
</message>
+ <message name="IDS_SYNC_SETUP_ABORTED_BY_PENDING_CLEAR" desc="The error message displayed to the user when setup was aborted because the server reported that a pending clear private data operation is in progress">
+ The sync server is busy, please try again later.
+ </message>
<message name="IDS_SYNC_ACCOUNT_SYNCED_TO_USER_WITH_TIME" desc="The message that appears in the options dialog indicating that account is synced to a user with the given email address. The last sync also appears in the message.">
Synced to <ph name="USER_EMAIL_ADDRESS">$1<ex>foo@gmail.com</ex></ph>. Last synced: <ph name="LAST_SYNC_TIME">$2<ex>12 seconds ago</ex></ph>
</message>
diff --git a/chrome/browser/sync/engine/authenticator.cc b/chrome/browser/sync/engine/authenticator.cc
index 479be99..eec7af3 100644
--- a/chrome/browser/sync/engine/authenticator.cc
+++ b/chrome/browser/sync/engine/authenticator.cc
@@ -43,7 +43,7 @@ Authenticator::AuthenticationResult Authenticator::Authenticate(
return AuthenticateToken(auth_service.auth_token());
}
-COMPILE_ASSERT(sync_pb::ClientToServerResponse::ErrorType_MAX == 6,
+COMPILE_ASSERT(sync_pb::ClientToServerResponse::ErrorType_MAX == 7,
client_to_server_response_errors_changed);
Authenticator::AuthenticationResult Authenticator::HandleSuccessfulTokenRequest(
@@ -98,6 +98,8 @@ Authenticator::AuthenticationResult Authenticator::AuthenticateToken(
case sync_pb::ClientToServerResponse::THROTTLED:
// should never happen (only for stores).
case sync_pb::ClientToServerResponse::ACCESS_DENIED:
+ // should never happen (only sent on get updates / commit)
+ case sync_pb::ClientToServerResponse::CLEAR_PENDING:
default:
LOG(ERROR) << "Corrupt Server packet received by auth, error code " <<
response.error_code();
diff --git a/chrome/browser/sync/engine/syncer_proto_util.cc b/chrome/browser/sync/engine/syncer_proto_util.cc
index ec95bc5..17de218 100644
--- a/chrome/browser/sync/engine/syncer_proto_util.cc
+++ b/chrome/browser/sync/engine/syncer_proto_util.cc
@@ -83,8 +83,11 @@ bool SyncerProtoUtil::VerifyResponseBirthday(syncable::Directory* dir,
std::string local_birthday = dir->store_birthday();
- // TODO(tim): Bug 46807. Check for new response code denoting a clear store
- // operation is in progress.
+ if (response->error_code() == ClientToServerResponse::CLEAR_PENDING) {
+ // Birthday verification failures result in stopping sync and deleting
+ // local sync data.
+ return false;
+ }
if (local_birthday.empty()) {
if (!response->has_store_birthday()) {
@@ -193,8 +196,6 @@ bool SyncerProtoUtil::PostClientToServerMessage(
}
if (!VerifyResponseBirthday(dir, response)) {
- // TODO(ncarter): Add a unit test for the case where the syncer becomes
- // stuck due to a bad birthday.
session->status_controller()->set_syncer_stuck(true);
session->delegate()->OnShouldStopSyncingPermanently();
return false;
diff --git a/chrome/browser/sync/engine/syncer_proto_util_unittest.cc b/chrome/browser/sync/engine/syncer_proto_util_unittest.cc
index b33cb48..e6eb68b 100644
--- a/chrome/browser/sync/engine/syncer_proto_util_unittest.cc
+++ b/chrome/browser/sync/engine/syncer_proto_util_unittest.cc
@@ -160,6 +160,9 @@ TEST_F(SyncerProtoUtilTest, VerifyResponseBirthday) {
// Doesn't match
response.set_store_birthday("meat");
EXPECT_FALSE(SyncerProtoUtil::VerifyResponseBirthday(lookup, &response));
+
+ response.set_error_code(ClientToServerResponse::CLEAR_PENDING);
+ EXPECT_FALSE(SyncerProtoUtil::VerifyResponseBirthday(lookup, &response));
}
TEST_F(SyncerProtoUtilTest, AddRequestBirthday) {
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index 6ef5d2c..168a379 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -115,7 +115,8 @@ ProfileSyncService::ProfileSyncService()
ALLOW_THIS_IN_INITIALIZER_LIST(wizard_(this)),
unrecoverable_error_detected_(false),
notification_method_(browser_sync::kDefaultNotificationMethod),
- ALLOW_THIS_IN_INITIALIZER_LIST(scoped_runnable_method_factory_(this)) {
+ ALLOW_THIS_IN_INITIALIZER_LIST(scoped_runnable_method_factory_(this)),
+ expect_sync_configuration_aborted_(false) {
}
ProfileSyncService::~ProfileSyncService() {
@@ -477,8 +478,10 @@ void ProfileSyncService::OnAuthError() {
}
void ProfileSyncService::OnStopSyncingPermanently() {
- if (SetupInProgress())
- wizard_.Step(SyncSetupWizard::FATAL_ERROR);
+ if (SetupInProgress()) {
+ wizard_.Step(SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR);
+ expect_sync_configuration_aborted_ = true;
+ }
DisableForUser();
}
@@ -719,6 +722,11 @@ void ProfileSyncService::Observe(NotificationType type,
case NotificationType::SYNC_CONFIGURE_DONE: {
DataTypeManager::ConfigureResult result =
*(Details<DataTypeManager::ConfigureResult>(details).ptr());
+ if (result == DataTypeManager::ABORTED &&
+ expect_sync_configuration_aborted_) {
+ expect_sync_configuration_aborted_ = false;
+ return;
+ }
if (result != DataTypeManager::OK) {
OnUnrecoverableError(FROM_HERE, "Sync Configuration failed.");
return;
diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h
index e88d852..bc55429 100644
--- a/chrome/browser/sync/profile_sync_service.h
+++ b/chrome/browser/sync/profile_sync_service.h
@@ -437,6 +437,11 @@ class ProfileSyncService : public browser_sync::SyncFrontend,
// management.
BooleanPrefMember pref_sync_managed_;
+ // This allows us to gracefully handle an ABORTED return code from the
+ // DataTypeManager in the event that the server informed us to cease and
+ // desist syncing immediately.
+ bool expect_sync_configuration_aborted_;
+
DISALLOW_COPY_AND_ASSIGN(ProfileSyncService);
};
diff --git a/chrome/browser/sync/protocol/sync.proto b/chrome/browser/sync/protocol/sync.proto
index 9b3b4d31..bbafdb9 100644
--- a/chrome/browser/sync/protocol/sync.proto
+++ b/chrome/browser/sync/protocol/sync.proto
@@ -419,6 +419,9 @@ message ClientToServerResponse {
USER_NOT_ACTIVATED = 5; // User doesn't have the Chrome bit set on that
// Google Account.
AUTH_INVALID = 6; // Auth token or cookie is otherwise invalid.
+ CLEAR_PENDING = 7; // A clear of the user data is pending (e.g.
+ // initiated by privacy request). Client should
+ // come back later.
}
optional ErrorType error_code = 4 [default = SUCCESS];
optional string error_message = 5;
diff --git a/chrome/browser/sync/resources/choose_datatypes.html b/chrome/browser/sync/resources/choose_datatypes.html
index bc01f5e..532822f 100644
--- a/chrome/browser/sync/resources/choose_datatypes.html
+++ b/chrome/browser/sync/resources/choose_datatypes.html
@@ -58,14 +58,22 @@ input[type='submit'] {
min-width: 87px;
min-height: 26px;
}
+.errormsg {
+ color: red;
+}
</style>
<script>
// Called once, when this html/js is loaded.
function initializeChooseDataTypesDialog() {
setInterval(advanceThrobber, 30);
- var args = JSON.parse(chrome.dialogArguments);
- setChooseDataTypesCheckboxes(args);
+ var args = JSON.parse(chrome.dialogArguments);
+ setChooseDataTypesCheckboxes(args);
+ }
+
+ function setCheckboxesAndErrors(args) {
+ setChooseDataTypesCheckboxes(args);
+ setErrorState(args);
}
// Can be called multiple times.
@@ -124,7 +132,16 @@ input[type='submit'] {
} else {
document.getElementById("typedUrlsCheckbox").style.display = "none";
document.getElementById("typedUrlsCheckboxLabel").style.display = "none";
- }
+ }
+ }
+
+ function setErrorState(args) {
+ if (!args.was_aborted)
+ return;
+ document.getElementById("aborted_text").style.display = "inline";
+ document.getElementById("okButton").disabled = true;
+ document.getElementById("keepEverythingSyncedRadio").disabled = true;
+ document.getElementById("chooseDataTypesRadio").disabled = true;
}
function setDataTypeCheckboxesEnabled(enabled) {
@@ -144,8 +161,8 @@ input[type='submit'] {
var throbberContainer = document.getElementById('throbber_container');
throbberContainer.style.visibility = isThrobbing ? "visible" : "hidden";
- var okButton = document.getElementById('okButton');
- okButton.disabled = isThrobbing;
+ var okButton = document.getElementById('okButton');
+ okButton.disabled = isThrobbing || templateData["was_aborted"];
okButton.value = isThrobbing ? templateData['settingup'] :
templateData['ok'];
}
@@ -168,10 +185,12 @@ input[type='submit'] {
return atLeastOneEnabled && !atLeastOneChecked;
}
- function sendChooseDataTypesAndClose() {
+ function sendChooseDataTypesAndClose() {
+ // The user is trying again, so we don't need the aborted text.
+ document.getElementById("aborted_text").style.display = "none";
if (noDataTypesChecked()) {
- document.getElementById("error_text").style.visibility = "visible";
+ document.getElementById("error_text").style.display = "inline";
return;
}
@@ -262,7 +281,8 @@ input[type='submit'] {
</tr>
<tr>
<td>
- <span id="error_text" i18n-content="synczerodatatypeserror" style="visibility:hidden"></span>
+ <span id="error_text" i18n-content="synczerodatatypeserror" style="display:none"></span>
+ <span id="aborted_text" class="errormsg" i18n-content="setupabortederror" style="display:none"></span>
</td>
</tr>
<tr valign="bottom">
diff --git a/chrome/browser/sync/sync_setup_flow.cc b/chrome/browser/sync/sync_setup_flow.cc
index 769d4b0..b1063bb 100644
--- a/chrome/browser/sync/sync_setup_flow.cc
+++ b/chrome/browser/sync/sync_setup_flow.cc
@@ -191,7 +191,7 @@ void FlowHandler::ShowChooseDataTypes(const DictionaryValue& args) {
std::string json;
base::JSONWriter::Write(&args, false, &json);
- std::wstring javascript = std::wstring(L"setChooseDataTypesCheckboxes") +
+ std::wstring javascript = std::wstring(L"setCheckboxesAndErrors") +
L"(" + UTF8ToWide(json) + L");";
ExecuteJavascriptInIFrame(kChooseDataTypesIFrameXPath, javascript);
}
@@ -385,6 +385,8 @@ bool SyncSetupFlow::ShouldAdvance(SyncSetupWizard::State state) {
return current_state_ == SyncSetupWizard::GAIA_LOGIN;
case SyncSetupWizard::CHOOSE_DATA_TYPES:
return current_state_ == SyncSetupWizard::GAIA_SUCCESS;
+ case SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR:
+ return current_state_ == SyncSetupWizard::CHOOSE_DATA_TYPES;
case SyncSetupWizard::FATAL_ERROR:
return true; // You can always hit the panic button.
case SyncSetupWizard::DONE_FIRST_TIME:
@@ -420,6 +422,13 @@ void SyncSetupFlow::Advance(SyncSetupWizard::State advance_state) {
flow_handler_->ShowChooseDataTypes(args);
break;
}
+ case SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR: {
+ DictionaryValue args;
+ SyncSetupFlow::GetArgsForChooseDataTypes(service_, &args);
+ args.SetBoolean(L"was_aborted", true);
+ flow_handler_->ShowChooseDataTypes(args);
+ break;
+ }
case SyncSetupWizard::FATAL_ERROR: {
// This shows the user the "Could not connect to server" error.
// TODO(sync): Update this error messaging.
diff --git a/chrome/browser/sync/sync_setup_flow.h b/chrome/browser/sync/sync_setup_flow.h
index a80fb98..f67434c 100644
--- a/chrome/browser/sync/sync_setup_flow.h
+++ b/chrome/browser/sync/sync_setup_flow.h
@@ -106,7 +106,11 @@ class SyncSetupFlow : public HtmlDialogUIDelegate {
FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, DialogCancelled);
FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, InvalidTransitions);
FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, FullSuccessfulRunSetsPref);
- FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, DiscreteRun);
+ FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, AbortedByPendingClear);
+ FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, DiscreteRunGaiaLogin);
+ FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, DiscreteRunChooseDataTypes);
+ FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest,
+ DiscreteRunChooseDataTypesAbortedByPendingClear);
// Use static Run method to get an instance.
SyncSetupFlow(SyncSetupWizard::State start_state,
diff --git a/chrome/browser/sync/sync_setup_wizard.cc b/chrome/browser/sync/sync_setup_wizard.cc
index 0329a4a..c879887 100644
--- a/chrome/browser/sync/sync_setup_wizard.cc
+++ b/chrome/browser/sync/sync_setup_wizard.cc
@@ -120,36 +120,38 @@ void SyncResourcesSource::StartDataRequest(const std::string& path_raw,
} else if (path_raw == kSyncChooseDataTypesPath) {
DictionaryValue localized_strings;
localized_strings.SetString(L"choosedatatypesheader",
- l10n_util::GetString(IDS_SYNC_CHOOSE_DATATYPES_HEADER));
+ l10n_util::GetString(IDS_SYNC_CHOOSE_DATATYPES_HEADER));
localized_strings.SetString(L"choosedatatypesinstructions",
- l10n_util::GetStringF(IDS_SYNC_CHOOSE_DATATYPES_INSTRUCTIONS,
- l10n_util::GetString(IDS_PRODUCT_NAME)));
+ l10n_util::GetStringF(IDS_SYNC_CHOOSE_DATATYPES_INSTRUCTIONS,
+ l10n_util::GetString(IDS_PRODUCT_NAME)));
localized_strings.SetString(L"keepeverythingsynced",
- l10n_util::GetString(IDS_SYNC_EVERYTHING));
+ l10n_util::GetString(IDS_SYNC_EVERYTHING));
localized_strings.SetString(L"choosedatatypes",
- l10n_util::GetString(IDS_SYNC_CHOOSE_DATATYPES));
+ l10n_util::GetString(IDS_SYNC_CHOOSE_DATATYPES));
localized_strings.SetString(L"bookmarks",
- l10n_util::GetString(IDS_SYNC_DATATYPE_BOOKMARKS));
+ l10n_util::GetString(IDS_SYNC_DATATYPE_BOOKMARKS));
localized_strings.SetString(L"preferences",
- l10n_util::GetString(IDS_SYNC_DATATYPE_PREFERENCES));
+ l10n_util::GetString(IDS_SYNC_DATATYPE_PREFERENCES));
localized_strings.SetString(L"autofill",
- l10n_util::GetString(IDS_SYNC_DATATYPE_AUTOFILL));
+ l10n_util::GetString(IDS_SYNC_DATATYPE_AUTOFILL));
localized_strings.SetString(L"themes",
- l10n_util::GetString(IDS_SYNC_DATATYPE_THEMES));
+ l10n_util::GetString(IDS_SYNC_DATATYPE_THEMES));
localized_strings.SetString(L"passwords",
- l10n_util::GetString(IDS_SYNC_DATATYPE_PASSWORDS));
+ l10n_util::GetString(IDS_SYNC_DATATYPE_PASSWORDS));
localized_strings.SetString(L"extensions",
- l10n_util::GetString(IDS_SYNC_DATATYPE_EXTENSIONS));
+ l10n_util::GetString(IDS_SYNC_DATATYPE_EXTENSIONS));
localized_strings.SetString(L"typedurls",
- l10n_util::GetString(IDS_SYNC_DATATYPE_TYPED_URLS));
+ l10n_util::GetString(IDS_SYNC_DATATYPE_TYPED_URLS));
localized_strings.SetString(L"synczerodatatypeserror",
- l10n_util::GetString(IDS_SYNC_ZERO_DATA_TYPES_ERROR));
+ l10n_util::GetString(IDS_SYNC_ZERO_DATA_TYPES_ERROR));
+ localized_strings.SetString(L"setupabortederror",
+ l10n_util::GetString(IDS_SYNC_SETUP_ABORTED_BY_PENDING_CLEAR));
localized_strings.SetString(L"ok",
- l10n_util::GetString(IDS_OK));
+ l10n_util::GetString(IDS_OK));
localized_strings.SetString(L"cancel",
- l10n_util::GetString(IDS_CANCEL));
+ l10n_util::GetString(IDS_CANCEL));
localized_strings.SetString(L"settingup",
- l10n_util::GetString(IDS_SYNC_LOGIN_SETTING_UP));
+ l10n_util::GetString(IDS_SYNC_LOGIN_SETTING_UP));
static const base::StringPiece html(ResourceBundle::GetSharedInstance()
.GetRawDataResource(IDR_SYNC_CHOOSE_DATATYPES_HTML));
SetFontAndTextDirection(&localized_strings);
@@ -235,7 +237,8 @@ bool SyncSetupWizard::IsTerminalState(State advance_state) {
return advance_state == GAIA_SUCCESS ||
advance_state == DONE ||
advance_state == DONE_FIRST_TIME ||
- advance_state == FATAL_ERROR;
+ advance_state == FATAL_ERROR ||
+ advance_state == SETUP_ABORTED_BY_PENDING_CLEAR;
}
bool SyncSetupWizard::IsVisible() const {
diff --git a/chrome/browser/sync/sync_setup_wizard.h b/chrome/browser/sync/sync_setup_wizard.h
index acd4650..55195bf 100644
--- a/chrome/browser/sync/sync_setup_wizard.h
+++ b/chrome/browser/sync/sync_setup_wizard.h
@@ -33,6 +33,9 @@ class SyncSetupWizard {
// The panic switch. Something went terribly wrong during setup and we
// can't recover.
FATAL_ERROR,
+ // The client can't set up sync at the moment due to a concurrent operation
+ // to clear cloud data being in progress on the server.
+ SETUP_ABORTED_BY_PENDING_CLEAR,
// A final state for when setup completes and it is possible it is the
// user's first time (globally speaking) as the cloud doesn't have any
// bookmarks. We show additional info in this case to explain setting up
diff --git a/chrome/browser/sync/sync_setup_wizard_unittest.cc b/chrome/browser/sync/sync_setup_wizard_unittest.cc
index 0644501..02dd1df 100644
--- a/chrome/browser/sync/sync_setup_wizard_unittest.cc
+++ b/chrome/browser/sync/sync_setup_wizard_unittest.cc
@@ -371,7 +371,13 @@ TEST_F(SyncSetupWizardTest, InvalidTransitions) {
wizard_->Step(SyncSetupWizard::DONE_FIRST_TIME);
EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, test_window_->flow()->current_state_);
+ wizard_->Step(SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR);
+ EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN,
+ test_window_->flow()->current_state_);
+
wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
+ EXPECT_EQ(SyncSetupWizard::CHOOSE_DATA_TYPES,
+ test_window_->flow()->current_state_);
wizard_->Step(SyncSetupWizard::FATAL_ERROR);
EXPECT_EQ(SyncSetupWizard::FATAL_ERROR, test_window_->flow()->current_state_);
@@ -399,7 +405,56 @@ TEST_F(SyncSetupWizardTest, FirstFullSuccessfulRunSetsPref) {
prefs::kSyncHasSetupCompleted));
}
-TEST_F(SyncSetupWizardTest, DiscreteRun) {
+TEST_F(SyncSetupWizardTest, AbortedByPendingClear) {
+ SKIP_TEST_ON_MACOSX();
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
+ wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
+ wizard_->Step(SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR);
+ EXPECT_EQ(SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR,
+ test_window_->flow()->current_state_);
+ test_window_->CloseDialog();
+ EXPECT_FALSE(wizard_->IsVisible());
+}
+
+TEST_F(SyncSetupWizardTest, DiscreteRunChooseDataTypes) {
+ SKIP_TEST_ON_MACOSX();
+ // For a discrete run, we need to have ran through setup once.
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
+ wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
+ wizard_->Step(SyncSetupWizard::DONE);
+ test_window_->CloseDialog();
+ EXPECT_TRUE(test_window_->TestAndResetWasShowHTMLDialogCalled());
+
+ wizard_->Step(SyncSetupWizard::CHOOSE_DATA_TYPES);
+ EXPECT_TRUE(test_window_->TestAndResetWasShowHTMLDialogCalled());
+ EXPECT_EQ(SyncSetupWizard::DONE, test_window_->flow()->end_state_);
+
+ wizard_->Step(SyncSetupWizard::DONE);
+ test_window_->CloseDialog();
+ EXPECT_FALSE(wizard_->IsVisible());
+}
+
+TEST_F(SyncSetupWizardTest, DiscreteRunChooseDataTypesAbortedByPendingClear) {
+ SKIP_TEST_ON_MACOSX();
+ // For a discrete run, we need to have ran through setup once.
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
+ wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
+ wizard_->Step(SyncSetupWizard::DONE);
+ test_window_->CloseDialog();
+ EXPECT_TRUE(test_window_->TestAndResetWasShowHTMLDialogCalled());
+
+ wizard_->Step(SyncSetupWizard::CHOOSE_DATA_TYPES);
+ EXPECT_TRUE(test_window_->TestAndResetWasShowHTMLDialogCalled());
+ EXPECT_EQ(SyncSetupWizard::DONE, test_window_->flow()->end_state_);
+ wizard_->Step(SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR);
+ EXPECT_EQ(SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR,
+ test_window_->flow()->current_state_);
+
+ test_window_->CloseDialog();
+ EXPECT_FALSE(wizard_->IsVisible());
+}
+
+TEST_F(SyncSetupWizardTest, DiscreteRunGaiaLogin) {
SKIP_TEST_ON_MACOSX();
DictionaryValue dialog_args;
// For a discrete run, we need to have ran through setup once.