- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / login / login_utils_browsertest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/login/login_utils.h"
6
7 #include "base/basictypes.h"
8 #include "base/bind.h"
9 #include "base/command_line.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/path_service.h"
13 #include "base/prefs/pref_registry_simple.h"
14 #include "base/run_loop.h"
15 #include "base/strings/string_util.h"
16 #include "base/synchronization/waitable_event.h"
17 #include "base/threading/sequenced_worker_pool.h"
18 #include "base/threading/thread.h"
19 #include "chrome/browser/chrome_notification_types.h"
20 #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
21 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
22 #include "chrome/browser/chromeos/login/authenticator.h"
23 #include "chrome/browser/chromeos/login/login_status_consumer.h"
24 #include "chrome/browser/chromeos/login/user_manager.h"
25 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
26 #include "chrome/browser/chromeos/settings/cros_settings.h"
27 #include "chrome/browser/chromeos/settings/device_settings_service.h"
28 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
29 #include "chrome/browser/chromeos/settings/mock_owner_key_util.h"
30 #include "chrome/browser/io_thread.h"
31 #include "chrome/browser/net/predictor.h"
32 #include "chrome/browser/policy/browser_policy_connector.h"
33 #include "chrome/browser/policy/cloud/device_management_service.h"
34 #include "chrome/browser/policy/policy_service.h"
35 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
36 #include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h"
37 #include "chrome/browser/profiles/profile_manager.h"
38 #include "chrome/browser/rlz/rlz.h"
39 #include "chrome/common/chrome_paths.h"
40 #include "chrome/common/chrome_switches.h"
41 #include "chrome/common/pref_names.h"
42 #include "chrome/test/base/scoped_testing_local_state.h"
43 #include "chrome/test/base/testing_browser_process.h"
44 #include "chromeos/chromeos_switches.h"
45 #include "chromeos/cryptohome/mock_async_method_caller.h"
46 #include "chromeos/cryptohome/system_salt_getter.h"
47 #include "chromeos/dbus/fake_dbus_thread_manager.h"
48 #include "chromeos/disks/disk_mount_manager.h"
49 #include "chromeos/disks/mock_disk_mount_manager.h"
50 #include "chromeos/login/login_state.h"
51 #include "chromeos/network/network_handler.h"
52 #include "chromeos/system/mock_statistics_provider.h"
53 #include "chromeos/system/statistics_provider.h"
54 #include "content/public/browser/browser_thread.h"
55 #include "content/public/test/test_browser_thread.h"
56 #include "content/public/test/test_utils.h"
57 #include "google_apis/gaia/gaia_auth_consumer.h"
58 #include "google_apis/gaia/gaia_urls.h"
59 #include "net/url_request/test_url_fetcher_factory.h"
60 #include "net/url_request/url_fetcher_delegate.h"
61 #include "net/url_request/url_request.h"
62 #include "net/url_request/url_request_context_getter.h"
63 #include "net/url_request/url_request_status.h"
64 #include "net/url_request/url_request_test_util.h"
65 #include "testing/gmock/include/gmock/gmock.h"
66 #include "testing/gtest/include/gtest/gtest.h"
67
68 #if defined(ENABLE_RLZ)
69 #include "rlz/lib/rlz_value_store.h"
70 #endif
71
72 using ::testing::AnyNumber;
73
74 namespace chromeos {
75
76 namespace {
77
78 namespace em = enterprise_management;
79
80 using ::testing::DoAll;
81 using ::testing::Return;
82 using ::testing::SaveArg;
83 using ::testing::SetArgPointee;
84 using ::testing::_;
85 using content::BrowserThread;
86
87 const char kDomain[] = "domain.com";
88 const char kUsername[] = "user@domain.com";
89 const char kDeviceId[] = "100200300";
90 const char kUsernameOtherDomain[] = "user@other.com";
91
92 const char kOAuthTokenCookie[] = "oauth_token=1234";
93
94 const char kGaiaAccountDisabledResponse[] = "Error=AccountDeleted";
95
96 const char kOAuth2TokenPairData[] =
97     "{"
98     "  \"refresh_token\": \"1234\","
99     "  \"access_token\": \"5678\","
100     "  \"expires_in\": 3600"
101     "}";
102
103 const char kOAuth2AccessTokenData[] =
104     "{"
105     "  \"access_token\": \"5678\","
106     "  \"expires_in\": 3600"
107     "}";
108
109 const char kDMServer[] = "http://server/device_management";
110 const char kDMRegisterRequest[] =
111     "http://server/device_management?request=register";
112 const char kDMPolicyRequest[] =
113     "http://server/device_management?request=policy";
114
115 const char kDMToken[] = "1234";
116
117 // Used to mark |flag|, indicating that RefreshPolicies() has executed its
118 // callback.
119 void SetFlag(bool* flag) {
120   *flag = true;
121 }
122
123 // Single task of the fake IO loop used in the test, that just waits until
124 // it is signaled to quit or perform some work.
125 // |completion| is the event to wait for, and |work| is the task to invoke
126 // when signaled. If the task returns false then this quits the IO loop.
127 void BlockLoop(base::WaitableEvent* completion, base::Callback<bool()> work) {
128   do {
129     completion->Wait();
130   } while (work.Run());
131   base::MessageLoop::current()->QuitNow();
132 }
133
134 void CopyLockResult(base::RunLoop* loop,
135                     policy::EnterpriseInstallAttributes::LockResult* out,
136                     policy::EnterpriseInstallAttributes::LockResult result) {
137   *out = result;
138   loop->Quit();
139 }
140
141 class LoginUtilsTest : public testing::Test,
142                        public LoginUtils::Delegate,
143                        public LoginStatusConsumer {
144  public:
145   // Initialization here is important. The UI thread gets the test's
146   // message loop, as does the file thread (which never actually gets
147   // started - so this is a way to fake multiple threads on a single
148   // test thread).  The IO thread does not get the message loop set,
149   // and is never started.  This is necessary so that we skip various
150   // bits of initialization that get posted to the IO thread.  We do
151   // however, at one point in the test, temporarily set the message
152   // loop for the IO thread.
153   LoginUtilsTest()
154       : fake_io_thread_completion_(false, false),
155         fake_io_thread_("fake_io_thread"),
156         loop_(base::MessageLoop::TYPE_IO),
157         browser_process_(TestingBrowserProcess::GetGlobal()),
158         local_state_(browser_process_),
159         ui_thread_(BrowserThread::UI, &loop_),
160         db_thread_(BrowserThread::DB, &loop_),
161         file_thread_(BrowserThread::FILE, &loop_),
162         mock_input_method_manager_(NULL),
163         mock_async_method_caller_(NULL),
164         connector_(NULL),
165         prepared_profile_(NULL) {}
166
167   virtual void SetUp() OVERRIDE {
168     // This test is not a full blown InProcessBrowserTest, and doesn't have
169     // all the usual threads running. However a lot of subsystems pulled from
170     // ProfileImpl post to IO (usually from ProfileIOData), and DCHECK that
171     // those tasks were posted. Those tasks in turn depend on a lot of other
172     // components that aren't there during this test, so this kludge is used to
173     // have a running IO loop that doesn't really execute any tasks.
174     //
175     // See InvokeOnIO() below for a way to perform specific tasks on IO, when
176     // that's necessary.
177
178     // A thread is needed to create a new MessageLoop, since there can be only
179     // one loop per thread.
180     fake_io_thread_.StartWithOptions(
181         base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
182     base::MessageLoop* fake_io_loop = fake_io_thread_.message_loop();
183     // Make this loop enter the single task, BlockLoop(). Pass in the completion
184     // event and the work callback.
185     fake_io_thread_.StopSoon();
186     fake_io_loop->PostTask(
187         FROM_HERE,
188         base::Bind(
189           BlockLoop,
190           &fake_io_thread_completion_,
191           base::Bind(&LoginUtilsTest::DoIOWork, base::Unretained(this))));
192     // Map BrowserThread::IO to this loop. This allows posting to IO but nothing
193     // will be executed.
194     io_thread_.reset(
195         new content::TestBrowserThread(BrowserThread::IO, fake_io_loop));
196
197     ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
198
199     CommandLine* command_line = CommandLine::ForCurrentProcess();
200     command_line->AppendSwitchASCII(
201         ::switches::kDeviceManagementUrl, kDMServer);
202     command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
203
204     // DBusThreadManager should be initialized before io_thread_state_, as
205     // DBusThreadManager is used from chromeos::ProxyConfigServiceImpl,
206     // which is part of io_thread_state_.
207     DBusThreadManager::InitializeForTesting(&fake_dbus_thread_manager_);
208
209     SystemSaltGetter::Initialize();
210     LoginState::Initialize();
211
212     EXPECT_CALL(mock_statistics_provider_, GetMachineStatistic(_, _))
213         .WillRepeatedly(Return(false));
214     chromeos::system::StatisticsProvider::SetTestProvider(
215         &mock_statistics_provider_);
216
217     mock_input_method_manager_ = new input_method::MockInputMethodManager();
218     input_method::InitializeForTesting(mock_input_method_manager_);
219     disks::DiskMountManager::InitializeForTesting(&mock_disk_mount_manager_);
220     mock_disk_mount_manager_.SetupDefaultReplies();
221
222     mock_async_method_caller_ = new cryptohome::MockAsyncMethodCaller;
223     cryptohome::AsyncMethodCaller::InitializeForTesting(
224         mock_async_method_caller_);
225
226     test_device_settings_service_.reset(new ScopedTestDeviceSettingsService);
227     test_cros_settings_.reset(new ScopedTestCrosSettings);
228     test_user_manager_.reset(new ScopedTestUserManager);
229
230     // IOThread creates ProxyConfigServiceImpl and
231     // BrowserPolicyConnector::Init() creates a NetworkConfigurationUpdater,
232     // which both access NetworkHandler. Thus initialize it here before creating
233     // IOThread and before calling BrowserPolicyConnector::Init().
234     NetworkHandler::Initialize();
235
236     browser_process_->SetProfileManager(
237         new ProfileManagerWithoutInit(scoped_temp_dir_.path()));
238     browser_process_->SetSystemRequestContext(
239         new net::TestURLRequestContextGetter(
240             base::MessageLoopProxy::current()));
241     connector_ = browser_process_->browser_policy_connector();
242     connector_->Init(local_state_.Get(),
243                      browser_process_->system_request_context());
244
245     io_thread_state_.reset(new IOThread(local_state_.Get(),
246                                         browser_process_->policy_service(),
247                                         NULL, NULL));
248     browser_process_->SetIOThread(io_thread_state_.get());
249
250 #if defined(ENABLE_RLZ)
251     rlz_initialized_cb_ = base::Bind(&base::DoNothing);
252     rlz_lib::testing::SetRlzStoreDirectory(scoped_temp_dir_.path());
253     RLZTracker::EnableZeroDelayForTesting();
254 #endif
255
256     RunUntilIdle();
257   }
258
259   virtual void TearDown() OVERRIDE {
260     cryptohome::AsyncMethodCaller::Shutdown();
261     mock_async_method_caller_ = NULL;
262
263     test_user_manager_.reset();
264
265     InvokeOnIO(
266         base::Bind(&LoginUtilsTest::TearDownOnIO, base::Unretained(this)));
267
268     // LoginUtils instance must not outlive Profile instances.
269     LoginUtils::Set(NULL);
270
271     input_method::Shutdown();
272     LoginState::Shutdown();
273     SystemSaltGetter::Shutdown();
274
275     // These trigger some tasks that have to run while BrowserThread::UI
276     // exists. Delete all the profiles before deleting the connector.
277     browser_process_->SetProfileManager(NULL);
278     connector_ = NULL;
279     browser_process_->SetBrowserPolicyConnector(NULL);
280     QuitIOLoop();
281     RunUntilIdle();
282   }
283
284   void TearDownOnIO() {
285     // chrome_browser_net::Predictor usually skips its shutdown routines on
286     // unit_tests, but does the full thing when
287     // g_browser_process->profile_manager() is valid during initialization.
288     // That includes a WaitableEvent on UI waiting for a task on IO, so that
289     // task must execute. Do it directly from here now.
290     std::vector<Profile*> profiles =
291         browser_process_->profile_manager()->GetLoadedProfiles();
292     for (size_t i = 0; i < profiles.size(); ++i) {
293       chrome_browser_net::Predictor* predictor =
294           profiles[i]->GetNetworkPredictor();
295       if (predictor) {
296         predictor->EnablePredictorOnIOThread(false);
297         predictor->Shutdown();
298       }
299     }
300   }
301
302   void RunUntilIdle() {
303     loop_.RunUntilIdle();
304     BrowserThread::GetBlockingPool()->FlushForTesting();
305     loop_.RunUntilIdle();
306   }
307
308   // Invokes |task| on the IO loop and returns after it has executed.
309   void InvokeOnIO(const base::Closure& task) {
310     fake_io_thread_work_ = task;
311     fake_io_thread_completion_.Signal();
312     content::RunMessageLoop();
313   }
314
315   // Makes the fake IO loop return.
316   void QuitIOLoop() {
317     fake_io_thread_completion_.Signal();
318     content::RunMessageLoop();
319   }
320
321   // Helper for BlockLoop, InvokeOnIO and QuitIOLoop.
322   bool DoIOWork() {
323     bool has_work = !fake_io_thread_work_.is_null();
324     if (has_work)
325       fake_io_thread_work_.Run();
326     fake_io_thread_work_.Reset();
327     BrowserThread::PostTask(
328         BrowserThread::UI, FROM_HERE,
329         base::MessageLoop::QuitWhenIdleClosure());
330     // If there was work then keep waiting for more work.
331     // If there was no work then quit the fake IO loop.
332     return has_work;
333   }
334
335   virtual void OnProfilePrepared(Profile* profile) OVERRIDE {
336     EXPECT_FALSE(prepared_profile_);
337     prepared_profile_ = profile;
338   }
339
340 #if defined(ENABLE_RLZ)
341   virtual void OnRlzInitialized(Profile* profile) OVERRIDE {
342     rlz_initialized_cb_.Run();
343   }
344 #endif
345
346   virtual void OnLoginFailure(const LoginFailure& error) OVERRIDE {
347     FAIL() << "OnLoginFailure not expected";
348   }
349
350   virtual void OnLoginSuccess(const UserContext& user_context) OVERRIDE {
351     FAIL() << "OnLoginSuccess not expected";
352   }
353
354   void EnrollDevice(const std::string& username) {
355     base::RunLoop loop;
356     policy::EnterpriseInstallAttributes::LockResult result;
357     connector_->GetInstallAttributes()->LockDevice(
358         username, policy::DEVICE_MODE_ENTERPRISE, kDeviceId,
359         base::Bind(&CopyLockResult, &loop, &result));
360     loop.Run();
361     EXPECT_EQ(policy::EnterpriseInstallAttributes::LOCK_SUCCESS, result);
362     RunUntilIdle();
363   }
364
365   void PrepareProfile(const std::string& username) {
366     // Normally this would happen during browser startup, but for tests
367     // we need to trigger creation of Profile-related services.
368     ChromeBrowserMainExtraPartsProfiles::
369         EnsureBrowserContextKeyedServiceFactoriesBuilt();
370     ProfileManager::AllowGetDefaultProfile();
371
372     DeviceSettingsTestHelper device_settings_test_helper;
373     DeviceSettingsService::Get()->SetSessionManager(
374         &device_settings_test_helper, new MockOwnerKeyUtil());
375
376     EXPECT_CALL(*mock_async_method_caller_, AsyncMount(_, _, _, _))
377         .WillRepeatedly(Return());
378     EXPECT_CALL(*mock_async_method_caller_, AsyncGetSanitizedUsername(_, _))
379         .WillRepeatedly(Return());
380
381     scoped_refptr<Authenticator> authenticator =
382         LoginUtils::Get()->CreateAuthenticator(this);
383     authenticator->CompleteLogin(ProfileManager::GetDefaultProfile(),
384                                  UserContext(username,
385                                              "password",
386                                              std::string(),
387                                              username));   // username_hash
388
389     const bool kUsingOAuth = true;
390     // Setting |kHasCookies| to false prevents ProfileAuthData::Transfer from
391     // waiting for an IO task before proceeding.
392     const bool kHasCookies = false;
393     const bool kHasActiveSession = false;
394     LoginUtils::Get()->PrepareProfile(
395         UserContext(username, "password", std::string(), username, kUsingOAuth),
396         std::string(), kHasCookies, kHasActiveSession, this);
397     device_settings_test_helper.Flush();
398     RunUntilIdle();
399
400     DeviceSettingsService::Get()->UnsetSessionManager();
401   }
402
403   net::TestURLFetcher* PrepareOAuthFetcher(const GURL& expected_url) {
404     net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0);
405     EXPECT_TRUE(fetcher);
406     if (!fetcher)
407       return NULL;
408     EXPECT_TRUE(fetcher->delegate());
409     EXPECT_TRUE(StartsWithASCII(fetcher->GetOriginalURL().spec(),
410                                 expected_url.spec(),
411                                 true));
412     fetcher->set_url(fetcher->GetOriginalURL());
413     fetcher->set_response_code(200);
414     fetcher->set_status(net::URLRequestStatus());
415     return fetcher;
416   }
417
418   net::TestURLFetcher* PrepareDMServiceFetcher(
419       const std::string& expected_url,
420       const em::DeviceManagementResponse& response) {
421     net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(
422         policy::DeviceManagementService::kURLFetcherID);
423     EXPECT_TRUE(fetcher);
424     if (!fetcher)
425       return NULL;
426     EXPECT_TRUE(fetcher->delegate());
427     EXPECT_TRUE(StartsWithASCII(fetcher->GetOriginalURL().spec(),
428                                 expected_url,
429                                 true));
430     fetcher->set_url(fetcher->GetOriginalURL());
431     fetcher->set_response_code(200);
432     fetcher->set_status(net::URLRequestStatus());
433     std::string data;
434     EXPECT_TRUE(response.SerializeToString(&data));
435     fetcher->SetResponseString(data);
436     return fetcher;
437   }
438
439   net::TestURLFetcher* PrepareDMRegisterFetcher() {
440     em::DeviceManagementResponse response;
441     em::DeviceRegisterResponse* register_response =
442         response.mutable_register_response();
443     register_response->set_device_management_token(kDMToken);
444     register_response->set_enrollment_type(
445         em::DeviceRegisterResponse::ENTERPRISE);
446     return PrepareDMServiceFetcher(kDMRegisterRequest, response);
447   }
448
449   net::TestURLFetcher* PrepareDMPolicyFetcher() {
450     em::DeviceManagementResponse response;
451     response.mutable_policy_response()->add_response();
452     return PrepareDMServiceFetcher(kDMPolicyRequest, response);
453   }
454
455  protected:
456   base::Closure fake_io_thread_work_;
457   base::WaitableEvent fake_io_thread_completion_;
458   base::Thread fake_io_thread_;
459
460   base::MessageLoop loop_;
461   TestingBrowserProcess* browser_process_;
462   ScopedTestingLocalState local_state_;
463
464   content::TestBrowserThread ui_thread_;
465   content::TestBrowserThread db_thread_;
466   content::TestBrowserThread file_thread_;
467   scoped_ptr<content::TestBrowserThread> io_thread_;
468   scoped_ptr<IOThread> io_thread_state_;
469
470   FakeDBusThreadManager fake_dbus_thread_manager_;
471   input_method::MockInputMethodManager* mock_input_method_manager_;
472   disks::MockDiskMountManager mock_disk_mount_manager_;
473   net::TestURLFetcherFactory test_url_fetcher_factory_;
474
475   cryptohome::MockAsyncMethodCaller* mock_async_method_caller_;
476
477   chromeos::system::MockStatisticsProvider mock_statistics_provider_;
478
479   policy::BrowserPolicyConnector* connector_;
480
481   // Initialized after |fake_dbus_thread_manager_| is set up.
482   scoped_ptr<ScopedTestDeviceSettingsService> test_device_settings_service_;
483   scoped_ptr<ScopedTestCrosSettings> test_cros_settings_;
484   scoped_ptr<ScopedTestUserManager> test_user_manager_;
485
486   Profile* prepared_profile_;
487
488   base::Closure rlz_initialized_cb_;
489
490  private:
491   base::ScopedTempDir scoped_temp_dir_;
492
493   std::string device_policy_;
494   std::string user_policy_;
495
496   DISALLOW_COPY_AND_ASSIGN(LoginUtilsTest);
497 };
498
499 class LoginUtilsBlockingLoginTest
500     : public LoginUtilsTest,
501       public testing::WithParamInterface<int> {};
502
503 TEST_F(LoginUtilsTest, NormalLoginDoesntBlock) {
504   UserManager* user_manager = UserManager::Get();
505   EXPECT_FALSE(user_manager->IsUserLoggedIn());
506   EXPECT_FALSE(connector_->IsEnterpriseManaged());
507   EXPECT_FALSE(prepared_profile_);
508   EXPECT_EQ(policy::USER_AFFILIATION_NONE,
509             connector_->GetUserAffiliation(kUsername));
510
511   // The profile will be created without waiting for a policy response.
512   PrepareProfile(kUsername);
513
514   EXPECT_TRUE(prepared_profile_);
515   ASSERT_TRUE(user_manager->IsUserLoggedIn());
516   EXPECT_EQ(kUsername, user_manager->GetLoggedInUser()->email());
517 }
518
519 TEST_F(LoginUtilsTest, EnterpriseLoginDoesntBlockForNormalUser) {
520   UserManager* user_manager = UserManager::Get();
521   EXPECT_FALSE(user_manager->IsUserLoggedIn());
522   EXPECT_FALSE(connector_->IsEnterpriseManaged());
523   EXPECT_FALSE(prepared_profile_);
524
525   // Enroll the device.
526   EnrollDevice(kUsername);
527
528   EXPECT_FALSE(user_manager->IsUserLoggedIn());
529   EXPECT_TRUE(connector_->IsEnterpriseManaged());
530   EXPECT_EQ(kDomain, connector_->GetEnterpriseDomain());
531   EXPECT_FALSE(prepared_profile_);
532   EXPECT_EQ(policy::USER_AFFILIATION_NONE,
533             connector_->GetUserAffiliation(kUsernameOtherDomain));
534
535   // Login with a non-enterprise user shouldn't block.
536   PrepareProfile(kUsernameOtherDomain);
537
538   EXPECT_TRUE(prepared_profile_);
539   ASSERT_TRUE(user_manager->IsUserLoggedIn());
540   EXPECT_EQ(kUsernameOtherDomain, user_manager->GetLoggedInUser()->email());
541 }
542
543 #if defined(ENABLE_RLZ)
544 TEST_F(LoginUtilsTest, RlzInitialized) {
545   // No RLZ brand code set initially.
546   EXPECT_FALSE(local_state_.Get()->HasPrefPath(prefs::kRLZBrand));
547
548   base::RunLoop wait_for_rlz_init;
549   rlz_initialized_cb_ = wait_for_rlz_init.QuitClosure();
550
551   PrepareProfile(kUsername);
552
553   wait_for_rlz_init.Run();
554   // Wait for blocking RLZ tasks to complete.
555   RunUntilIdle();
556
557   // RLZ brand code has been set to empty string.
558   EXPECT_TRUE(local_state_.Get()->HasPrefPath(prefs::kRLZBrand));
559   EXPECT_EQ(std::string(), local_state_.Get()->GetString(prefs::kRLZBrand));
560
561   // RLZ value for homepage access point should have been initialized.
562   string16 rlz_string;
563   EXPECT_TRUE(RLZTracker::GetAccessPointRlz(
564       RLZTracker::CHROME_HOME_PAGE, &rlz_string));
565   EXPECT_EQ(string16(), rlz_string);
566 }
567 #endif
568
569 TEST_P(LoginUtilsBlockingLoginTest, EnterpriseLoginBlocksForEnterpriseUser) {
570   UserManager* user_manager = UserManager::Get();
571   EXPECT_FALSE(user_manager->IsUserLoggedIn());
572   EXPECT_FALSE(connector_->IsEnterpriseManaged());
573   EXPECT_FALSE(prepared_profile_);
574
575   // Enroll the device.
576   EnrollDevice(kUsername);
577
578   EXPECT_FALSE(user_manager->IsUserLoggedIn());
579   EXPECT_TRUE(connector_->IsEnterpriseManaged());
580   EXPECT_EQ(kDomain, connector_->GetEnterpriseDomain());
581   EXPECT_FALSE(prepared_profile_);
582   EXPECT_EQ(policy::USER_AFFILIATION_MANAGED,
583             connector_->GetUserAffiliation(kUsername));
584   EXPECT_FALSE(user_manager->IsKnownUser(kUsername));
585
586   // Login with a user of the enterprise domain waits for policy.
587   PrepareProfile(kUsername);
588
589   EXPECT_FALSE(prepared_profile_);
590   ASSERT_TRUE(user_manager->IsUserLoggedIn());
591   EXPECT_TRUE(user_manager->IsCurrentUserNew());
592
593   GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
594   net::TestURLFetcher* fetcher;
595
596   // |steps| is the test parameter, and is the number of successful fetches.
597   // The first incomplete fetch will fail. In any case, the profile creation
598   // should resume.
599   int steps = GetParam();
600
601   // The next expected fetcher ID. This is used to make it fail.
602   int next_expected_fetcher_id = 0;
603
604   do {
605     if (steps < 1) break;
606
607     // Fake refresh token retrieval:
608     fetcher = PrepareOAuthFetcher(gaia_urls->client_login_to_oauth2_url());
609     ASSERT_TRUE(fetcher);
610     net::ResponseCookies cookies;
611     cookies.push_back(kOAuthTokenCookie);
612     fetcher->set_cookies(cookies);
613     fetcher->delegate()->OnURLFetchComplete(fetcher);
614     if (steps < 2) break;
615
616     // Fake OAuth2 token pair retrieval:
617     fetcher = PrepareOAuthFetcher(gaia_urls->oauth2_token_url());
618     ASSERT_TRUE(fetcher);
619     fetcher->SetResponseString(kOAuth2TokenPairData);
620     fetcher->delegate()->OnURLFetchComplete(fetcher);
621     if (steps < 3) break;
622
623     // Fake OAuth2 access token retrieval:
624     fetcher = PrepareOAuthFetcher(gaia_urls->oauth2_token_url());
625     ASSERT_TRUE(fetcher);
626     fetcher->SetResponseString(kOAuth2AccessTokenData);
627     fetcher->delegate()->OnURLFetchComplete(fetcher);
628
629     // The cloud policy subsystem is now ready to fetch the dmtoken and the user
630     // policy.
631     next_expected_fetcher_id = policy::DeviceManagementService::kURLFetcherID;
632     RunUntilIdle();
633     if (steps < 4) break;
634
635     fetcher = PrepareDMRegisterFetcher();
636     ASSERT_TRUE(fetcher);
637     fetcher->delegate()->OnURLFetchComplete(fetcher);
638     // The policy fetch job has now been scheduled, run it:
639     RunUntilIdle();
640     if (steps < 5) break;
641
642     // Verify that there is no profile prepared just before the policy fetch.
643     EXPECT_FALSE(prepared_profile_);
644
645     fetcher = PrepareDMPolicyFetcher();
646     ASSERT_TRUE(fetcher);
647     fetcher->delegate()->OnURLFetchComplete(fetcher);
648     RunUntilIdle();
649   } while (0);
650
651   if (steps < 5) {
652     // Verify that the profile hasn't been created yet.
653     EXPECT_FALSE(prepared_profile_);
654
655     // Make the current fetcher fail with a Gaia error.
656     net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(
657         next_expected_fetcher_id);
658     ASSERT_TRUE(fetcher);
659     EXPECT_TRUE(fetcher->delegate());
660     fetcher->set_url(fetcher->GetOriginalURL());
661     fetcher->set_response_code(401);
662     // This response body is important to make the gaia fetcher skip its delayed
663     // retry behavior, which makes testing harder. If this is sent to the policy
664     // fetchers then it will make them fail too.
665     fetcher->SetResponseString(kGaiaAccountDisabledResponse);
666     fetcher->delegate()->OnURLFetchComplete(fetcher);
667     RunUntilIdle();
668   }
669
670   // The profile is finally ready:
671   EXPECT_TRUE(prepared_profile_);
672 }
673
674 INSTANTIATE_TEST_CASE_P(
675     LoginUtilsBlockingLoginTestInstance,
676     LoginUtilsBlockingLoginTest,
677     testing::Values(0, 1, 2, 3, 4, 5));
678
679 }  // namespace
680
681 }  // namespace chromeos