This source file includes following definitions.
- GetURLRequestContext
 
- GetNetworkTaskRunner
 
- core_
 
- SetUp
 
- TearDown
 
- RunUntilIdle
 
- Connect
 
- LoadStore
 
- InitializeRegistry
 
- PopulateCache
 
- CreateResponse
 
- CreateSerializedResponse
 
- CreateTestSchema
 
- TEST_F
 
- TEST_F
 
- TEST_F
 
- TEST_F
 
- TEST_F
 
- TEST_F
 
- TEST_F
 
- TEST_F
 
- TEST_F
 
#include "components/policy/core/common/cloud/component_cloud_policy_service.h"
#include <map>
#include <string>
#include "base/callback.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/values.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
#include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
#include "components/policy/core/common/cloud/policy_builder.h"
#include "components/policy/core/common/cloud/resource_cache.h"
#include "components/policy/core/common/external_data_fetcher.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_types.h"
#include "components/policy/core/common/schema.h"
#include "components/policy/core/common/schema_map.h"
#include "crypto/sha2.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "policy/proto/chrome_extension_policy.pb.h"
#include "policy/proto/device_management_backend.pb.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace em = enterprise_management;
using testing::Mock;
namespace policy {
namespace {
const char kTestExtension[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
const char kTestExtension2[] = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
const char kTestDownload[] = "http://example.com/getpolicy?id=123";
const char kTestPolicy[] =
    "{"
    "  \"Name\": {"
    "    \"Value\": \"disabled\""
    "  },"
    "  \"Second\": {"
    "    \"Value\": \"maybe\","
    "    \"Level\": \"Recommended\""
    "  }"
    "}";
const char kInvalidTestPolicy[] =
    "{"
    "  \"Name\": {"
    "    \"Value\": \"published\""
    "  },"
    "  \"Undeclared Name\": {"
    "    \"Value\": \"not published\""
    "  }"
    "}";
const char kTestSchema[] =
    "{"
    "  \"type\": \"object\","
    "  \"properties\": {"
    "    \"Name\": { \"type\": \"string\" },"
    "    \"Second\": { \"type\": \"string\" }"
    "  }"
    "}";
class MockComponentCloudPolicyDelegate
    : public ComponentCloudPolicyService::Delegate {
 public:
  virtual ~MockComponentCloudPolicyDelegate() {}
  MOCK_METHOD0(OnComponentCloudPolicyUpdated, void());
};
class TestURLRequestContextGetter : public net::URLRequestContextGetter {
 public:
  explicit TestURLRequestContextGetter(
      scoped_refptr<base::SingleThreadTaskRunner> task_runner)
      : task_runner_(task_runner) {}
  virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE {
    return NULL;
  }
  virtual scoped_refptr<base::SingleThreadTaskRunner>
      GetNetworkTaskRunner() const OVERRIDE {
    return task_runner_;
  }
 private:
  virtual ~TestURLRequestContextGetter() {}
  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
};
}  
class ComponentCloudPolicyServiceTest : public testing::Test {
 protected:
  ComponentCloudPolicyServiceTest()
      : client_(NULL),
        core_(PolicyNamespaceKey(GetChromeUserPolicyType(), ""),
              &store_,
              loop_.message_loop_proxy()) {}
  virtual void SetUp() OVERRIDE {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    cache_ = new ResourceCache(temp_dir_.path(), loop_.message_loop_proxy());
    request_context_ =
        new TestURLRequestContextGetter(loop_.message_loop_proxy());
    service_.reset(new ComponentCloudPolicyService(
        &delegate_,
        ®istry_,
        &core_,
        make_scoped_ptr(cache_),
        request_context_,
        loop_.message_loop_proxy(),
        loop_.message_loop_proxy()));
    builder_.policy_data().set_policy_type(
        dm_protocol::kChromeExtensionPolicyType);
    builder_.policy_data().set_settings_entity_id(kTestExtension);
    builder_.payload().set_download_url(kTestDownload);
    builder_.payload().set_secure_hash(crypto::SHA256HashString(kTestPolicy));
    expected_policy_.Set("Name", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                         base::Value::CreateStringValue("disabled"), NULL);
    expected_policy_.Set("Second", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
                         base::Value::CreateStringValue("maybe"), NULL);
  }
  virtual void TearDown() OVERRIDE {
    
    service_.reset();
    RunUntilIdle();
  }
  void RunUntilIdle() {
    base::RunLoop().RunUntilIdle();
  }
  void Connect(size_t expected_namespaces_in_client) {
    client_ = new MockCloudPolicyClient();
    client_->SetDMToken(ComponentPolicyBuilder::kFakeToken);
    EXPECT_EQ(0u, client_->namespaces_to_fetch_.size());
    core_.Connect(scoped_ptr<CloudPolicyClient>(client_));
    
    
    
    EXPECT_EQ(expected_namespaces_in_client,
              client_->namespaces_to_fetch_.size());
    
    
    
    
    
    if (!store_.has_policy())
      EXPECT_CALL(*client_, FetchPolicy());
    core_.StartRefreshScheduler();
    RunUntilIdle();
    Mock::VerifyAndClearExpectations(client_);
  }
  void LoadStore() {
    EXPECT_FALSE(store_.is_initialized());
    em::PolicyData* data = new em::PolicyData();
    data->set_username(ComponentPolicyBuilder::kFakeUsername);
    data->set_request_token(ComponentPolicyBuilder::kFakeToken);
    store_.policy_.reset(data);
    store_.NotifyStoreLoaded();
    RunUntilIdle();
    EXPECT_TRUE(store_.is_initialized());
  }
  void InitializeRegistry() {
    registry_.RegisterComponent(
        PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension),
        CreateTestSchema());
    registry_.SetReady(POLICY_DOMAIN_CHROME);
    registry_.SetReady(POLICY_DOMAIN_EXTENSIONS);
  }
  void PopulateCache() {
    EXPECT_TRUE(cache_->Store(
        "extension-policy", kTestExtension, CreateSerializedResponse()));
    EXPECT_TRUE(
        cache_->Store("extension-policy-data", kTestExtension, kTestPolicy));
    builder_.policy_data().set_settings_entity_id(kTestExtension2);
    EXPECT_TRUE(cache_->Store(
        "extension-policy", kTestExtension2, CreateSerializedResponse()));
    EXPECT_TRUE(
        cache_->Store("extension-policy-data", kTestExtension2, kTestPolicy));
  }
  scoped_ptr<em::PolicyFetchResponse> CreateResponse() {
    builder_.Build();
    return make_scoped_ptr(new em::PolicyFetchResponse(builder_.policy()));
  }
  std::string CreateSerializedResponse() {
    builder_.Build();
    return builder_.GetBlob();
  }
  Schema CreateTestSchema() {
    std::string error;
    Schema schema = Schema::Parse(kTestSchema, &error);
    EXPECT_TRUE(schema.valid()) << error;
    return schema;
  }
  base::MessageLoop loop_;
  base::ScopedTempDir temp_dir_;
  scoped_refptr<TestURLRequestContextGetter> request_context_;
  net::TestURLFetcherFactory fetcher_factory_;
  MockComponentCloudPolicyDelegate delegate_;
  
  
  ResourceCache* cache_;
  MockCloudPolicyClient* client_;
  MockCloudPolicyStore store_;
  CloudPolicyCore core_;
  SchemaRegistry registry_;
  scoped_ptr<ComponentCloudPolicyService> service_;
  ComponentPolicyBuilder builder_;
  PolicyMap expected_policy_;
};
TEST_F(ComponentCloudPolicyServiceTest, InitializedAtConstructionTime) {
  service_.reset();
  Connect(1u);
  LoadStore();
  InitializeRegistry();
  cache_ = new ResourceCache(temp_dir_.path(), loop_.message_loop_proxy());
  service_.reset(new ComponentCloudPolicyService(&delegate_,
                                                 ®istry_,
                                                 &core_,
                                                 make_scoped_ptr(cache_),
                                                 request_context_,
                                                 loop_.message_loop_proxy(),
                                                 loop_.message_loop_proxy()));
  EXPECT_FALSE(service_->is_initialized());
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  EXPECT_CALL(*client_, FetchPolicy());
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(&client_);
  Mock::VerifyAndClearExpectations(&delegate_);
  EXPECT_TRUE(service_->is_initialized());
  EXPECT_EQ(2u, client_->namespaces_to_fetch_.size());
  const PolicyBundle empty_bundle;
  EXPECT_TRUE(service_->policy().Equals(empty_bundle));
}
TEST_F(ComponentCloudPolicyServiceTest, InitializeStoreThenRegistry) {
  Connect(1u);
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated()).Times(0);
  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
  LoadStore();
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);
  EXPECT_FALSE(service_->is_initialized());
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  EXPECT_CALL(*client_, FetchPolicy());
  InitializeRegistry();
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);
  EXPECT_TRUE(service_->is_initialized());
  const PolicyBundle empty_bundle;
  EXPECT_TRUE(service_->policy().Equals(empty_bundle));
}
TEST_F(ComponentCloudPolicyServiceTest, InitializeRegistryThenStore) {
  Connect(1u);
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated()).Times(0);
  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
  InitializeRegistry();
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);
  EXPECT_FALSE(service_->is_initialized());
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  EXPECT_CALL(*client_, FetchPolicy());
  LoadStore();
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);
  EXPECT_TRUE(service_->is_initialized());
  EXPECT_EQ(2u, client_->namespaces_to_fetch_.size());
  const PolicyBundle empty_bundle;
  EXPECT_TRUE(service_->policy().Equals(empty_bundle));
}
TEST_F(ComponentCloudPolicyServiceTest, InitializeWithCachedPolicy) {
  PopulateCache();
  Connect(1u);
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  EXPECT_CALL(*client_, FetchPolicy());
  InitializeRegistry();
  LoadStore();
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);
  EXPECT_TRUE(service_->is_initialized());
  EXPECT_EQ(2u, client_->namespaces_to_fetch_.size());
  
  std::map<std::string, std::string> contents;
  cache_->LoadAllSubkeys("extension-policy", &contents);
  ASSERT_EQ(1u, contents.size());
  EXPECT_EQ(kTestExtension, contents.begin()->first);
  PolicyBundle expected_bundle;
  const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
  expected_bundle.Get(ns).CopyFrom(expected_policy_);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
}
TEST_F(ComponentCloudPolicyServiceTest, FetchPolicy) {
  Connect(1u);
  
  
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
  registry_.SetReady(POLICY_DOMAIN_CHROME);
  registry_.SetReady(POLICY_DOMAIN_EXTENSIONS);
  LoadStore();
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);
  EXPECT_TRUE(service_->is_initialized());
  
  EXPECT_CALL(*client_, FetchPolicy());
  registry_.RegisterComponent(
      PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension),
      CreateTestSchema());
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(client_);
  
  client_->SetPolicy(PolicyNamespaceKey(dm_protocol::kChromeExtensionPolicyType,
                                        kTestExtension),
                     *CreateResponse());
  service_->OnPolicyFetched(client_);
  RunUntilIdle();
  
  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
  ASSERT_TRUE(fetcher);
  EXPECT_EQ(GURL(kTestDownload), fetcher->GetOriginalURL());
  fetcher->set_response_code(200);
  fetcher->SetResponseString(kTestPolicy);
  fetcher->delegate()->OnURLFetchComplete(fetcher);
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(&delegate_);
  
  const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
  PolicyBundle expected_bundle;
  expected_bundle.Get(ns).CopyFrom(expected_policy_);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
}
TEST_F(ComponentCloudPolicyServiceTest, LoadAndPurgeCache) {
  Connect(1u);
  
  PopulateCache();
  registry_.RegisterComponent(
      PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension2),
      CreateTestSchema());
  InitializeRegistry();
  
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  EXPECT_CALL(*client_, FetchPolicy());
  LoadStore();
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);
  PolicyBundle expected_bundle;
  PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
  expected_bundle.Get(ns).CopyFrom(expected_policy_);
  ns.component_id = kTestExtension2;
  expected_bundle.Get(ns).CopyFrom(expected_policy_);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
  
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  registry_.UnregisterComponent(
      PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension));
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(&delegate_);
  ns.component_id = kTestExtension;
  expected_bundle.Get(ns).Clear();
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
  std::map<std::string, std::string> contents;
  cache_->LoadAllSubkeys("extension-policy", &contents);
  EXPECT_EQ(1u, contents.size());
  EXPECT_TRUE(ContainsKey(contents, kTestExtension2));
}
TEST_F(ComponentCloudPolicyServiceTest, SignInAfterStartup) {
  registry_.SetReady(POLICY_DOMAIN_CHROME);
  registry_.SetReady(POLICY_DOMAIN_EXTENSIONS);
  
  EXPECT_FALSE(store_.is_initialized());
  EXPECT_FALSE(service_->is_initialized());
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  store_.NotifyStoreLoaded();
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(&delegate_);
  EXPECT_TRUE(service_->is_initialized());
  
  registry_.RegisterComponent(
      PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension),
      CreateTestSchema());
  RunUntilIdle();
  
  Connect(2u);
  
  
  client_->SetPolicy(PolicyNamespaceKey(dm_protocol::kChromeExtensionPolicyType,
                                        kTestExtension),
                     *CreateResponse());
  service_->OnPolicyFetched(client_);
  RunUntilIdle();
  
  
  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
  EXPECT_FALSE(fetcher);
  
  
  em::PolicyData* data = new em::PolicyData();
  data->set_username(ComponentPolicyBuilder::kFakeUsername);
  data->set_request_token(ComponentPolicyBuilder::kFakeToken);
  store_.policy_.reset(data);
  store_.NotifyStoreLoaded();
  RunUntilIdle();
  
  fetcher = fetcher_factory_.GetFetcherByID(0);
  ASSERT_TRUE(fetcher);
  EXPECT_EQ(GURL(kTestDownload), fetcher->GetOriginalURL());
  fetcher->set_response_code(200);
  fetcher->SetResponseString(kTestPolicy);
  fetcher->delegate()->OnURLFetchComplete(fetcher);
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(&delegate_);
  
  PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
  PolicyBundle expected_bundle;
  expected_bundle.Get(ns).CopyFrom(expected_policy_);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
}
TEST_F(ComponentCloudPolicyServiceTest, SignOut) {
  
  PopulateCache();
  LoadStore();
  InitializeRegistry();
  
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(&delegate_);
  PolicyBundle expected_bundle;
  const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
  expected_bundle.Get(ns).CopyFrom(expected_policy_);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
  std::map<std::string, std::string> contents;
  cache_->LoadAllSubkeys("extension-policy", &contents);
  ASSERT_EQ(1u, contents.size());
  
  Connect(2u);
  
  
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  core_.Disconnect();
  store_.policy_.reset();
  store_.NotifyStoreLoaded();
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(&delegate_);
  const PolicyBundle empty_bundle;
  EXPECT_TRUE(service_->policy().Equals(empty_bundle));
  cache_->LoadAllSubkeys("extension-policy", &contents);
  ASSERT_EQ(0u, contents.size());
}
TEST_F(ComponentCloudPolicyServiceTest, LoadInvalidPolicyFromCache) {
  
  
  builder_.payload().set_secure_hash(
      crypto::SHA256HashString(kInvalidTestPolicy));
  EXPECT_TRUE(cache_->Store(
      "extension-policy", kTestExtension, CreateSerializedResponse()));
  EXPECT_TRUE(cache_->Store(
      "extension-policy-data", kTestExtension, kInvalidTestPolicy));
  LoadStore();
  InitializeRegistry();
  
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(&delegate_);
  PolicyBundle expected_bundle;
  const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
  expected_bundle.Get(ns).Set("Name", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                              base::Value::CreateStringValue("published"),
                              NULL);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
}
}