user_cloud_policy_manager_chromeos_unittest.cc revision a3f7b4e666c476898878fa745f637129375cd889
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind_helpers.h" 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/callback.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/testing_pref_service.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/run_loop.h" 165e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/profiles/profile_helper.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/policy/cloud/cloud_policy_constants.h" 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/policy/cloud/cloud_policy_service.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/policy/cloud/mock_cloud_policy_store.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/policy/cloud/mock_device_management_service.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/policy/cloud/resource_cache.h" 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/policy/external_data_fetcher.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/policy/mock_configuration_policy_provider.h" 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/browser_prefs.h" 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/prefs/pref_service_syncable.h" 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/signin/token_service.h" 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/signin/token_service_factory.h" 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/chrome_constants.h" 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/base/testing_browser_process.h" 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/base/testing_profile.h" 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/base/testing_profile_manager.h" 36a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "content/public/test/test_browser_thread_bundle.h" 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "google_apis/gaia/gaia_auth_consumer.h" 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "google_apis/gaia/gaia_urls.h" 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/url_request/test_url_fetcher_factory.h" 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h" 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/url_request/url_request_status.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "policy/policy_constants.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace em = enterprise_management; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::AnyNumber; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::AtLeast; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Mock; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy { 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kOAuthTokenCookie[] = "oauth_token=1234"; 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kOAuth2TokenPairData[] = 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "{" 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " \"refresh_token\": \"1234\"," 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " \"access_token\": \"5678\"," 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " \"expires_in\": 3600" 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "}"; 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kOAuth2AccessTokenData[] = 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "{" 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " \"access_token\": \"5678\"," 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " \"expires_in\": 3600" 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "}"; 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class UserCloudPolicyManagerChromeOSTest : public testing::Test { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UserCloudPolicyManagerChromeOSTest() 78a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch : store_(NULL), 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile_(NULL), 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) signin_profile_(NULL) {} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The initialization path that blocks on the initial policy fetch requires 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // a signin Profile to use its URLRequestContext. 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile_manager_.reset( 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new TestingProfileManager(TestingBrowserProcess::GetGlobal())); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(profile_manager_->SetUp()); 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile_ = profile_manager_->CreateTestingProfile( 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch chrome::kInitialProfile, scoped_ptr<PrefServiceSyncable>(), 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UTF8ToUTF16("testing_profile"), 0); 91a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch signin_profile_ = profile_manager_->CreateTestingProfile(kSigninProfile); 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) signin_profile_->set_incognito(true); 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Usually the signin Profile and the main Profile are separate, but since 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the signin Profile is an OTR Profile then for this test it suffices to 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // attach it to the main Profile. 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile_->SetOffTheRecordProfile(signin_profile_); 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) signin_profile_->SetOriginalProfile(profile_); 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(signin_profile_, chromeos::ProfileHelper::GetSigninProfile()); 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::RegisterLocalState(prefs_.registry()); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up a policy map for testing. 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) policy_map_.Set("HomepageLocation", 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, 1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Value::CreateStringValue("http://chromium.org"), 1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NULL); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_bundle_.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .CopyFrom(policy_map_); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Create fake policy blobs to deliver to the client. 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) em::DeviceRegisterResponse* register_response = 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) register_blob_.mutable_register_response(); 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) register_response->set_device_management_token("dmtoken123"); 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) em::CloudPolicySettings policy_proto; 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) policy_proto.mutable_homepagelocation()->set_value("http://chromium.org"); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE( 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) policy_proto.SerializeToString(policy_data_.mutable_policy_value())); 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) policy_data_.set_policy_type(dm_protocol::kChromeUserPolicyType); 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) policy_data_.set_request_token("dmtoken123"); 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) policy_data_.set_device_id("id987"); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) em::PolicyFetchResponse* policy_response = 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policy_blob_.mutable_policy_response()->add_response(); 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(policy_data_.SerializeToString( 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policy_response->mutable_policy_data())); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _)) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(AnyNumber()); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() OVERRIDE { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (manager_) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_->RemoveObserver(&observer_); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_->Shutdown(); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 136a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch signin_profile_ = NULL; 137a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch profile_ = NULL; 138a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch profile_manager_->DeleteTestingProfile(kSigninProfile); 139a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch profile_manager_->DeleteTestingProfile(chrome::kInitialProfile); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void CreateManager(bool wait_for_fetch) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store_ = new MockCloudPolicyStore(); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*store_, Load()); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manager_.reset(new UserCloudPolicyManagerChromeOS( 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<CloudPolicyStore>(store_), 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceCache>(), 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) wait_for_fetch)); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_->Init(); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_->AddObserver(&observer_); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manager_->Connect(&prefs_, &device_management_service_, NULL, 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) USER_AFFILIATION_NONE); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mock::VerifyAndClearExpectations(store_); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!wait_for_fetch) { 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Create the UserCloudPolicyTokenForwarder, which forwards the refresh 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // token from the TokenService to the UserCloudPolicyManagerChromeOS. 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This service is automatically created for regular Profiles but not for 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // testing Profiles. 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TokenService* token_service = 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TokenServiceFactory::GetForProfile(profile_); 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(token_service); 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_forwarder_.reset( 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new UserCloudPolicyTokenForwarder(manager_.get(), token_service)); 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Expects a pending URLFetcher for the |expected_url|, and returns it with 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // prepared to deliver a response to its delegate. 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::TestURLFetcher* PrepareOAuthFetcher(const std::string& expected_url) { 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0); 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(fetcher); 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!fetcher) 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(fetcher->delegate()); 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(StartsWithASCII(fetcher->GetOriginalURL().spec(), 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_url, 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) true)); 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher->set_url(fetcher->GetOriginalURL()); 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher->set_response_code(200); 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher->set_status(net::URLRequestStatus()); 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return fetcher; 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Issues the OAuth2 tokens and returns the device management register job 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // if the flow succeeded. 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockDeviceManagementJob* IssueOAuthToken(bool has_request_token) { 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->core()->client()->is_registered()); 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GaiaUrls* gaia_urls = GaiaUrls::GetInstance(); 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::TestURLFetcher* fetcher = NULL; 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!has_request_token) { 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Issue the oauth_token cookie first. 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher = PrepareOAuthFetcher(gaia_urls->client_login_to_oauth2_url()); 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!fetcher) 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::ResponseCookies cookies; 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cookies.push_back(kOAuthTokenCookie); 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher->set_cookies(cookies); 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher->delegate()->OnURLFetchComplete(fetcher); 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Issue the refresh token. 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher = PrepareOAuthFetcher(gaia_urls->oauth2_token_url()); 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!fetcher) 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher->SetResponseString(kOAuth2TokenPairData); 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher->delegate()->OnURLFetchComplete(fetcher); 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Issue the access token. 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher = PrepareOAuthFetcher(gaia_urls->oauth2_token_url()); 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!fetcher) 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher->SetResponseString(kOAuth2AccessTokenData); 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Issuing this token triggers the callback of the OAuth2PolicyFetcher, 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // which triggers the registration request. 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockDeviceManagementJob* register_request = NULL; 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(device_management_service_, 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION)) 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(device_management_service_.CreateAsyncJob(®ister_request)); 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher->delegate()->OnURLFetchComplete(fetcher); 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(register_request); 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->core()->client()->is_registered()); 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Mock::VerifyAndClearExpectations(&device_management_service_); 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _)) 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .Times(AnyNumber()); 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return register_request; 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Expects a policy fetch request to be issued after invoking |trigger_fetch|. 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This method replies to that fetch request and verifies that the manager 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // handled the response. 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void FetchPolicy(const base::Closure& trigger_fetch) { 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockDeviceManagementJob* policy_request = NULL; 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(device_management_service_, 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH)) 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(device_management_service_.CreateAsyncJob(&policy_request)); 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) trigger_fetch.Run(); 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(policy_request); 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete()); 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->core()->client()->is_registered()); 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Mock::VerifyAndClearExpectations(&device_management_service_); 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _)) 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .Times(AnyNumber()); 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Send the initial policy back. This completes the initialization flow. 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*store_, Store(_)); 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) policy_request->SendResponse(DM_STATUS_SUCCESS, policy_blob_); 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Mock::VerifyAndClearExpectations(store_); 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Notifying that the store is has cached the fetched policy completes the 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // process, and initializes the manager. 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get())); 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) store_->policy_map_.CopyFrom(policy_map_); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store_->NotifyStoreLoaded(); 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mock::VerifyAndClearExpectations(&observer_); 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->policies().Equals(expected_bundle_)); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 268a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch // Required by the refresh scheduler that's created by the manager and 269a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch // for the cleanup of URLRequestContextGetter in the |signin_profile_|. 270a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch content::TestBrowserThreadBundle thread_bundle_; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Convenience policy objects. 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) em::PolicyData policy_data_; 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) em::DeviceManagementResponse register_blob_; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) em::DeviceManagementResponse policy_blob_; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyMap policy_map_; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyBundle expected_bundle_; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Policy infrastructure. 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::TestURLFetcherFactory test_url_fetcher_factory_; 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestingPrefServiceSimple prefs_; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockConfigurationPolicyObserver observer_; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockDeviceManagementService device_management_service_; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockCloudPolicyStore* store_; 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UserCloudPolicyManagerChromeOS> manager_; 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<UserCloudPolicyTokenForwarder> token_forwarder_; 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Required by ProfileHelper to get the signin Profile context. 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<TestingProfileManager> profile_manager_; 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestingProfile* profile_; 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestingProfile* signin_profile_; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 293a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch static const char kSigninProfile[]; 294a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(UserCloudPolicyManagerChromeOSTest); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 299a3f7b4e666c476898878fa745f637129375cd889Ben Murdochconst char UserCloudPolicyManagerChromeOSTest::kSigninProfile[] = 300a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch "signin_profile"; 301a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFirstFetch) { 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Tests the initialization of a manager whose Profile is waiting for the 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // initial fetch, when the policy cache is empty. 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_NO_FATAL_FAILURE(CreateManager(true)); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Initialize the CloudPolicyService without any stored data. 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) store_->NotifyStoreLoaded(); 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete()); 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->core()->client()->is_registered()); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This starts the OAuth2 policy token fetcher using the signin Profile. 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The manager will then issue the registration request. 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockDeviceManagementJob* register_request = IssueOAuthToken(false); 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(register_request); 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Reply with a valid registration response. This triggers the initial policy 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // fetch. 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FetchPolicy(base::Bind(&MockDeviceManagementJob::SendResponse, 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(register_request), 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DM_STATUS_SUCCESS, register_blob_)); 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingRefreshFetch) { 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Tests the initialization of a manager whose Profile is waiting for the 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // initial fetch, when a previously cached policy and DMToken already exist. 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_NO_FATAL_FAILURE(CreateManager(true)); 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Set the initially cached data and initialize the CloudPolicyService. 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The initial policy fetch is issued using the cached DMToken. 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) store_->policy_.reset(new em::PolicyData(policy_data_)); 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FetchPolicy(base::Bind(&MockCloudPolicyStore::NotifyStoreLoaded, 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(store_))); 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchStoreError) { 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Tests the initialization of a manager whose Profile is waiting for the 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // initial fetch, when the initial store load fails. 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_NO_FATAL_FAILURE(CreateManager(true)); 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Initialize the CloudPolicyService without any stored data. 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) store_->NotifyStoreError(); 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete()); 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->core()->client()->is_registered()); 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This starts the OAuth2 policy token fetcher using the signin Profile. 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The manager will then issue the registration request. 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockDeviceManagementJob* register_request = IssueOAuthToken(false); 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(register_request); 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Reply with a valid registration response. This triggers the initial policy 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // fetch. 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FetchPolicy(base::Bind(&MockDeviceManagementJob::SendResponse, 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(register_request), 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DM_STATUS_SUCCESS, register_blob_)); 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchOAuthError) { 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Tests the initialization of a manager whose Profile is waiting for the 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // initial fetch, when the OAuth2 token fetch fails. 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_NO_FATAL_FAILURE(CreateManager(true)); 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Initialize the CloudPolicyService without any stored data. 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) store_->NotifyStoreLoaded(); 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete()); 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->core()->client()->is_registered()); 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This starts the OAuth2 policy token fetcher using the signin Profile. 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The manager will initialize with no policy after the token fetcher fails. 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get())); 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The PolicyOAuth2TokenFetcher posts delayed retries on some errors. This 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // data will make it fail immediately. 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::TestURLFetcher* fetcher = PrepareOAuthFetcher( 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GaiaUrls::GetInstance()->client_login_to_oauth2_url()); 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(fetcher); 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher->set_response_code(400); 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher->SetResponseString("Error=BadAuthentication"); 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fetcher->delegate()->OnURLFetchComplete(fetcher); 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(PolicyBundle().Equals(manager_->policies())); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mock::VerifyAndClearExpectations(&observer_); 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchRegisterError) { 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Tests the initialization of a manager whose Profile is waiting for the 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // initial fetch, when the device management registration fails. 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_NO_FATAL_FAILURE(CreateManager(true)); 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Initialize the CloudPolicyService without any stored data. 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) store_->NotifyStoreError(); 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete()); 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->core()->client()->is_registered()); 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This starts the OAuth2 policy token fetcher using the signin Profile. 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The manager will then issue the registration request. 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockDeviceManagementJob* register_request = IssueOAuthToken(false); 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(register_request); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Now make it fail. 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get())); 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) register_request->SendResponse(DM_STATUS_TEMPORARY_UNAVAILABLE, 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) em::DeviceManagementResponse()); 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(PolicyBundle().Equals(manager_->policies())); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mock::VerifyAndClearExpectations(&observer_); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchPolicyFetchError) { 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Tests the initialization of a manager whose Profile is waiting for the 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // initial fetch, when the policy fetch request fails. 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_NO_FATAL_FAILURE(CreateManager(true)); 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Initialize the CloudPolicyService without any stored data. 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) store_->NotifyStoreLoaded(); 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete()); 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->core()->client()->is_registered()); 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This starts the OAuth2 policy token fetcher using the signin Profile. 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The manager will then issue the registration request. 428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockDeviceManagementJob* register_request = IssueOAuthToken(false); 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(register_request); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Reply with a valid registration response. This triggers the initial policy 432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // fetch. 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockDeviceManagementJob* policy_request = NULL; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(device_management_service_, 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH)) 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(device_management_service_.CreateAsyncJob(&policy_request)); 437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) register_request->SendResponse(DM_STATUS_SUCCESS, register_blob_); 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Mock::VerifyAndClearExpectations(&device_management_service_); 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(policy_request); 440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete()); 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->core()->client()->is_registered()); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make the policy fetch fail. The observer gets 2 notifications: one from the 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // RefreshPolicies callback, and another from the OnClientError callback. 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // A single notification suffices for this edge case, but this behavior is 446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // also correct and makes the implementation simpler. 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get())).Times(AtLeast(1)); 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) policy_request->SendResponse(DM_STATUS_TEMPORARY_UNAVAILABLE, 450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) em::DeviceManagementResponse()); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mock::VerifyAndClearExpectations(&observer_); 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(PolicyBundle().Equals(manager_->policies())); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(UserCloudPolicyManagerChromeOSTest, NonBlockingFirstFetch) { 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Tests the first policy fetch request by a Profile that isn't managed. 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_NO_FATAL_FAILURE(CreateManager(false)); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Initialize the CloudPolicyService without any stored data. Since the 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // manager is not waiting for the initial fetch, it will become initialized 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // once the store is ready. 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); 464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get())); 466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) store_->NotifyStoreLoaded(); 467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Mock::VerifyAndClearExpectations(&observer_); 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete()); 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); 470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->core()->client()->is_registered()); 471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The manager is waiting for the refresh token, and hasn't started any 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // fetchers. 474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(test_url_fetcher_factory_.GetFetcherByID(0)); 475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Set a fake refresh token at the TokenService. 477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); 478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(token_service); 479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GaiaAuthConsumer::ClientOAuthResult tokens("refresh", "access", 3600); 480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(token_service->HasOAuthLoginToken()); 481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_service->UpdateCredentialsWithOAuth2(tokens); 482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(token_service->HasOAuthLoginToken()); 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // That should have notified the manager, which now issues the request for the 485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // policy oauth token. 486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockDeviceManagementJob* register_request = IssueOAuthToken(true); 487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(register_request); 488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) register_request->SendResponse(DM_STATUS_SUCCESS, register_blob_); 489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The refresh scheduler takes care of the initial fetch for unmanaged users. 491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // It posts a delayed task with 0ms delay in this case, so spinning the loop 492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // issues the initial fetch. 493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::RunLoop loop; 494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FetchPolicy( 495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&base::RunLoop::RunUntilIdle, base::Unretained(&loop))); 496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(UserCloudPolicyManagerChromeOSTest, NonBlockingRefreshFetch) { 499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Tests a non-blocking initial policy fetch for a Profile that already has 500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // a cached DMToken. 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_NO_FATAL_FAILURE(CreateManager(false)); 502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Set the initially cached data and initialize the CloudPolicyService. 504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The initial policy fetch is issued using the cached DMToken. 505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); 506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); 507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get())); 508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) store_->policy_.reset(new em::PolicyData(policy_data_)); 509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) store_->NotifyStoreLoaded(); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mock::VerifyAndClearExpectations(&observer_); 511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete()); 512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); 513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(manager_->core()->client()->is_registered()); 514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The refresh scheduler takes care of the initial fetch for unmanaged users. 516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // It posts a delayed task with 0ms delay in this case, so spinning the loop 517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // issues the initial fetch. 518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::RunLoop loop; 519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FetchPolicy( 520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&base::RunLoop::RunUntilIdle, base::Unretained(&loop))); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace policy 524