普通文本  |  537行  |  19.78 KB

// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// TODO(jhawkins): Rewrite these tests to handle the new inlined sync UI.

#include "chrome/browser/sync/sync_setup_wizard.h"

#include "base/json/json_writer.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util-inl.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/sync/profile_sync_factory_mock.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/sync_setup_flow.h"
#include "chrome/browser/sync/sync_setup_flow_handler.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/common/net/gaia/google_service_auth_error.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/browser_with_test_window_test.h"
#include "chrome/test/test_browser_window.h"
#include "chrome/test/testing_profile.h"
#include "testing/gtest/include/gtest/gtest.h"

static const char kTestUser[] = "chrome.p13n.test@gmail.com";
static const char kTestPassword[] = "passwd";
static const char kTestCaptcha[] = "pizzamyheart";
static const char kTestCaptchaUrl[] = "http://pizzamyheart/";

typedef GoogleServiceAuthError AuthError;

// A PSS subtype to inject.
class ProfileSyncServiceForWizardTest : public ProfileSyncService {
 public:
  ProfileSyncServiceForWizardTest(ProfileSyncFactory* factory, Profile* profile)
      : ProfileSyncService(factory, profile, ""),
        user_cancelled_dialog_(false) {
    RegisterPreferences();
    ResetTestStats();
  }

  virtual ~ProfileSyncServiceForWizardTest() { }

  virtual void OnUserSubmittedAuth(const std::string& username,
                                   const std::string& password,
                                   const std::string& captcha,
                                   const std::string& access_code) {
    username_ = username;
    password_ = password;
    captcha_ = captcha;
  }

  virtual void OnUserChoseDatatypes(bool sync_everything,
      const syncable::ModelTypeSet& chosen_types) {
    user_chose_data_types_ = true;
    chosen_data_types_ = chosen_types;
  }

  virtual void OnUserCancelledDialog() {
    user_cancelled_dialog_ = true;
  }

  virtual void SetPassphrase(const std::string& passphrase,
                             bool is_explicit,
                             bool is_creation) {
    passphrase_ = passphrase;
  }

  virtual string16 GetAuthenticatedUsername() const {
    return UTF8ToUTF16(username_);
  }

  void set_auth_state(const std::string& last_email,
                      const AuthError& error) {
    last_attempted_user_email_ = last_email;
    last_auth_error_ = error;
  }

  void set_passphrase_required(bool required) {
    observed_passphrase_required_ = required;
  }

  void ResetTestStats() {
    username_.clear();
    password_.clear();
    captcha_.clear();
    user_cancelled_dialog_ = false;
    user_chose_data_types_ = false;
    keep_everything_synced_ = false;
    chosen_data_types_.clear();
  }

  std::string username_;
  std::string password_;
  std::string captcha_;
  bool user_cancelled_dialog_;
  bool user_chose_data_types_;
  bool keep_everything_synced_;
  syncable::ModelTypeSet chosen_data_types_;

  std::string passphrase_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceForWizardTest);
};

class TestingProfileWithSyncService : public TestingProfile {
 public:
  TestingProfileWithSyncService() {
    sync_service_.reset(new ProfileSyncServiceForWizardTest(&factory_, this));
  }

  virtual ProfileSyncService* GetProfileSyncService() {
    return sync_service_.get();
  }
 private:
  ProfileSyncFactoryMock factory_;
  scoped_ptr<ProfileSyncService> sync_service_;
};

class TestBrowserWindowForWizardTest : public TestBrowserWindow {
 public:
  explicit TestBrowserWindowForWizardTest(Browser* browser)
      : TestBrowserWindow(browser), flow_(NULL),
        was_show_html_dialog_called_(false) {
  }

  virtual ~TestBrowserWindowForWizardTest() {
    if (flow_.get()) {
      // The handler contract is that they are valid for the lifetime of the
      // sync login overlay, but are cleaned up after the dialog is closed
      // and/or deleted.
      flow_.reset();
    }
  }

  bool TestAndResetWasShowHTMLDialogCalled() {
    bool ret = was_show_html_dialog_called_;
    was_show_html_dialog_called_ = false;
    return ret;
  }

  // Simulates the user (or browser view hierarchy) closing the html dialog.
  // Handles cleaning up the delegate and associated handlers.
  void CloseDialog() {
    if (flow_.get()) {
      // The flow deletes itself here.  Don't use reset().
      flow_.release()->OnDialogClosed("");
    }
  }

  SyncSetupFlow* flow() { return flow_.get(); }

 private:
  // In real life, this is owned by the view that is opened by the browser.  We
  // mock all that out, so we need to take ownership so the flow doesn't leak.
  scoped_ptr<SyncSetupFlow> flow_;

  bool was_show_html_dialog_called_;
};

class SyncSetupWizardTest : public BrowserWithTestWindowTest {
 public:
  SyncSetupWizardTest()
      : test_window_(NULL),
        wizard_(NULL) { }
  virtual ~SyncSetupWizardTest() { }
  virtual void SetUp() {
    set_profile(new TestingProfileWithSyncService());
    profile()->CreateBookmarkModel(false);
    // Wait for the bookmarks model to load.
    profile()->BlockUntilBookmarkModelLoaded();
    set_browser(new Browser(Browser::TYPE_NORMAL, profile()));
    test_window_ = new TestBrowserWindowForWizardTest(browser());
    set_window(test_window_);
    browser()->set_window(window());
    BrowserList::SetLastActive(browser());
    service_ = static_cast<ProfileSyncServiceForWizardTest*>(
        profile()->GetProfileSyncService());
    wizard_.reset(new SyncSetupWizard(service_));
  }

  virtual void TearDown() {
    test_window_ = NULL;
    service_ = NULL;
    wizard_.reset();
  }

  TestBrowserWindowForWizardTest* test_window_;
  scoped_ptr<SyncSetupWizard> wizard_;
  ProfileSyncServiceForWizardTest* service_;
};

// See http://code.google.com/p/chromium/issues/detail?id=40715 for
// why we skip the below tests on OS X.  We don't use DISABLED_ as we
// would have to change the corresponding FRIEND_TEST() declarations.

#if defined(OS_MACOSX)
#define SKIP_TEST_ON_MACOSX() \
  do { LOG(WARNING) << "Test skipped on OS X"; return; } while (0)
#else
#define SKIP_TEST_ON_MACOSX() do {} while (0)
#endif

TEST_F(SyncSetupWizardTest, DISABLED_InitialStepLogin) {
  SKIP_TEST_ON_MACOSX();
  DictionaryValue dialog_args;
  SyncSetupFlow::GetArgsForGaiaLogin(service_, &dialog_args);
  std::string json_start_args;
  base::JSONWriter::Write(&dialog_args, false, &json_start_args);
  ListValue credentials;
  std::string auth = "{\"user\":\"";
  auth += std::string(kTestUser) + "\",\"pass\":\"";
  auth += std::string(kTestPassword) + "\",\"captcha\":\"";
  auth += std::string(kTestCaptcha) + "\",\"access_code\":\"";
  auth += std::string() + "\"}";
  credentials.Append(new StringValue(auth));

  EXPECT_FALSE(wizard_->IsVisible());
  EXPECT_FALSE(test_window_->flow());
  wizard_->Step(SyncSetupWizard::GAIA_LOGIN);

  EXPECT_TRUE(wizard_->IsVisible());
  EXPECT_TRUE(test_window_->TestAndResetWasShowHTMLDialogCalled());
  EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, test_window_->flow()->current_state_);
  EXPECT_EQ(SyncSetupWizard::DONE, test_window_->flow()->end_state_);
  EXPECT_EQ(json_start_args, test_window_->flow()->dialog_start_args_);

#if 0
  // Simulate the user submitting credentials.
  test_window_->flow()->flow_handler_->HandleSubmitAuth(&credentials);
  EXPECT_TRUE(wizard_->IsVisible());
  EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, test_window_->flow()->current_state_);
  EXPECT_EQ(kTestUser, service_->username_);
  EXPECT_EQ(kTestPassword, service_->password_);
  EXPECT_EQ(kTestCaptcha, service_->captcha_);
  EXPECT_FALSE(service_->user_cancelled_dialog_);
  service_->ResetTestStats();
#endif

  // Simulate failed credentials.
  AuthError invalid_gaia(AuthError::INVALID_GAIA_CREDENTIALS);
  service_->set_auth_state(kTestUser, invalid_gaia);
  wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
  EXPECT_TRUE(wizard_->IsVisible());
  EXPECT_FALSE(test_window_->TestAndResetWasShowHTMLDialogCalled());
  EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, test_window_->flow()->current_state_);
  dialog_args.Clear();
  SyncSetupFlow::GetArgsForGaiaLogin(service_, &dialog_args);
  EXPECT_EQ(5U, dialog_args.size());
  std::string iframe_to_show;
  dialog_args.GetString("iframeToShow", &iframe_to_show);
  EXPECT_EQ("login", iframe_to_show);
  std::string actual_user;
  dialog_args.GetString("user", &actual_user);
  EXPECT_EQ(kTestUser, actual_user);
  int error = -1;
  dialog_args.GetInteger("error", &error);
  EXPECT_EQ(static_cast<int>(AuthError::INVALID_GAIA_CREDENTIALS), error);
  service_->set_auth_state(kTestUser, AuthError::None());

  // Simulate captcha.
  AuthError captcha_error(AuthError::FromCaptchaChallenge(
      std::string(), GURL(kTestCaptchaUrl), GURL()));
  service_->set_auth_state(kTestUser, captcha_error);
  wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
  SyncSetupFlow::GetArgsForGaiaLogin(service_, &dialog_args);
  EXPECT_EQ(5U, dialog_args.size());
  dialog_args.GetString("iframeToShow", &iframe_to_show);
  EXPECT_EQ("login", iframe_to_show);
  std::string captcha_url;
  dialog_args.GetString("captchaUrl", &captcha_url);
  EXPECT_EQ(kTestCaptchaUrl, GURL(captcha_url).spec());
  error = -1;
  dialog_args.GetInteger("error", &error);
  EXPECT_EQ(static_cast<int>(AuthError::CAPTCHA_REQUIRED), error);
  service_->set_auth_state(kTestUser, AuthError::None());

  // Simulate success.
  wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
  EXPECT_TRUE(wizard_->IsVisible());
  EXPECT_FALSE(test_window_->TestAndResetWasShowHTMLDialogCalled());
  // In a non-discrete run, GAIA_SUCCESS immediately transitions you to
  // SYNC_EVERYTHING.
  EXPECT_EQ(SyncSetupWizard::SYNC_EVERYTHING,
            test_window_->flow()->current_state_);

  // That's all we're testing here, just move on to DONE.  We'll test the
  // "choose data types" scenarios elsewhere.
  wizard_->Step(SyncSetupWizard::SETTING_UP);  // No merge and sync.
  wizard_->Step(SyncSetupWizard::DONE);  // No merge and sync.
  EXPECT_TRUE(wizard_->IsVisible());
  EXPECT_FALSE(test_window_->TestAndResetWasShowHTMLDialogCalled());
  EXPECT_EQ(SyncSetupWizard::DONE, test_window_->flow()->current_state_);
}

TEST_F(SyncSetupWizardTest, DISABLED_ChooseDataTypesSetsPrefs) {
  SKIP_TEST_ON_MACOSX();
  wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
  wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
  wizard_->Step(SyncSetupWizard::CONFIGURE);

  ListValue data_type_choices_value;
  std::string data_type_choices = "{\"keepEverythingSynced\":false,";
  data_type_choices += "\"syncBookmarks\":true,\"syncPreferences\":true,";
  data_type_choices += "\"syncThemes\":false,\"syncPasswords\":false,";
  data_type_choices += "\"syncAutofill\":false,\"syncExtensions\":false,";
  data_type_choices += "\"syncTypedUrls\":true,\"syncApps\":true,";
  data_type_choices += "\"syncSessions\":false,\"usePassphrase\":false}";
  data_type_choices_value.Append(new StringValue(data_type_choices));

#if 0
  // Simulate the user choosing data types; bookmarks, prefs, typed
  // URLS, and apps are on, the rest are off.
  test_window_->flow()->flow_handler_->HandleConfigure(
      &data_type_choices_value);
  EXPECT_TRUE(wizard_->IsVisible());
  EXPECT_TRUE(test_window_->TestAndResetWasShowHTMLDialogCalled());
  EXPECT_FALSE(service_->keep_everything_synced_);
  EXPECT_EQ(service_->chosen_data_types_.count(syncable::BOOKMARKS), 1U);
  EXPECT_EQ(service_->chosen_data_types_.count(syncable::PREFERENCES), 1U);
  EXPECT_EQ(service_->chosen_data_types_.count(syncable::THEMES), 0U);
  EXPECT_EQ(service_->chosen_data_types_.count(syncable::PASSWORDS), 0U);
  EXPECT_EQ(service_->chosen_data_types_.count(syncable::AUTOFILL), 0U);
  EXPECT_EQ(service_->chosen_data_types_.count(syncable::EXTENSIONS), 0U);
  EXPECT_EQ(service_->chosen_data_types_.count(syncable::TYPED_URLS), 1U);
  EXPECT_EQ(service_->chosen_data_types_.count(syncable::APPS), 1U);
#endif
  test_window_->CloseDialog();
}

TEST_F(SyncSetupWizardTest, DISABLED_EnterPassphraseRequired) {
  SKIP_TEST_ON_MACOSX();
  wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
  wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
  wizard_->Step(SyncSetupWizard::CONFIGURE);
  wizard_->Step(SyncSetupWizard::SETTING_UP);
  service_->set_passphrase_required(true);
  wizard_->Step(SyncSetupWizard::ENTER_PASSPHRASE);
  EXPECT_EQ(SyncSetupWizard::ENTER_PASSPHRASE,
            test_window_->flow()->current_state_);
#if 0
  ListValue value;
  value.Append(new StringValue("{\"passphrase\":\"myPassphrase\","
                                "\"mode\":\"gaia\"}"));
  test_window_->flow()->flow_handler_->HandlePassphraseEntry(&value);
  EXPECT_EQ("myPassphrase", service_->passphrase_);
#endif
}

TEST_F(SyncSetupWizardTest, DISABLED_PassphraseMigration) {
  SKIP_TEST_ON_MACOSX();
  wizard_->Step(SyncSetupWizard::PASSPHRASE_MIGRATION);
#if 0
  ListValue value;
  value.Append(new StringValue("{\"option\":\"explicit\","
                               "\"passphrase\":\"myPassphrase\"}"));
  test_window_->flow()->flow_handler_->HandleFirstPassphrase(&value);
  EXPECT_EQ("myPassphrase", service_->passphrase_);

  ListValue value2;
  value2.Append(new StringValue("{\"option\":\"nothanks\","
                                "\"passphrase\":\"myPassphrase\"}"));
  test_window_->flow()->flow_handler_->HandleFirstPassphrase(&value2);
  EXPECT_EQ(service_->chosen_data_types_.count(syncable::PASSWORDS), 0U);
#endif
}

TEST_F(SyncSetupWizardTest, DISABLED_DialogCancelled) {
  SKIP_TEST_ON_MACOSX();
  wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
  // Simulate the user closing the dialog.
  test_window_->CloseDialog();
  EXPECT_FALSE(wizard_->IsVisible());
  EXPECT_TRUE(service_->user_cancelled_dialog_);
  EXPECT_EQ(std::string(), service_->username_);
  EXPECT_EQ(std::string(), service_->password_);

  wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
  EXPECT_TRUE(wizard_->IsVisible());
  EXPECT_TRUE(test_window_->TestAndResetWasShowHTMLDialogCalled());
  wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
  EXPECT_FALSE(test_window_->TestAndResetWasShowHTMLDialogCalled());

  test_window_->CloseDialog();
  EXPECT_FALSE(wizard_->IsVisible());
  EXPECT_TRUE(service_->user_cancelled_dialog_);
  EXPECT_EQ(std::string(), service_->username_);
  EXPECT_EQ(std::string(), service_->password_);
}

TEST_F(SyncSetupWizardTest, DISABLED_InvalidTransitions) {
  SKIP_TEST_ON_MACOSX();
  wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
  EXPECT_FALSE(wizard_->IsVisible());
  EXPECT_FALSE(test_window_->TestAndResetWasShowHTMLDialogCalled());

  wizard_->Step(SyncSetupWizard::DONE);
  EXPECT_FALSE(wizard_->IsVisible());
  EXPECT_FALSE(test_window_->TestAndResetWasShowHTMLDialogCalled());

  wizard_->Step(SyncSetupWizard::DONE_FIRST_TIME);
  EXPECT_FALSE(wizard_->IsVisible());
  EXPECT_FALSE(test_window_->TestAndResetWasShowHTMLDialogCalled());

  wizard_->Step(SyncSetupWizard::GAIA_LOGIN);

  wizard_->Step(SyncSetupWizard::DONE);
  EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, test_window_->flow()->current_state_);
  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::SYNC_EVERYTHING,
            test_window_->flow()->current_state_);

  wizard_->Step(SyncSetupWizard::FATAL_ERROR);
  EXPECT_EQ(SyncSetupWizard::FATAL_ERROR, test_window_->flow()->current_state_);
}

TEST_F(SyncSetupWizardTest, DISABLED_FullSuccessfulRunSetsPref) {
  SKIP_TEST_ON_MACOSX();
  wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
  wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
  wizard_->Step(SyncSetupWizard::SETTING_UP);
  wizard_->Step(SyncSetupWizard::DONE);
  test_window_->CloseDialog();
  EXPECT_FALSE(wizard_->IsVisible());
  EXPECT_TRUE(service_->profile()->GetPrefs()->GetBoolean(
      prefs::kSyncHasSetupCompleted));
}

TEST_F(SyncSetupWizardTest, DISABLED_FirstFullSuccessfulRunSetsPref) {
  SKIP_TEST_ON_MACOSX();
  wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
  wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
  wizard_->Step(SyncSetupWizard::SETTING_UP);
  wizard_->Step(SyncSetupWizard::DONE_FIRST_TIME);
  test_window_->CloseDialog();
  EXPECT_FALSE(wizard_->IsVisible());
  EXPECT_TRUE(service_->profile()->GetPrefs()->GetBoolean(
      prefs::kSyncHasSetupCompleted));
}

TEST_F(SyncSetupWizardTest, DISABLED_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, DISABLED_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::CONFIGURE);
  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,
       DISABLED_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::CONFIGURE);
  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, DISABLED_DiscreteRunGaiaLogin) {
  SKIP_TEST_ON_MACOSX();
  DictionaryValue dialog_args;
  // 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::SETTING_UP);
  wizard_->Step(SyncSetupWizard::DONE);
  test_window_->CloseDialog();
  EXPECT_TRUE(test_window_->TestAndResetWasShowHTMLDialogCalled());

  wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
  EXPECT_EQ(SyncSetupWizard::GAIA_SUCCESS, test_window_->flow()->end_state_);

  AuthError invalid_gaia(AuthError::INVALID_GAIA_CREDENTIALS);
  service_->set_auth_state(kTestUser, invalid_gaia);
  wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
  EXPECT_TRUE(wizard_->IsVisible());
  SyncSetupFlow::GetArgsForGaiaLogin(service_, &dialog_args);
  EXPECT_EQ(5U, dialog_args.size());
  std::string iframe_to_show;
  dialog_args.GetString("iframeToShow", &iframe_to_show);
  EXPECT_EQ("login", iframe_to_show);
  std::string actual_user;
  dialog_args.GetString("user", &actual_user);
  EXPECT_EQ(kTestUser, actual_user);
  int error = -1;
  dialog_args.GetInteger("error", &error);
  EXPECT_EQ(static_cast<int>(AuthError::INVALID_GAIA_CREDENTIALS), error);
  service_->set_auth_state(kTestUser, AuthError::None());

  wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
  EXPECT_TRUE(test_window_->TestAndResetWasShowHTMLDialogCalled());
}

#undef SKIP_TEST_ON_MACOSX