login_utils_browsertest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/login/login_utils.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/basictypes.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/command_line.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/message_loop.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/path_service.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/scoped_temp_dir.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/string_util.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/threading/sequenced_worker_pool.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/cros/cros_library.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/cros/mock_cryptohome_library.h"
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/login/authenticator.h"
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/login/login_status_consumer.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/io_thread.h"
23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/net/predictor.h"
24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/policy/browser_policy_connector.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/policy/cloud_policy_data_store.h"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/policy/policy_service.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/policy/proto/device_management_backend.pb.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/chrome_notification_types.h"
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/pref_names.h"
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/test/base/testing_browser_process.h"
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/test/base/testing_pref_service.h"
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chromeos/cryptohome/mock_async_method_caller.h"
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chromeos/dbus/mock_cryptohome_client.h"
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chromeos/dbus/mock_dbus_thread_manager.h"
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chromeos/dbus/mock_session_manager_client.h"
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/notification_service.h"
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/test/test_browser_thread.h"
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/test/test_utils.h"
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_consumer.h"
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "google_apis/gaia/gaia_urls.h"
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/test_url_fetcher_factory.h"
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h"
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request.h"
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_status.h"
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace chromeos {
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace em = enterprise_management;
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using ::testing::DoAll;
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using ::testing::Return;
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using ::testing::SaveArg;
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using ::testing::SetArgPointee;
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using ::testing::_;
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::BrowserThread;
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTrue[] = "true";
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kDomain[] = "domain.com";
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kUsername[] = "user@domain.com";
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kMode[] = "enterprise";
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kDeviceId[] = "100200300";
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kUsernameOtherDomain[] = "user@other.com";
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kAttributeOwned[] = "enterprise.owned";
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kAttributeOwner[] = "enterprise.user";
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kAttrEnterpriseDomain[] = "enterprise.domain";
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kAttrEnterpriseMode[] = "enterprise.mode";
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kAttrEnterpriseDeviceId[] = "enterprise.device_id";
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kOAuthTokenCookie[] = "oauth_token=1234";
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kOAuthGetAccessTokenData[] =
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "oauth_token=1234&oauth_token_secret=1234";
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kOAuthServiceTokenData[] =
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    "wrap_access_token=1234&wrap_access_token_expires_in=123456789";
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kDMServer[] = "http://server/device_management";
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const char kDMRegisterRequest[] =
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    "http://server/device_management?request=register";
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const char kDMPolicyRequest[] =
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "http://server/device_management?request=policy";
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kDMToken[] = "1234";
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Used to mark |flag|, indicating that RefreshPolicies() has executed its
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// callback.
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SetFlag(bool* flag) {
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *flag = true;
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ACTION_P(MockSessionManagerClientRetrievePolicyCallback, policy) {
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  arg0.Run(*policy);
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ACTION_P(MockSessionManagerClientStorePolicyCallback, success) {
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  arg1.Run(success);
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class LoginUtilsTest : public testing::Test,
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       public LoginUtils::Delegate,
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       public LoginStatusConsumer {
1086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) public:
1096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Initialization here is important. The UI thread gets the test's
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // message loop, as does the file thread (which never actually gets
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // started - so this is a way to fake multiple threads on a single
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // test thread).  The IO thread does not get the message loop set,
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // and is never started.  This is necessary so that we skip various
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // bits of initialization that get posted to the IO thread.  We do
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // however, at one point in the test, temporarily set the message
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // loop for the IO thread.
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  LoginUtilsTest()
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      : loop_(MessageLoop::TYPE_IO),
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        browser_process_(
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            static_cast<TestingBrowserProcess*>(g_browser_process)),
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        local_state_(browser_process_),
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        ui_thread_(content::BrowserThread::UI, &loop_),
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        db_thread_(content::BrowserThread::DB),
124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        file_thread_(content::BrowserThread::FILE, &loop_),
125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        io_thread_(content::BrowserThread::IO),
126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        mock_async_method_caller_(NULL),
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        connector_(NULL),
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        cryptohome_(NULL),
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        prepared_profile_(NULL) {}
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CommandLine* command_line = CommandLine::ForCurrentProcess();
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    command_line->AppendSwitchASCII(switches::kDeviceManagementUrl, kDMServer);
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    local_state_.Get()->RegisterStringPref(prefs::kApplicationLocale, "");
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // DBusThreadManager should be initialized before io_thread_state_, as
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // DBusThreadManager is used from chromeos::ProxyConfigServiceImpl,
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // which is part of io_thread_state_.
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DBusThreadManager::InitializeForTesting(&mock_dbus_thread_manager_);
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    input_method::InputMethodManager::InitializeForTesting(
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        &mock_input_method_manager_);
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Likewise, SessionManagerClient should also be initialized before
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // io_thread_state_.
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockSessionManagerClient* session_managed_client =
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        mock_dbus_thread_manager_.mock_session_manager_client();
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_CALL(*session_managed_client, RetrieveDevicePolicy(_))
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillRepeatedly(
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            MockSessionManagerClientRetrievePolicyCallback(&device_policy_));
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_CALL(*session_managed_client, RetrieveUserPolicy(_))
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillRepeatedly(
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            MockSessionManagerClientRetrievePolicyCallback(&user_policy_));
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_CALL(*session_managed_client, StoreUserPolicy(_, _))
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillRepeatedly(
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            DoAll(SaveArg<0>(&user_policy_),
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  MockSessionManagerClientStorePolicyCallback(true)));
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    mock_async_method_caller_ = new cryptohome::MockAsyncMethodCaller;
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    cryptohome::AsyncMethodCaller::InitializeForTesting(
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        mock_async_method_caller_);
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    io_thread_state_.reset(new IOThread(local_state_.Get(), NULL, NULL));
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    browser_process_->SetIOThread(io_thread_state_.get());
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CrosLibrary::TestApi* test_api = CrosLibrary::Get()->GetTestApi();
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(test_api);
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    cryptohome_ = new MockCryptohomeLibrary();
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_CALL(*cryptohome_, InstallAttributesIsReady())
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillRepeatedly(Return(true));
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_CALL(*cryptohome_, InstallAttributesIsInvalid())
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillRepeatedly(Return(false));
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_CALL(*cryptohome_, InstallAttributesIsFirstInstall())
179010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        .WillRepeatedly(Return(true));
180010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_CALL(*cryptohome_, TpmIsEnabled())
181010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        .WillRepeatedly(Return(false));
182010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_CALL(*cryptohome_, InstallAttributesSet(kAttributeOwned, kTrue))
183010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        .WillRepeatedly(Return(true));
184010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_CALL(*cryptohome_, InstallAttributesSet(kAttributeOwner,
185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                                   kUsername))
186010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        .WillRepeatedly(Return(true));
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_CALL(*cryptohome_, InstallAttributesSet(kAttrEnterpriseDomain,
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                   kDomain))
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        .WillRepeatedly(Return(true));
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_CALL(*cryptohome_, InstallAttributesSet(kAttrEnterpriseMode,
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                   kMode))
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        .WillRepeatedly(Return(true));
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_CALL(*cryptohome_, InstallAttributesSet(kAttrEnterpriseDeviceId,
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                   kDeviceId))
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        .WillRepeatedly(Return(true));
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_CALL(*cryptohome_, InstallAttributesFinalize())
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        .WillRepeatedly(Return(true));
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_CALL(*cryptohome_, InstallAttributesGet(kAttributeOwned, _))
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        .WillRepeatedly(DoAll(SetArgPointee<1>(kTrue),
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              Return(true)));
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_CALL(*cryptohome_, InstallAttributesGet(kAttributeOwner, _))
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillRepeatedly(DoAll(SetArgPointee<1>(kUsername),
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              Return(true)));
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_CALL(*cryptohome_, InstallAttributesGet(kAttrEnterpriseDomain, _))
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillRepeatedly(DoAll(SetArgPointee<1>(kDomain),
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              Return(true)));
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_CALL(*cryptohome_, InstallAttributesGet(kAttrEnterpriseMode, _))
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillRepeatedly(DoAll(SetArgPointee<1>(kMode),
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              Return(true)));
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_CALL(*cryptohome_, InstallAttributesGet(kAttrEnterpriseDeviceId, _))
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillRepeatedly(DoAll(SetArgPointee<1>(kDeviceId),
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              Return(true)));
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    test_api->SetCryptohomeLibrary(cryptohome_, true);
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_CALL(*mock_dbus_thread_manager_.mock_cryptohome_client(),
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                IsMounted(_));
217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    browser_process_->SetProfileManager(
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new ProfileManagerWithoutInit(scoped_temp_dir_.path()));
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    connector_ = browser_process_->browser_policy_connector();
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    connector_->Init();
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RunUntilIdle();
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    cryptohome::AsyncMethodCaller::Shutdown();
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    mock_async_method_caller_ = NULL;
2296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    RunUntilIdle();
2316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    {
2326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // chrome_browser_net::Predictor usually skips its shutdown routines on
2336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // unit_tests, but does the full thing when
2346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // g_browser_process->profile_manager() is valid during initialization.
2356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // Run a task on a temporary BrowserThread::IO that allows skipping
2366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // these routines.
2376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      //
2386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // It is important to not have a fake message loop on the IO
2396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // thread for the whole test, see comment on LoginUtilsTest
2406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // constructor for details.
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      io_thread_.DeprecatedSetMessageLoop(&loop_);
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      loop_.PostTask(FROM_HERE,
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     base::Bind(&LoginUtilsTest::TearDownOnIO,
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                base::Unretained(this)));
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      RunUntilIdle();
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      io_thread_.DeprecatedSetMessageLoop(NULL);
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // These trigger some tasks that have to run while BrowserThread::UI
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // exists. Delete all the profiles before deleting the connector.
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    browser_process_->SetProfileManager(NULL);
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    connector_ = NULL;
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    browser_process_->SetBrowserPolicyConnector(NULL);
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RunUntilIdle();
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void TearDownOnIO() {
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    std::vector<Profile*> profiles =
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        browser_process_->profile_manager()->GetLoadedProfiles();
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (size_t i = 0; i < profiles.size(); ++i) {
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      chrome_browser_net::Predictor* predictor =
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          profiles[i]->GetNetworkPredictor();
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (predictor) {
264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        predictor->EnablePredictorOnIOThread(false);
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        predictor->Shutdown();
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void RunUntilIdle() {
271c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    loop_.RunUntilIdle();
272c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    BrowserThread::GetBlockingPool()->FlushForTesting();
273    loop_.RunUntilIdle();
274  }
275
276  virtual void OnProfilePrepared(Profile* profile) OVERRIDE {
277    EXPECT_FALSE(prepared_profile_);
278    prepared_profile_ = profile;
279  }
280
281  virtual void OnLoginFailure(const LoginFailure& error) OVERRIDE {
282    FAIL() << "OnLoginFailure not expected";
283  }
284
285  virtual void OnLoginSuccess(const std::string& username,
286                              const std::string& password,
287                              bool pending_requests,
288                              bool using_oauth) OVERRIDE {
289    FAIL() << "OnLoginSuccess not expected";
290  }
291
292  void LockDevice(const std::string& username) {
293    EXPECT_CALL(*cryptohome_, InstallAttributesIsFirstInstall())
294        .WillOnce(Return(true))
295        .WillRepeatedly(Return(false));
296    policy::CloudPolicyDataStore* device_data_store =
297        connector_->GetDeviceCloudPolicyDataStore();
298    device_data_store->set_device_mode(policy::DEVICE_MODE_ENTERPRISE);
299    device_data_store->set_device_id(kDeviceId);
300    EXPECT_EQ(policy::EnterpriseInstallAttributes::LOCK_SUCCESS,
301              connector_->LockDevice(username));
302    RunUntilIdle();
303  }
304
305  void PrepareProfile(const std::string& username) {
306    ScopedDeviceSettingsTestHelper device_settings_test_helper;
307    MockSessionManagerClient* session_manager_client =
308        mock_dbus_thread_manager_.mock_session_manager_client();
309    EXPECT_CALL(*session_manager_client, StartSession(_));
310    EXPECT_CALL(*cryptohome_, GetSystemSalt())
311        .WillRepeatedly(Return(std::string("stub_system_salt")));
312    EXPECT_CALL(*mock_async_method_caller_, AsyncMount(_, _, _, _))
313        .WillRepeatedly(Return());
314
315    scoped_refptr<Authenticator> authenticator =
316        LoginUtils::Get()->CreateAuthenticator(this);
317    authenticator->CompleteLogin(ProfileManager::GetDefaultProfile(),
318                                 username,
319                                 "password");
320
321    const bool kPendingRequests = false;
322    const bool kUsingOAuth = true;
323    const bool kHasCookies = true;
324    LoginUtils::Get()->PrepareProfile(username, std::string(), "password",
325                                      kPendingRequests, kUsingOAuth,
326                                      kHasCookies, this);
327    device_settings_test_helper.Flush();
328    RunUntilIdle();
329  }
330
331  net::TestURLFetcher* PrepareOAuthFetcher(const std::string& expected_url) {
332    net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0);
333    EXPECT_TRUE(fetcher);
334    EXPECT_TRUE(fetcher->delegate());
335    EXPECT_TRUE(StartsWithASCII(fetcher->GetOriginalURL().spec(),
336                                expected_url,
337                                true));
338    fetcher->set_url(fetcher->GetOriginalURL());
339    fetcher->set_response_code(200);
340    fetcher->set_status(net::URLRequestStatus());
341    return fetcher;
342  }
343
344  net::TestURLFetcher* PrepareDMServiceFetcher(
345      const std::string& expected_url,
346      const em::DeviceManagementResponse& response) {
347    net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0);
348    EXPECT_TRUE(fetcher);
349    EXPECT_TRUE(fetcher->delegate());
350    EXPECT_TRUE(StartsWithASCII(fetcher->GetOriginalURL().spec(),
351                                expected_url,
352                                true));
353    fetcher->set_url(fetcher->GetOriginalURL());
354    fetcher->set_response_code(200);
355    fetcher->set_status(net::URLRequestStatus());
356    std::string data;
357    EXPECT_TRUE(response.SerializeToString(&data));
358    fetcher->SetResponseString(data);
359    return fetcher;
360  }
361
362  net::TestURLFetcher* PrepareDMRegisterFetcher() {
363    em::DeviceManagementResponse response;
364    em::DeviceRegisterResponse* register_response =
365        response.mutable_register_response();
366    register_response->set_device_management_token(kDMToken);
367    register_response->set_enrollment_type(
368        em::DeviceRegisterResponse::ENTERPRISE);
369    return PrepareDMServiceFetcher(kDMRegisterRequest, response);
370  }
371
372  net::TestURLFetcher* PrepareDMPolicyFetcher() {
373    em::DeviceManagementResponse response;
374    response.mutable_policy_response()->add_response();
375    return PrepareDMServiceFetcher(kDMPolicyRequest, response);
376  }
377
378 protected:
379  ScopedStubCrosEnabler stub_cros_enabler_;
380
381  MessageLoop loop_;
382  TestingBrowserProcess* browser_process_;
383  ScopedTestingLocalState local_state_;
384
385  content::TestBrowserThread ui_thread_;
386  content::TestBrowserThread db_thread_;
387  content::TestBrowserThread file_thread_;
388  content::TestBrowserThread io_thread_;
389  scoped_ptr<IOThread> io_thread_state_;
390
391  MockDBusThreadManager mock_dbus_thread_manager_;
392  input_method::MockInputMethodManager mock_input_method_manager_;
393  net::TestURLFetcherFactory test_url_fetcher_factory_;
394
395  cryptohome::MockAsyncMethodCaller* mock_async_method_caller_;
396
397  policy::BrowserPolicyConnector* connector_;
398  MockCryptohomeLibrary* cryptohome_;
399  Profile* prepared_profile_;
400
401 private:
402  ScopedTempDir scoped_temp_dir_;
403
404  std::string device_policy_;
405  std::string user_policy_;
406
407  DISALLOW_COPY_AND_ASSIGN(LoginUtilsTest);
408};
409
410class LoginUtilsBlockingLoginTest
411    : public LoginUtilsTest,
412      public testing::WithParamInterface<int> {};
413
414TEST_F(LoginUtilsTest, NormalLoginDoesntBlock) {
415  UserManager* user_manager = UserManager::Get();
416  ASSERT_TRUE(!user_manager->IsUserLoggedIn());
417  EXPECT_FALSE(connector_->IsEnterpriseManaged());
418  EXPECT_FALSE(prepared_profile_);
419
420  // The profile will be created without waiting for a policy response.
421  PrepareProfile(kUsername);
422
423  EXPECT_TRUE(prepared_profile_);
424  ASSERT_TRUE(user_manager->IsUserLoggedIn());
425  EXPECT_EQ(kUsername, user_manager->GetLoggedInUser()->email());
426}
427
428TEST_F(LoginUtilsTest, EnterpriseLoginDoesntBlockForNormalUser) {
429  UserManager* user_manager = UserManager::Get();
430  ASSERT_TRUE(!user_manager->IsUserLoggedIn());
431  EXPECT_FALSE(connector_->IsEnterpriseManaged());
432  EXPECT_FALSE(prepared_profile_);
433
434  // Enroll the device.
435  LockDevice(kUsername);
436
437  ASSERT_TRUE(!user_manager->IsUserLoggedIn());
438  EXPECT_TRUE(connector_->IsEnterpriseManaged());
439  EXPECT_EQ(kDomain, connector_->GetEnterpriseDomain());
440  EXPECT_FALSE(prepared_profile_);
441
442  // Login with a non-enterprise user shouldn't block.
443  PrepareProfile(kUsernameOtherDomain);
444
445  EXPECT_TRUE(prepared_profile_);
446  ASSERT_TRUE(user_manager->IsUserLoggedIn());
447  EXPECT_EQ(kUsernameOtherDomain, user_manager->GetLoggedInUser()->email());
448}
449
450TEST_F(LoginUtilsTest, OAuth1TokenFetchFailureUnblocksRefreshPolicies) {
451  // 0. Check that a user is not logged in yet.
452  UserManager* user_manager = UserManager::Get();
453  ASSERT_TRUE(!user_manager->IsUserLoggedIn());
454  EXPECT_FALSE(connector_->IsEnterpriseManaged());
455  EXPECT_FALSE(prepared_profile_);
456
457  // 1. Fake sign-in.
458  // The profile will be created without waiting for a policy.
459  content::WindowedNotificationObserver profile_creation_observer(
460      chrome::NOTIFICATION_PROFILE_CREATED,
461      content::NotificationService::AllSources());
462  PrepareProfile(kUsername);
463  // Wait until the profile is fully initialized. This makes sure the async
464  // prefs init has finished, and the OnProfileCreated() callback has been
465  // invoked.
466  profile_creation_observer.Wait();
467  EXPECT_TRUE(prepared_profile_);
468  ASSERT_TRUE(user_manager->IsUserLoggedIn());
469  EXPECT_EQ(kUsername, user_manager->GetLoggedInUser()->email());
470
471  // 2. Get the pending oauth1 access token fetcher.
472  net::TestURLFetcher* fetcher =
473      PrepareOAuthFetcher(GaiaUrls::GetInstance()->get_oauth_token_url());
474  ASSERT_TRUE(fetcher);
475
476  // 3. Issuing a RefreshPolicies() now blocks waiting for the oauth token.
477  bool refresh_policies_completed = false;
478  browser_process_->policy_service()->RefreshPolicies(
479      base::Bind(SetFlag, &refresh_policies_completed));
480  RunUntilIdle();
481  ASSERT_FALSE(refresh_policies_completed);
482
483  // 4. Now make the fetcher fail. RefreshPolicies() should unblock.
484  // The OAuth1TokenFetcher retries up to 5 times with a 3 second delay;
485  // just invoke the callback directly to avoid waiting for that.
486  // The |mock_fetcher| is passed instead of the original because the original
487  // is deleted by the GaiaOAuthFetcher after the first callback.
488  net::URLFetcherDelegate* delegate = fetcher->delegate();
489  ASSERT_TRUE(delegate);
490  net::TestURLFetcher mock_fetcher(fetcher->id(),
491                                   fetcher->GetOriginalURL(),
492                                   delegate);
493  mock_fetcher.set_status(net::URLRequestStatus());
494  mock_fetcher.set_response_code(404);
495  for (int i = 0; i < 6; ++i) {
496    ASSERT_FALSE(refresh_policies_completed);
497    delegate->OnURLFetchComplete(&mock_fetcher);
498    RunUntilIdle();
499  }
500  EXPECT_TRUE(refresh_policies_completed);
501}
502
503TEST_P(LoginUtilsBlockingLoginTest, EnterpriseLoginBlocksForEnterpriseUser) {
504  UserManager* user_manager = UserManager::Get();
505  ASSERT_TRUE(!user_manager->IsUserLoggedIn());
506  EXPECT_FALSE(connector_->IsEnterpriseManaged());
507  EXPECT_FALSE(prepared_profile_);
508
509  // Enroll the device.
510  LockDevice(kUsername);
511
512  ASSERT_TRUE(!user_manager->IsUserLoggedIn());
513  EXPECT_TRUE(connector_->IsEnterpriseManaged());
514  EXPECT_EQ(kDomain, connector_->GetEnterpriseDomain());
515  EXPECT_FALSE(prepared_profile_);
516
517  // Login with a user of the enterprise domain waits for policy.
518  PrepareProfile(kUsername);
519
520  EXPECT_FALSE(prepared_profile_);
521  ASSERT_TRUE(user_manager->IsUserLoggedIn());
522
523  GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
524  net::TestURLFetcher* fetcher;
525
526  // |steps| is the test parameter, and is the number of successful fetches.
527  // The first incomplete fetch will fail. In any case, the profile creation
528  // should resume.
529  int steps = GetParam();
530
531  do {
532    if (steps < 1) break;
533
534    // Fake OAuth token retrieval:
535    fetcher = PrepareOAuthFetcher(gaia_urls->get_oauth_token_url());
536    ASSERT_TRUE(fetcher);
537    net::ResponseCookies cookies;
538    cookies.push_back(kOAuthTokenCookie);
539    fetcher->set_cookies(cookies);
540    fetcher->delegate()->OnURLFetchComplete(fetcher);
541    if (steps < 2) break;
542
543    // Fake OAuth access token retrieval:
544    fetcher = PrepareOAuthFetcher(gaia_urls->oauth_get_access_token_url());
545    ASSERT_TRUE(fetcher);
546    fetcher->SetResponseString(kOAuthGetAccessTokenData);
547    fetcher->delegate()->OnURLFetchComplete(fetcher);
548    if (steps < 3) break;
549
550    // Fake OAuth service token retrieval:
551    fetcher = PrepareOAuthFetcher(gaia_urls->oauth_wrap_bridge_url());
552    ASSERT_TRUE(fetcher);
553    fetcher->SetResponseString(kOAuthServiceTokenData);
554    fetcher->delegate()->OnURLFetchComplete(fetcher);
555
556    // The cloud policy subsystem is now ready to fetch the dmtoken and the user
557    // policy.
558    RunUntilIdle();
559    if (steps < 4) break;
560
561    fetcher = PrepareDMRegisterFetcher();
562    ASSERT_TRUE(fetcher);
563    fetcher->delegate()->OnURLFetchComplete(fetcher);
564    // The policy fetch job has now been scheduled, run it:
565    RunUntilIdle();
566    if (steps < 5) break;
567
568    // Verify that there is no profile prepared just before the policy fetch.
569    EXPECT_FALSE(prepared_profile_);
570
571    fetcher = PrepareDMPolicyFetcher();
572    ASSERT_TRUE(fetcher);
573    fetcher->delegate()->OnURLFetchComplete(fetcher);
574  } while (0);
575
576  if (steps < 5) {
577    // Verify that the profile hasn't been created yet.
578    EXPECT_FALSE(prepared_profile_);
579
580    // Make the current fetcher fail.
581    net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0);
582    ASSERT_TRUE(fetcher);
583    EXPECT_TRUE(fetcher->delegate());
584    fetcher->set_url(fetcher->GetOriginalURL());
585    fetcher->set_response_code(500);
586    fetcher->delegate()->OnURLFetchComplete(fetcher);
587  }
588
589  // The profile is finally ready:
590  EXPECT_TRUE(prepared_profile_);
591}
592
593INSTANTIATE_TEST_CASE_P(
594    LoginUtilsBlockingLoginTestInstance,
595    LoginUtilsBlockingLoginTest,
596    testing::Values(0, 1, 2, 3, 4, 5));
597
598}  // namespace
599
600}
601