user_cloud_policy_manager_chromeos_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file.
490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
6ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/bind.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/bind_helpers.h"
990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/callback.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/prefs/pref_registry_simple.h"
12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/prefs/testing_pref_service.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/run_loop.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/sequenced_task_runner.h"
15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/strings/string_util.h"
16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/test/test_simple_task_runner.h"
1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.h"
19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/chromeos/profiles/profile_helper.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/prefs/browser_prefs.h"
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/prefs/pref_service_syncable.h"
22a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "chrome/browser/signin/fake_profile_oauth2_token_service_wrapper.h"
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/signin/profile_oauth2_token_service.h"
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/signin/signin_manager.h"
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h"
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/common/chrome_constants.h"
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/test/base/testing_browser_process.h"
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/test/base/testing_profile.h"
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/test/base/testing_profile_manager.h"
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "components/policy/core/common/cloud/cloud_external_data_manager.h"
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "components/policy/core/common/cloud/mock_cloud_external_data_manager.h"
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "components/policy/core/common/cloud/mock_device_management_service.h"
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "components/policy/core/common/external_data_fetcher.h"
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "components/policy/core/common/mock_configuration_policy_provider.h"
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "components/policy/core/common/schema_registry.h"
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "google_apis/gaia/gaia_auth_consumer.h"
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "google_apis/gaia/gaia_constants.h"
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "google_apis/gaia/gaia_urls.h"
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/url_request/test_url_fetcher_factory.h"
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h"
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/url_request/url_request_status.h"
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "policy/policy_constants.h"
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "policy/proto/device_management_backend.pb.h"
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace em = enterprise_management;
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using testing::AnyNumber;
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using testing::AtLeast;
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using testing::Mock;
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using testing::_;
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace policy {
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace {
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kOAuthTokenCookie[] = "oauth_token=1234";
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kOAuth2TokenPairData[] =
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "{"
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "  \"refresh_token\": \"1234\","
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "  \"access_token\": \"5678\","
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "  \"expires_in\": 3600"
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "}";
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kOAuth2AccessTokenData[] =
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    "{"
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    "  \"access_token\": \"5678\","
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    "  \"expires_in\": 3600"
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    "}";
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class UserCloudPolicyManagerChromeOSTest : public testing::Test {
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) protected:
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  UserCloudPolicyManagerChromeOSTest()
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : store_(NULL),
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        external_data_manager_(NULL),
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        task_runner_(new base::TestSimpleTaskRunner()),
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        profile_(NULL),
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        signin_profile_(NULL) {}
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // The initialization path that blocks on the initial policy fetch requires
91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // a signin Profile to use its URLRequestContext.
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    profile_manager_.reset(
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_TRUE(profile_manager_->SetUp());
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    TestingProfile::TestingFactories factories;
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    factories.push_back(
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        std::make_pair(ProfileOAuth2TokenServiceFactory::GetInstance(),
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       FakeProfileOAuth2TokenServiceWrapper::Build));
9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    profile_ = profile_manager_->CreateTestingProfile(
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        chrome::kInitialProfile, scoped_ptr<PrefServiceSyncable>(),
10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        base::UTF8ToUTF16("testing_profile"), 0, std::string(), factories);
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    signin_profile_ = profile_manager_->CreateTestingProfile(kSigninProfile);
103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    signin_profile_->ForceIncognito(true);
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Usually the signin Profile and the main Profile are separate, but since
10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // the signin Profile is an OTR Profile then for this test it suffices to
106424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // attach it to the main Profile.
107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    profile_->SetOffTheRecordProfile(scoped_ptr<Profile>(signin_profile_));
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    signin_profile_->SetOriginalProfile(profile_);
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ASSERT_EQ(signin_profile_, chromeos::ProfileHelper::GetSigninProfile());
110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    chrome::RegisterLocalState(prefs_.registry());
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Set up a policy map for testing.
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    policy_map_.Set("HomepageLocation",
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                    POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                    base::Value::CreateStringValue("http://chromium.org"),
11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                    NULL);
11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    expected_bundle_.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        .CopyFrom(policy_map_);
12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Create fake policy blobs to deliver to the client.
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    em::DeviceRegisterResponse* register_response =
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        register_blob_.mutable_register_response();
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    register_response->set_device_management_token("dmtoken123");
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    em::CloudPolicySettings policy_proto;
127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    policy_proto.mutable_homepagelocation()->set_value("http://chromium.org");
128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ASSERT_TRUE(
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        policy_proto.SerializeToString(policy_data_.mutable_policy_value()));
130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    policy_data_.set_policy_type(dm_protocol::kChromeUserPolicyType);
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    policy_data_.set_request_token("dmtoken123");
132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    policy_data_.set_device_id("id987");
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    em::PolicyFetchResponse* policy_response =
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        policy_blob_.mutable_policy_response()->add_response();
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ASSERT_TRUE(policy_data_.SerializeToString(
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        policy_response->mutable_policy_data()));
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _))
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        .Times(AnyNumber());
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (token_forwarder_)
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      token_forwarder_->Shutdown();
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (manager_) {
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      manager_->RemoveObserver(&observer_);
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      manager_->Shutdown();
148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    signin_profile_ = NULL;
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    profile_ = NULL;
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    profile_manager_->DeleteTestingProfile(kSigninProfile);
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    profile_manager_->DeleteTestingProfile(chrome::kInitialProfile);
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void CreateManager(bool wait_for_fetch, int fetch_timeout) {
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    store_ = new MockCloudPolicyStore();
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    external_data_manager_ = new MockCloudExternalDataManager;
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    external_data_manager_->SetPolicyStore(store_);
159a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    EXPECT_CALL(*store_, Load());
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    manager_.reset(new UserCloudPolicyManagerChromeOS(
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        scoped_ptr<CloudPolicyStore>(store_),
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        scoped_ptr<CloudExternalDataManager>(external_data_manager_),
163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        base::FilePath(),
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        wait_for_fetch,
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        base::TimeDelta::FromSeconds(fetch_timeout),
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        task_runner_,
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        task_runner_,
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        task_runner_));
169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    manager_->Init(&schema_registry_);
17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    manager_->AddObserver(&observer_);
17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    manager_->Connect(&prefs_, &device_management_service_, NULL,
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      USER_AFFILIATION_NONE);
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Mock::VerifyAndClearExpectations(store_);
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_FALSE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete());
176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!wait_for_fetch) {
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      // Create the UserCloudPolicyTokenForwarder, which fetches the access
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      // token using the OAuth2PolicyFetcher and forwards it to the
180a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      // UserCloudPolicyManagerChromeOS. This service is automatically created
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      // for regular Profiles but not for testing Profiles.
18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ProfileOAuth2TokenService* token_service =
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ASSERT_TRUE(token_service);
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      SigninManagerBase* signin_manager =
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          SigninManagerFactory::GetForProfile(profile_);
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ASSERT_TRUE(signin_manager);
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      token_forwarder_.reset(
18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          new UserCloudPolicyTokenForwarder(manager_.get(), token_service,
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                            signin_manager));
191a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
192a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
194a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Expects a pending URLFetcher for the |expected_url|, and returns it with
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // prepared to deliver a response to its delegate.
19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  net::TestURLFetcher* PrepareOAuthFetcher(const GURL& expected_url) {
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0);
198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_TRUE(fetcher);
199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (!fetcher)
200424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      return NULL;
201424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_TRUE(fetcher->delegate());
202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_TRUE(StartsWithASCII(fetcher->GetOriginalURL().spec(),
203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                expected_url.spec(),
204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                true));
205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    fetcher->set_url(fetcher->GetOriginalURL());
206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    fetcher->set_response_code(200);
207424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    fetcher->set_status(net::URLRequestStatus());
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return fetcher;
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
210424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
211424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Issues the OAuth2 tokens and returns the device management register job
212424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // if the flow succeeded.
213a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  MockDeviceManagementJob* IssueOAuthToken(bool has_request_token) {
21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_FALSE(manager_->core()->client()->is_registered());
21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Issuing this token triggers the callback of the OAuth2PolicyFetcher,
21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // which triggers the registration request.
21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    MockDeviceManagementJob* register_request = NULL;
21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_CALL(device_management_service_,
22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION, _))
22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        .WillOnce(device_management_service_.CreateAsyncJob(&register_request));
22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
223a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (!has_request_token) {
224a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
225a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      net::TestURLFetcher* fetcher = NULL;
226a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
227a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      // Issue the oauth_token cookie first.
228a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      fetcher = PrepareOAuthFetcher(gaia_urls->client_login_to_oauth2_url());
229a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      if (!fetcher)
230a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        return NULL;
23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      net::ResponseCookies cookies;
23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      cookies.push_back(kOAuthTokenCookie);
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      fetcher->set_cookies(cookies);
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      fetcher->delegate()->OnURLFetchComplete(fetcher);
23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      // Issue the refresh token.
237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      fetcher = PrepareOAuthFetcher(gaia_urls->oauth2_token_url());
23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (!fetcher)
23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        return NULL;
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      fetcher->SetResponseString(kOAuth2TokenPairData);
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      fetcher->delegate()->OnURLFetchComplete(fetcher);
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Issue the access token.
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      fetcher = PrepareOAuthFetcher(gaia_urls->oauth2_token_url());
24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (!fetcher)
246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        return NULL;
24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      fetcher->SetResponseString(kOAuth2AccessTokenData);
248424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      fetcher->delegate()->OnURLFetchComplete(fetcher);
2492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    } else {
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Since the refresh token is available, OAuth2TokenService was used
2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // to request the access token and not UserCloudPolicyTokenForwarder.
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Issue the access token with the former.
25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      FakeProfileOAuth2TokenService* token_service =
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        static_cast<FakeProfileOAuth2TokenService*>(
25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            ProfileOAuth2TokenServiceFactory::GetForProfile(profile_));
25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      EXPECT_TRUE(token_service);
25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      OAuth2TokenService::ScopeSet scopes;
25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      scopes.insert(GaiaConstants::kDeviceManagementServiceOAuth);
25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      scopes.insert(GaiaConstants::kOAuthWrapBridgeUserInfoScope);
260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      token_service->IssueTokenForScope(
261424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          scopes, "5678",
2622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch          base::Time::Now() + base::TimeDelta::FromSeconds(3600));
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(register_request);
26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_FALSE(manager_->core()->client()->is_registered());
26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Mock::VerifyAndClearExpectations(&device_management_service_);
26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _))
27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        .Times(AnyNumber());
27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return register_request;
27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Expects a policy fetch request to be issued after invoking |trigger_fetch|.
276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // This method replies to that fetch request and verifies that the manager
2772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // handled the response.
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void FetchPolicy(const base::Closure& trigger_fetch) {
2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    MockDeviceManagementJob* policy_request = NULL;
280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_CALL(device_management_service_,
281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH, _))
282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        .WillOnce(device_management_service_.CreateAsyncJob(&policy_request));
28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    trigger_fetch.Run();
28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ASSERT_TRUE(policy_request);
28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete());
28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_TRUE(manager_->core()->client()->is_registered());
28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Mock::VerifyAndClearExpectations(&device_management_service_);
28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _))
290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        .Times(AnyNumber());
2912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Send the initial policy back. This completes the initialization flow.
2937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_CALL(*store_, Store(_));
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    policy_request->SendResponse(DM_STATUS_SUCCESS, policy_blob_);
29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Mock::VerifyAndClearExpectations(store_);
296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Notifying that the store is has cached the fetched policy completes the
29890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // process, and initializes the manager.
29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    store_->policy_map_.CopyFrom(policy_map_);
301    store_->NotifyStoreLoaded();
302    EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
303    Mock::VerifyAndClearExpectations(&observer_);
304    EXPECT_TRUE(manager_->policies().Equals(expected_bundle_));
305  }
306
307  // Required by the refresh scheduler that's created by the manager and
308  // for the cleanup of URLRequestContextGetter in the |signin_profile_|.
309  content::TestBrowserThreadBundle thread_bundle_;
310
311  // Convenience policy objects.
312  em::PolicyData policy_data_;
313  em::DeviceManagementResponse register_blob_;
314  em::DeviceManagementResponse policy_blob_;
315  PolicyMap policy_map_;
316  PolicyBundle expected_bundle_;
317
318  // Policy infrastructure.
319  net::TestURLFetcherFactory test_url_fetcher_factory_;
320  TestingPrefServiceSimple prefs_;
321  MockConfigurationPolicyObserver observer_;
322  MockDeviceManagementService device_management_service_;
323  MockCloudPolicyStore* store_;  // Not owned.
324  MockCloudExternalDataManager* external_data_manager_;  // Not owned.
325  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
326  SchemaRegistry schema_registry_;
327  scoped_ptr<UserCloudPolicyManagerChromeOS> manager_;
328  scoped_ptr<UserCloudPolicyTokenForwarder> token_forwarder_;
329
330  // Required by ProfileHelper to get the signin Profile context.
331  scoped_ptr<TestingProfileManager> profile_manager_;
332  TestingProfile* profile_;
333  TestingProfile* signin_profile_;
334
335  static const char kSigninProfile[];
336
337 private:
338  DISALLOW_COPY_AND_ASSIGN(UserCloudPolicyManagerChromeOSTest);
339};
340
341const char UserCloudPolicyManagerChromeOSTest::kSigninProfile[] =
342    "signin_profile";
343
344TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFirstFetch) {
345  // Tests the initialization of a manager whose Profile is waiting for the
346  // initial fetch, when the policy cache is empty.
347  ASSERT_NO_FATAL_FAILURE(CreateManager(true, 1000));
348
349  // Initialize the CloudPolicyService without any stored data.
350  EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete());
351  store_->NotifyStoreLoaded();
352  EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete());
353  EXPECT_FALSE(manager_->core()->client()->is_registered());
354
355  // This starts the OAuth2 policy token fetcher using the signin Profile.
356  // The manager will then issue the registration request.
357  MockDeviceManagementJob* register_request = IssueOAuthToken(false);
358  ASSERT_TRUE(register_request);
359
360  // Reply with a valid registration response. This triggers the initial policy
361  // fetch.
362  FetchPolicy(base::Bind(&MockDeviceManagementJob::SendResponse,
363                         base::Unretained(register_request),
364                         DM_STATUS_SUCCESS, register_blob_));
365}
366
367TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingRefreshFetch) {
368  // Tests the initialization of a manager whose Profile is waiting for the
369  // initial fetch, when a previously cached policy and DMToken already exist.
370  ASSERT_NO_FATAL_FAILURE(CreateManager(true, 1000));
371
372  // Set the initially cached data and initialize the CloudPolicyService.
373  // The initial policy fetch is issued using the cached DMToken.
374  store_->policy_.reset(new em::PolicyData(policy_data_));
375  FetchPolicy(base::Bind(&MockCloudPolicyStore::NotifyStoreLoaded,
376                         base::Unretained(store_)));
377}
378
379TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchStoreError) {
380  // Tests the initialization of a manager whose Profile is waiting for the
381  // initial fetch, when the initial store load fails.
382  ASSERT_NO_FATAL_FAILURE(CreateManager(true, 1000));
383
384  // Initialize the CloudPolicyService without any stored data.
385  EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete());
386  store_->NotifyStoreError();
387  EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete());
388  EXPECT_FALSE(manager_->core()->client()->is_registered());
389
390  // This starts the OAuth2 policy token fetcher using the signin Profile.
391  // The manager will then issue the registration request.
392  MockDeviceManagementJob* register_request = IssueOAuthToken(false);
393  ASSERT_TRUE(register_request);
394
395  // Reply with a valid registration response. This triggers the initial policy
396  // fetch.
397  FetchPolicy(base::Bind(&MockDeviceManagementJob::SendResponse,
398                         base::Unretained(register_request),
399                         DM_STATUS_SUCCESS, register_blob_));
400}
401
402TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchOAuthError) {
403  // Tests the initialization of a manager whose Profile is waiting for the
404  // initial fetch, when the OAuth2 token fetch fails.
405  ASSERT_NO_FATAL_FAILURE(CreateManager(true, 1000));
406
407  // Initialize the CloudPolicyService without any stored data.
408  EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete());
409  store_->NotifyStoreLoaded();
410  EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete());
411  EXPECT_FALSE(manager_->core()->client()->is_registered());
412
413  // This starts the OAuth2 policy token fetcher using the signin Profile.
414  // The manager will initialize with no policy after the token fetcher fails.
415  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
416
417  // The PolicyOAuth2TokenFetcher posts delayed retries on some errors. This
418  // data will make it fail immediately.
419  net::TestURLFetcher* fetcher = PrepareOAuthFetcher(
420      GaiaUrls::GetInstance()->client_login_to_oauth2_url());
421  ASSERT_TRUE(fetcher);
422  fetcher->set_response_code(400);
423  fetcher->SetResponseString("Error=BadAuthentication");
424  EXPECT_FALSE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
425  fetcher->delegate()->OnURLFetchComplete(fetcher);
426  EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
427  EXPECT_TRUE(PolicyBundle().Equals(manager_->policies()));
428  Mock::VerifyAndClearExpectations(&observer_);
429}
430
431TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchRegisterError) {
432  // Tests the initialization of a manager whose Profile is waiting for the
433  // initial fetch, when the device management registration fails.
434  ASSERT_NO_FATAL_FAILURE(CreateManager(true, 1000));
435
436  // Initialize the CloudPolicyService without any stored data.
437  EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete());
438  store_->NotifyStoreError();
439  EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete());
440  EXPECT_FALSE(manager_->core()->client()->is_registered());
441
442  // This starts the OAuth2 policy token fetcher using the signin Profile.
443  // The manager will then issue the registration request.
444  MockDeviceManagementJob* register_request = IssueOAuthToken(false);
445  ASSERT_TRUE(register_request);
446
447  // Now make it fail.
448  EXPECT_FALSE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
449  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
450  register_request->SendResponse(DM_STATUS_TEMPORARY_UNAVAILABLE,
451                                 em::DeviceManagementResponse());
452  EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
453  EXPECT_TRUE(PolicyBundle().Equals(manager_->policies()));
454  Mock::VerifyAndClearExpectations(&observer_);
455}
456
457TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchPolicyFetchError) {
458  // Tests the initialization of a manager whose Profile is waiting for the
459  // initial fetch, when the policy fetch request fails.
460  ASSERT_NO_FATAL_FAILURE(CreateManager(true, 1000));
461
462  // Initialize the CloudPolicyService without any stored data.
463  EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete());
464  store_->NotifyStoreLoaded();
465  EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete());
466  EXPECT_FALSE(manager_->core()->client()->is_registered());
467
468  // This starts the OAuth2 policy token fetcher using the signin Profile.
469  // The manager will then issue the registration request.
470  MockDeviceManagementJob* register_request = IssueOAuthToken(false);
471  ASSERT_TRUE(register_request);
472
473  // Reply with a valid registration response. This triggers the initial policy
474  // fetch.
475  MockDeviceManagementJob* policy_request = NULL;
476  EXPECT_CALL(device_management_service_,
477              CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH, _))
478      .WillOnce(device_management_service_.CreateAsyncJob(&policy_request));
479  register_request->SendResponse(DM_STATUS_SUCCESS, register_blob_);
480  Mock::VerifyAndClearExpectations(&device_management_service_);
481  ASSERT_TRUE(policy_request);
482  EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete());
483  EXPECT_TRUE(manager_->core()->client()->is_registered());
484
485  // Make the policy fetch fail. The observer gets 2 notifications: one from the
486  // RefreshPolicies callback, and another from the OnClientError callback.
487  // A single notification suffices for this edge case, but this behavior is
488  // also correct and makes the implementation simpler.
489  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get())).Times(AtLeast(1));
490  EXPECT_FALSE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
491  policy_request->SendResponse(DM_STATUS_TEMPORARY_UNAVAILABLE,
492                               em::DeviceManagementResponse());
493  Mock::VerifyAndClearExpectations(&observer_);
494  EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
495  EXPECT_TRUE(PolicyBundle().Equals(manager_->policies()));
496}
497
498TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchTimeout) {
499  // The blocking fetch should be abandoned after the timeout.
500  ASSERT_NO_FATAL_FAILURE(CreateManager(true, 0));
501
502  // Initialize the CloudPolicyService without any stored data.
503  EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete());
504  store_->NotifyStoreLoaded();
505  EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete());
506  EXPECT_FALSE(manager_->core()->client()->is_registered());
507
508  // Running the message loop should trigger the timeout.
509  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get())).Times(AtLeast(1));
510  EXPECT_FALSE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
511  base::RunLoop().RunUntilIdle();
512  Mock::VerifyAndClearExpectations(&observer_);
513  EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
514  EXPECT_TRUE(PolicyBundle().Equals(manager_->policies()));
515}
516
517
518TEST_F(UserCloudPolicyManagerChromeOSTest, NonBlockingFirstFetch) {
519  // Tests the first policy fetch request by a Profile that isn't managed.
520  ASSERT_NO_FATAL_FAILURE(CreateManager(false, 1000));
521
522  // Initialize the CloudPolicyService without any stored data. Since the
523  // manager is not waiting for the initial fetch, it will become initialized
524  // once the store is ready.
525  EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete());
526  EXPECT_FALSE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
527  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
528  store_->NotifyStoreLoaded();
529  Mock::VerifyAndClearExpectations(&observer_);
530  EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete());
531  EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
532  EXPECT_FALSE(manager_->core()->client()->is_registered());
533
534  // The manager is waiting for the refresh token, and hasn't started any
535  // fetchers.
536  EXPECT_FALSE(test_url_fetcher_factory_.GetFetcherByID(0));
537
538  // Set a fake refresh token at the OAuth2TokenService.
539  FakeProfileOAuth2TokenService* token_service =
540    static_cast<FakeProfileOAuth2TokenService*>(
541        ProfileOAuth2TokenServiceFactory::GetForProfile(profile_));
542  ASSERT_TRUE(token_service);
543  SigninManagerBase* signin_manager =
544      SigninManagerFactory::GetForProfile(profile_);
545  ASSERT_TRUE(signin_manager);
546  const std::string& account_id = signin_manager->GetAuthenticatedAccountId();
547  EXPECT_FALSE(token_service->RefreshTokenIsAvailable(account_id));
548  token_service->UpdateCredentials(account_id, "refresh_token");
549  EXPECT_TRUE(token_service->RefreshTokenIsAvailable(account_id));
550
551  // That should have notified the manager, which now issues the request for the
552  // policy oauth token.
553  MockDeviceManagementJob* register_request = IssueOAuthToken(true);
554  ASSERT_TRUE(register_request);
555  register_request->SendResponse(DM_STATUS_SUCCESS, register_blob_);
556
557  // The refresh scheduler takes care of the initial fetch for unmanaged users.
558  // Running the task runner issues the initial fetch.
559  FetchPolicy(
560      base::Bind(&base::TestSimpleTaskRunner::RunUntilIdle, task_runner_));
561}
562
563TEST_F(UserCloudPolicyManagerChromeOSTest, NonBlockingRefreshFetch) {
564  // Tests a non-blocking initial policy fetch for a Profile that already has
565  // a cached DMToken.
566  ASSERT_NO_FATAL_FAILURE(CreateManager(false, 1000));
567
568  // Set the initially cached data and initialize the CloudPolicyService.
569  // The initial policy fetch is issued using the cached DMToken.
570  EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete());
571  EXPECT_FALSE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
572  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
573  store_->policy_.reset(new em::PolicyData(policy_data_));
574  store_->NotifyStoreLoaded();
575  Mock::VerifyAndClearExpectations(&observer_);
576  EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete());
577  EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
578  EXPECT_TRUE(manager_->core()->client()->is_registered());
579
580  // The refresh scheduler takes care of the initial fetch for unmanaged users.
581  // Running the task runner issues the initial fetch.
582  FetchPolicy(
583      base::Bind(&base::TestSimpleTaskRunner::RunUntilIdle, task_runner_));
584}
585
586}  // namespace policy
587