// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/policy/core/common/cloud/component_cloud_policy_service.h"

#include <stdint.h>

#include <map>
#include <string>
#include <utility>

#include "base/callback.h"
#include "base/files/scoped_temp_dir.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.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 "components/policy/proto/chrome_extension_policy.pb.h"
#include "components/policy/proto/device_management_backend.pb.h"
#include "crypto/rsa_private_key.h"
#include "crypto/sha2.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_network_connection_tracker.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace em = enterprise_management;

using testing::AtLeast;
using testing::Mock;
using testing::Return;

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:
  ~MockComponentCloudPolicyDelegate() override {}

  MOCK_METHOD0(OnComponentCloudPolicyUpdated, void());
};

}  // namespace

class ComponentCloudPolicyServiceTest : public testing::Test {
 protected:
  ComponentCloudPolicyServiceTest()
      : cache_(nullptr),
        client_(nullptr),
        core_(dm_protocol::kChromeUserPolicyType,
              std::string(),
              &store_,
              base::ThreadTaskRunnerHandle::Get(),
              network::TestNetworkConnectionTracker::CreateGetter()) {
    builder_.SetDefaultSigningKey();
    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));

    public_key_ = builder_.GetPublicSigningKeyAsString();

    expected_policy_.Set("Name", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                         POLICY_SOURCE_CLOUD,
                         std::make_unique<base::Value>("disabled"), nullptr);
    expected_policy_.Set("Second", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
                         POLICY_SOURCE_CLOUD,
                         std::make_unique<base::Value>("maybe"), nullptr);
  }

  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());

    owned_cache_.reset(new ResourceCache(temp_dir_.GetPath(),
                                         base::ThreadTaskRunnerHandle::Get(),
                                         /* max_cache_size */ base::nullopt));
    cache_ = owned_cache_.get();
  }

  void TearDown() override {
    // The service cleans up its backend on the background thread.
    service_.reset();
    RunUntilIdle();
  }

  void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }

  void Connect() {
    client_ = new MockCloudPolicyClient(
        base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
            &loader_factory_));
    service_.reset(new ComponentCloudPolicyService(
        dm_protocol::kChromeExtensionPolicyType, &delegate_, &registry_, &core_,
        client_, std::move(owned_cache_), base::ThreadTaskRunnerHandle::Get()));

    client_->SetDMToken(ComponentCloudPolicyBuilder::kFakeToken);
    EXPECT_EQ(1u, client_->types_to_fetch_.size());
    core_.Connect(std::unique_ptr<CloudPolicyClient>(client_));
    EXPECT_EQ(2u, client_->types_to_fetch_.size());

    // Also initialize the refresh scheduler, so that calls to
    // core()->RefreshSoon() trigger a FetchPolicy() call on the mock |client_|.
    // The |service_| should never trigger new fetches.
    EXPECT_CALL(*client_, FetchPolicy());
    core_.StartRefreshScheduler();
    RunUntilIdle();
    Mock::VerifyAndClearExpectations(client_);
  }

  void LoadStore() {
    em::PolicyData* data = new em::PolicyData();
    data->set_username(PolicyBuilder::kFakeUsername);
    data->set_request_token(PolicyBuilder::kFakeToken);
    data->set_device_id(PolicyBuilder::kFakeDeviceId);
    data->set_public_key_version(PolicyBuilder::kFakePublicKeyVersion);
    store_.policy_.reset(data);
    store_.policy_signature_public_key_ = public_key_;
    store_.NotifyStoreLoaded();
    RunUntilIdle();
    EXPECT_TRUE(store_.is_initialized());
  }

  void InitializeRegistry() {
    registry_.RegisterComponent(
        PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension),
        CreateTestSchema());
    registry_.SetAllDomainsReady();
  }

  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));
    builder_.policy_data().set_settings_entity_id(kTestExtension);
  }

  std::unique_ptr<em::PolicyFetchResponse> CreateResponse() {
    builder_.Build();
    return std::make_unique<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;
  }

  const PolicyNamespace kTestExtensionNS =
      PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
  const PolicyNamespace kTestExtensionNS2 =
      PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension2);

  base::test::ScopedTaskEnvironment task_environment_;
  base::ScopedTempDir temp_dir_;
  network::TestURLLoaderFactory loader_factory_;
  MockComponentCloudPolicyDelegate delegate_;
  // |cache_| is owned by the |service_| and is invalid once the |service_|
  // is destroyed.
  std::unique_ptr<ResourceCache> owned_cache_;
  ResourceCache* cache_;
  MockCloudPolicyClient* client_;
  MockCloudPolicyStore store_;
  CloudPolicyCore core_;
  SchemaRegistry registry_;
  std::unique_ptr<ComponentCloudPolicyService> service_;
  ComponentCloudPolicyBuilder builder_;
  PolicyMap expected_policy_;
  std::string public_key_;
};

TEST_F(ComponentCloudPolicyServiceTest, InitializeStoreThenRegistry) {
  Connect();

  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()).Times(0);
  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();

  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()).Times(0);
  LoadStore();
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);
  EXPECT_TRUE(service_->is_initialized());
  EXPECT_EQ(2u, client_->types_to_fetch_.size());
  const PolicyBundle empty_bundle;
  EXPECT_TRUE(service_->policy().Equals(empty_bundle));
}

TEST_F(ComponentCloudPolicyServiceTest, InitializeWithCachedPolicy) {
  PopulateCache();
  Connect();

  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
  InitializeRegistry();
  LoadStore();
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);

  EXPECT_TRUE(service_->is_initialized());
  EXPECT_EQ(2u, client_->types_to_fetch_.size());

  // Policies for both extensions are stored in the cache.
  std::map<std::string, std::string> contents;
  cache_->LoadAllSubkeys("extension-policy", &contents);
  ASSERT_EQ(2u, contents.size());
  EXPECT_TRUE(base::ContainsKey(contents, kTestExtension));
  EXPECT_TRUE(base::ContainsKey(contents, kTestExtension2));

  // Only policy for extension 1 is now being served, as the registry contains
  // only its schema.
  PolicyBundle expected_bundle;
  expected_bundle.Get(kTestExtensionNS).CopyFrom(expected_policy_);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));

  // Register extension 2. Its policy gets loaded without any additional
  // policy fetches.
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
  registry_.RegisterComponent(kTestExtensionNS2, CreateTestSchema());
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);

  // Policies for both extensions are being served now.
  expected_bundle.Get(kTestExtensionNS2).CopyFrom(expected_policy_);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
}

TEST_F(ComponentCloudPolicyServiceTest, FetchPolicy) {
  Connect();
  // Initialize the store. A refresh is not needed, because no components are
  // registered yet.
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
  registry_.SetAllDomainsReady();
  LoadStore();
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);
  EXPECT_TRUE(service_->is_initialized());

  // Register the components to fetch. The |service_| issues a new update
  // because the new schema may filter different policies from the store.
  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  registry_.RegisterComponent(kTestExtensionNS, CreateTestSchema());
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);

  // Send back a fake policy fetch response.
  client_->SetPolicy(dm_protocol::kChromeExtensionPolicyType, kTestExtension,
                     *CreateResponse());
  service_->OnPolicyFetched(client_);
  RunUntilIdle();

  // That should have triggered the download fetch.
  EXPECT_TRUE(loader_factory_.IsPending(kTestDownload));
  loader_factory_.AddResponse(kTestDownload, kTestPolicy);

  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(&delegate_);

  // The policy is now being served.
  PolicyBundle expected_bundle;
  expected_bundle.Get(kTestExtensionNS).CopyFrom(expected_policy_);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
}

TEST_F(ComponentCloudPolicyServiceTest, FetchPolicyBeforeStoreLoaded) {
  Connect();
  // A fake policy is fetched.
  client_->SetPolicy(dm_protocol::kChromeExtensionPolicyType, kTestExtension,
                     *CreateResponse());
  service_->OnPolicyFetched(client_);
  RunUntilIdle();

  // Initialize the store. A refresh is not needed, because no components are
  // registered yet.
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
  registry_.SetAllDomainsReady();
  LoadStore();
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);
  EXPECT_TRUE(service_->is_initialized());

  // Register the components to fetch. The |service_| issues a new update
  // because the new schema may filter different policies from the store.
  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  registry_.RegisterComponent(kTestExtensionNS, CreateTestSchema());
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);

  // The download started.
  EXPECT_TRUE(loader_factory_.IsPending(kTestDownload));
  loader_factory_.AddResponse(kTestDownload, kTestPolicy);

  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(&delegate_);

  // The policy is now being served.
  PolicyBundle expected_bundle;
  expected_bundle.Get(kTestExtensionNS).CopyFrom(expected_policy_);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
}

TEST_F(ComponentCloudPolicyServiceTest,
       FetchPolicyWithCachedPolicyBeforeStoreLoaded) {
  PopulateCache();
  Connect();
  // A fake policy is fetched.
  client_->SetPolicy(dm_protocol::kChromeExtensionPolicyType, kTestExtension,
                     *CreateResponse());
  service_->OnPolicyFetched(client_);
  RunUntilIdle();

  // Initialize the store.
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated()).Times(AtLeast(1));
  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
  InitializeRegistry();
  LoadStore();
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);
  EXPECT_TRUE(service_->is_initialized());

  // Only policy for extension 1 is served. Policy for extension 2, which was in
  // the cache initially, is now dropped.
  PolicyBundle expected_bundle;
  expected_bundle.Get(kTestExtensionNS).CopyFrom(expected_policy_);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
}

TEST_F(ComponentCloudPolicyServiceTest, LoadCacheAndDeleteExtensions) {
  Connect();
  // Insert data in the cache.
  PopulateCache();
  registry_.RegisterComponent(kTestExtensionNS2, CreateTestSchema());
  InitializeRegistry();

  // Load the initial cache.
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
  LoadStore();
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);

  PolicyBundle expected_bundle;
  expected_bundle.Get(kTestExtensionNS).CopyFrom(expected_policy_);
  expected_bundle.Get(kTestExtensionNS2).CopyFrom(expected_policy_);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));

  // Now purge one of the extensions. This generates a notification after an
  // immediate filtering.
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  registry_.UnregisterComponent(kTestExtensionNS);
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(&delegate_);

  // The policy served for extension 1 becomes empty.
  expected_bundle.Get(kTestExtensionNS).Clear();
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));

  // The cache still keeps policies for both extensions.
  std::map<std::string, std::string> contents;
  cache_->LoadAllSubkeys("extension-policy", &contents);
  EXPECT_EQ(2u, contents.size());
  EXPECT_TRUE(base::ContainsKey(contents, kTestExtension));
  EXPECT_TRUE(base::ContainsKey(contents, kTestExtension2));
}

TEST_F(ComponentCloudPolicyServiceTest, SignInAfterStartup) {
  registry_.SetAllDomainsReady();

  // Initialize the store without credentials.
  EXPECT_FALSE(store_.is_initialized());
  store_.NotifyStoreLoaded();
  RunUntilIdle();

  // Register an extension.
  registry_.RegisterComponent(kTestExtensionNS, CreateTestSchema());
  RunUntilIdle();

  // Now signin. The service will finish loading its backend (which is empty
  // for now, because there are no credentials) and issue a notification.
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  Connect();
  Mock::VerifyAndClearExpectations(&delegate_);

  // Send the response to the service. The response data will be ignored,
  // because the store doesn't have the updated credentials yet.
  client_->SetPolicy(dm_protocol::kChromeExtensionPolicyType, kTestExtension,
                     *CreateResponse());
  service_->OnPolicyFetched(client_);
  RunUntilIdle();

  // The policy was ignored and no download is started because the store
  // doesn't have credentials.
  EXPECT_EQ(0, loader_factory_.NumPending());

  // Now update the |store_| with the updated policy, which includes
  // credentials. The responses in the |client_| will be reloaded.
  LoadStore();

  // The extension policy was validated this time, and the download is started.
  ASSERT_EQ(1, loader_factory_.NumPending());
  EXPECT_TRUE(loader_factory_.IsPending(kTestDownload));
  loader_factory_.AddResponse(kTestDownload, kTestPolicy);

  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(&delegate_);

  // The policy is now being served.
  PolicyBundle expected_bundle;
  expected_bundle.Get(kTestExtensionNS).CopyFrom(expected_policy_);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
}

TEST_F(ComponentCloudPolicyServiceTest, SignOut) {
  // Initialize everything and serve policy for a component.
  PopulateCache();
  LoadStore();
  InitializeRegistry();

  // The initial, cached policy will be served once the backend is initialized.
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  Connect();
  Mock::VerifyAndClearExpectations(&delegate_);
  // Policy for extension 1 is now being served.
  PolicyBundle expected_bundle;
  expected_bundle.Get(kTestExtensionNS).CopyFrom(expected_policy_);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
  // The cache still contains policies for both extensions.
  std::map<std::string, std::string> contents;
  cache_->LoadAllSubkeys("extension-policy", &contents);
  ASSERT_EQ(2u, contents.size());

  // Signing out removes all of the component policies from the service and
  // from the cache. It does not trigger a refresh.
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  core_.Disconnect();
  store_.policy_.reset();
  Mock::VerifyAndClearExpectations(&store_);
  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) {
  // Put the invalid test policy in the cache. One of its policies will be
  // loaded, the other should be filtered out by the schema.
  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();

  // The initial, cached policy will be served once the backend is initialized.
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  Connect();
  Mock::VerifyAndClearExpectations(&delegate_);

  PolicyBundle expected_bundle;
  expected_bundle.Get(kTestExtensionNS)
      .Set("Name", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
           POLICY_SOURCE_CLOUD, std::make_unique<base::Value>("published"),
           nullptr);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
}

TEST_F(ComponentCloudPolicyServiceTest, PurgeWhenServerRemovesPolicy) {
  // Initialize with cached policy.
  PopulateCache();
  Connect();

  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
  registry_.RegisterComponent(kTestExtensionNS2, CreateTestSchema());
  InitializeRegistry();
  LoadStore();
  Mock::VerifyAndClearExpectations(client_);
  Mock::VerifyAndClearExpectations(&delegate_);

  EXPECT_TRUE(service_->is_initialized());
  EXPECT_EQ(2u, client_->types_to_fetch_.size());

  // Verify that policy for 2 extensions has been loaded from the cache.
  std::map<std::string, std::string> contents;
  cache_->LoadAllSubkeys("extension-policy", &contents);
  ASSERT_EQ(2u, contents.size());
  EXPECT_TRUE(base::ContainsKey(contents, kTestExtension));
  EXPECT_TRUE(base::ContainsKey(contents, kTestExtension2));

  PolicyBundle expected_bundle;
  expected_bundle.Get(kTestExtensionNS).CopyFrom(expected_policy_);
  expected_bundle.Get(kTestExtensionNS2).CopyFrom(expected_policy_);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));

  // Receive an updated fetch response from the server. There is no response for
  // extension 2, so it will be dropped from the cache. This triggers an
  // immediate notification to the delegate.
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  client_->SetPolicy(dm_protocol::kChromeExtensionPolicyType, kTestExtension,
                     *CreateResponse());
  service_->OnPolicyFetched(client_);
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(&delegate_);

  // The cache should have dropped the entries for the second extension.
  contents.clear();
  cache_->LoadAllSubkeys("extension-policy", &contents);
  ASSERT_EQ(1u, contents.size());
  EXPECT_TRUE(base::ContainsKey(contents, kTestExtension));
  EXPECT_FALSE(base::ContainsKey(contents, kTestExtension2));

  // And the service isn't publishing policy for the second extension anymore.
  expected_bundle.Clear();
  expected_bundle.Get(kTestExtensionNS).CopyFrom(expected_policy_);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
}

TEST_F(ComponentCloudPolicyServiceTest, KeyRotation) {
  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  Connect();
  LoadStore();
  InitializeRegistry();
  RunUntilIdle();
  EXPECT_TRUE(service_->is_initialized());

  // Send back a fake policy fetch response with the new signing key.
  const int kNewPublicKeyVersion = PolicyBuilder::kFakePublicKeyVersion + 1;
  std::unique_ptr<crypto::RSAPrivateKey> new_signing_key =
      PolicyBuilder::CreateTestOtherSigningKey();
  builder_.SetSigningKey(*new_signing_key);
  builder_.policy_data().set_public_key_version(kNewPublicKeyVersion);
  client_->SetPolicy(dm_protocol::kChromeExtensionPolicyType, kTestExtension,
                     *CreateResponse());
  service_->OnPolicyFetched(client_);
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(&store_);

  // The download fetch shouldn't have been triggered, as the component policy
  // validation should fail due to the old key returned by the store.
  ASSERT_EQ(0, loader_factory_.NumPending());

  // Update the signing key in the store.
  store_.policy_signature_public_key_ = builder_.GetPublicSigningKeyAsString();
  store_.policy_->set_public_key_version(kNewPublicKeyVersion);
  store_.NotifyStoreLoaded();
  RunUntilIdle();

  // The validation of the component policy should have finished successfully
  // and trigger the download fetch.
  EXPECT_TRUE(loader_factory_.IsPending(kTestDownload));
  loader_factory_.AddResponse(kTestDownload, kTestPolicy);

  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
  RunUntilIdle();
  Mock::VerifyAndClearExpectations(&delegate_);

  // The policy is now being served.
  PolicyBundle expected_bundle;
  expected_bundle.Get(kTestExtensionNS).CopyFrom(expected_policy_);
  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
}

}  // namespace policy
