12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/component_cloud_policy_service.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <map>
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <string>
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/callback.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/run_loop.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/single_thread_task_runner.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_constants.h"
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/policy_builder.h"
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/resource_cache.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/external_data_fetcher.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_map.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_types.h"
2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "components/policy/core/common/schema.h"
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/schema_map.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "crypto/sha2.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/test_url_fetcher_factory.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request_context.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "policy/proto/chrome_extension_policy.pb.h"
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "policy/proto/device_management_backend.pb.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace em = enterprise_management;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Mock;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace policy {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kTestExtension[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kTestExtension2[] = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kTestDownload[] = "http://example.com/getpolicy?id=123";
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kTestPolicy[] =
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "{"
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"Name\": {"
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "    \"Value\": \"disabled\""
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  },"
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"Second\": {"
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "    \"Value\": \"maybe\","
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "    \"Level\": \"Recommended\""
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  }"
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "}";
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kInvalidTestPolicy[] =
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "{"
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  \"Name\": {"
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    \"Value\": \"published\""
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  },"
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  \"Undeclared Name\": {"
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    \"Value\": \"not published\""
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  }"
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "}";
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kTestSchema[] =
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "{"
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "  \"type\": \"object\","
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "  \"properties\": {"
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "    \"Name\": { \"type\": \"string\" },"
7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "    \"Second\": { \"type\": \"string\" }"
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "  }"
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "}";
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MockComponentCloudPolicyDelegate
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public ComponentCloudPolicyService::Delegate {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~MockComponentCloudPolicyDelegate() {}
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD0(OnComponentCloudPolicyUpdated, void());
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestURLRequestContextGetter : public net::URLRequestContextGetter {
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit TestURLRequestContextGetter(
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_refptr<base::SingleThreadTaskRunner> task_runner)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : task_runner_(task_runner) {}
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual scoped_refptr<base::SingleThreadTaskRunner>
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetNetworkTaskRunner() const OVERRIDE {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return task_runner_;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TestURLRequestContextGetter() {}
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ComponentCloudPolicyServiceTest : public testing::Test {
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ComponentCloudPolicyServiceTest()
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : client_(NULL),
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        core_(PolicyNamespaceKey(GetChromeUserPolicyType(), ""),
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              &store_,
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              loop_.message_loop_proxy()) {}
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    cache_ = new ResourceCache(temp_dir_.path(), loop_.message_loop_proxy());
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    request_context_ =
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new TestURLRequestContextGetter(loop_.message_loop_proxy());
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    service_.reset(new ComponentCloudPolicyService(
12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        &delegate_,
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &registry_,
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &core_,
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        make_scoped_ptr(cache_),
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        request_context_,
12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        loop_.message_loop_proxy(),
12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        loop_.message_loop_proxy()));
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    builder_.policy_data().set_policy_type(
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        dm_protocol::kChromeExtensionPolicyType);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    builder_.policy_data().set_settings_entity_id(kTestExtension);
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    builder_.payload().set_download_url(kTestDownload);
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    builder_.payload().set_secure_hash(crypto::SHA256HashString(kTestPolicy));
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    expected_policy_.Set("Name",
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         POLICY_LEVEL_MANDATORY,
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         POLICY_SCOPE_USER,
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         new base::StringValue("disabled"),
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         NULL);
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    expected_policy_.Set("Second",
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         POLICY_LEVEL_RECOMMENDED,
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         POLICY_SCOPE_USER,
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         new base::StringValue("maybe"),
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         NULL);
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // The service cleans up its backend on the background thread.
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    service_.reset();
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunUntilIdle();
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RunUntilIdle() {
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Connect(size_t expected_namespaces_in_client) {
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    client_ = new MockCloudPolicyClient();
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    client_->SetDMToken(ComponentPolicyBuilder::kFakeToken);
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(0u, client_->namespaces_to_fetch_.size());
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    core_.Connect(scoped_ptr<CloudPolicyClient>(client_));
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // |expected_namespaces_in_client| is the expected number of components
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // that the ComponentCloudPolicyService will set at the |client_| at
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // OnCoreConnected.
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(expected_namespaces_in_client,
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              client_->namespaces_to_fetch_.size());
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Also initialize the refresh scheduler, so that calls to
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // core()->RefreshSoon() trigger a FetchPolicy() call on the mock |client_|.
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // The |service_| should never trigger new fetches.
1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_CALL(*client_, FetchPolicy());
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    core_.StartRefreshScheduler();
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    RunUntilIdle();
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Mock::VerifyAndClearExpectations(client_);
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void LoadStore() {
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(store_.is_initialized());
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    em::PolicyData* data = new em::PolicyData();
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data->set_username(ComponentPolicyBuilder::kFakeUsername);
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data->set_request_token(ComponentPolicyBuilder::kFakeToken);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    store_.policy_.reset(data);
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    store_.NotifyStoreLoaded();
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunUntilIdle();
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_TRUE(store_.is_initialized());
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void InitializeRegistry() {
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    registry_.RegisterComponent(
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension),
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        CreateTestSchema());
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    registry_.SetReady(POLICY_DOMAIN_CHROME);
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    registry_.SetReady(POLICY_DOMAIN_EXTENSIONS);
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void PopulateCache() {
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(cache_->Store(
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "extension-policy", kTestExtension, CreateSerializedResponse()));
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        cache_->Store("extension-policy-data", kTestExtension, kTestPolicy));
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    builder_.policy_data().set_settings_entity_id(kTestExtension2);
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(cache_->Store(
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "extension-policy", kTestExtension2, CreateSerializedResponse()));
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        cache_->Store("extension-policy-data", kTestExtension2, kTestPolicy));
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<em::PolicyFetchResponse> CreateResponse() {
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    builder_.Build();
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return make_scoped_ptr(new em::PolicyFetchResponse(builder_.policy()));
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string CreateSerializedResponse() {
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    builder_.Build();
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return builder_.GetBlob();
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Schema CreateTestSchema() {
22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::string error;
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Schema schema = Schema::Parse(kTestSchema, &error);
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_TRUE(schema.valid()) << error;
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return schema;
23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop loop_;
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir_;
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<TestURLRequestContextGetter> request_context_;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcherFactory fetcher_factory_;
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockComponentCloudPolicyDelegate delegate_;
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |cache_| is owned by the |service_| and is invalid once the |service_|
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is destroyed.
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceCache* cache_;
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MockCloudPolicyClient* client_;
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockCloudPolicyStore store_;
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CloudPolicyCore core_;
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SchemaRegistry registry_;
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ComponentCloudPolicyService> service_;
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ComponentPolicyBuilder builder_;
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PolicyMap expected_policy_;
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ComponentCloudPolicyServiceTest, InitializedAtConstructionTime) {
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  service_.reset();
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Connect(1u);
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  LoadStore();
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeRegistry();
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  cache_ = new ResourceCache(temp_dir_.path(), loop_.message_loop_proxy());
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  service_.reset(new ComponentCloudPolicyService(&delegate_,
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                 &registry_,
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                 &core_,
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                 make_scoped_ptr(cache_),
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                 request_context_,
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                 loop_.message_loop_proxy(),
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                 loop_.message_loop_proxy()));
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(service_->is_initialized());
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunUntilIdle();
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&client_);
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&delegate_);
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(service_->is_initialized());
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(2u, client_->namespaces_to_fetch_.size());
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const PolicyBundle empty_bundle;
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(service_->policy().Equals(empty_bundle));
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ComponentCloudPolicyServiceTest, InitializeStoreThenRegistry) {
278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Connect(2u);
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated()).Times(0);
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadStore();
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(client_);
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&delegate_);
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(service_->is_initialized());
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeRegistry();
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunUntilIdle();
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(client_);
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&delegate_);
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(service_->is_initialized());
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const PolicyBundle empty_bundle;
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(service_->policy().Equals(empty_bundle));
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ComponentCloudPolicyServiceTest, InitializeRegistryThenStore) {
300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Connect(2u);
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated()).Times(0);
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeRegistry();
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunUntilIdle();
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(client_);
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&delegate_);
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(service_->is_initialized());
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadStore();
313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(client_);
314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&delegate_);
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(service_->is_initialized());
316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(2u, client_->namespaces_to_fetch_.size());
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const PolicyBundle empty_bundle;
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(service_->policy().Equals(empty_bundle));
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ComponentCloudPolicyServiceTest, InitializeWithCachedPolicy) {
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PopulateCache();
323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Connect(2u);
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeRegistry();
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadStore();
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(client_);
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&delegate_);
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(service_->is_initialized());
333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(2u, client_->namespaces_to_fetch_.size());
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // kTestExtension2 is not in the registry so it was dropped.
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<std::string, std::string> contents;
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cache_->LoadAllSubkeys("extension-policy", &contents);
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1u, contents.size());
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(kTestExtension, contents.begin()->first);
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyBundle expected_bundle;
342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  expected_bundle.Get(ns).CopyFrom(expected_policy_);
344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ComponentCloudPolicyServiceTest, FetchPolicy) {
348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Connect(2u);
349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Initialize the store and create the backend.
350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // A refresh is not needed, because no components are registered yet.
351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registry_.SetReady(POLICY_DOMAIN_CHROME);
354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registry_.SetReady(POLICY_DOMAIN_EXTENSIONS);
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadStore();
356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(client_);
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&delegate_);
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(service_->is_initialized());
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
360116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Register the components to fetch. The |service_| issues a new update
361116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // because the new schema may filter different policies from the store.
362116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
363116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registry_.RegisterComponent(
365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension),
366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      CreateTestSchema());
367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunUntilIdle();
368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(client_);
369116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Mock::VerifyAndClearExpectations(&delegate_);
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send back a fake policy fetch response.
372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  client_->SetPolicy(PolicyNamespaceKey(dm_protocol::kChromeExtensionPolicyType,
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                        kTestExtension),
374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     *CreateResponse());
375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  service_->OnPolicyFetched(client_);
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunUntilIdle();
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // That should have triggered the download fetch.
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(fetcher);
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(GURL(kTestDownload), fetcher->GetOriginalURL());
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher->set_response_code(200);
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher->SetResponseString(kTestPolicy);
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher->delegate()->OnURLFetchComplete(fetcher);
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunUntilIdle();
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&delegate_);
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The policy is now being served.
391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PolicyBundle expected_bundle;
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected_bundle.Get(ns).CopyFrom(expected_policy_);
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ComponentCloudPolicyServiceTest, LoadAndPurgeCache) {
398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Connect(2u);
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Insert data in the cache.
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PopulateCache();
401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registry_.RegisterComponent(
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension2),
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      CreateTestSchema());
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeRegistry();
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Load the initial cache.
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(*client_, FetchPolicy()).Times(0);
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadStore();
410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(client_);
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&delegate_);
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PolicyBundle expected_bundle;
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected_bundle.Get(ns).CopyFrom(expected_policy_);
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ns.component_id = kTestExtension2;
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected_bundle.Get(ns).CopyFrom(expected_policy_);
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Now purge one of the extensions. This generates 2 notifications: one for
421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // the new, immediate filtering, and another once the backend comes back
422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // after purging the cache.
423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated()).Times(2);
424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registry_.UnregisterComponent(
425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension));
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunUntilIdle();
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&delegate_);
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ns.component_id = kTestExtension;
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected_bundle.Get(ns).Clear();
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<std::string, std::string> contents;
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cache_->LoadAllSubkeys("extension-policy", &contents);
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, contents.size());
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(ContainsKey(contents, kTestExtension2));
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ComponentCloudPolicyServiceTest, SignInAfterStartup) {
440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registry_.SetReady(POLICY_DOMAIN_CHROME);
441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registry_.SetReady(POLICY_DOMAIN_EXTENSIONS);
442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Initialize the store without credentials.
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(store_.is_initialized());
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(service_->is_initialized());
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  store_.NotifyStoreLoaded();
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunUntilIdle();
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&delegate_);
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(service_->is_initialized());
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Register an extension.
453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registry_.RegisterComponent(
455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension),
456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      CreateTestSchema());
457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunUntilIdle();
458116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Mock::VerifyAndClearExpectations(&delegate_);
459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Now signin. A fetch will be requested for the new extension.
461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Connect(2u);
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Send the response to the service. The response data will be ignored,
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // because the store doesn't have the updated credentials yet.
465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  client_->SetPolicy(PolicyNamespaceKey(dm_protocol::kChromeExtensionPolicyType,
466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                        kTestExtension),
467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     *CreateResponse());
468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  service_->OnPolicyFetched(client_);
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunUntilIdle();
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The policy was ignored and no download is started because the store
472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // doesn't have credentials.
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(fetcher);
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now update the |store_| with the updated policy, which includes
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // credentials. The responses in the |client_| will be reloaded.
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  em::PolicyData* data = new em::PolicyData();
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data->set_username(ComponentPolicyBuilder::kFakeUsername);
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data->set_request_token(ComponentPolicyBuilder::kFakeToken);
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  store_.policy_.reset(data);
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  store_.NotifyStoreLoaded();
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunUntilIdle();
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The extension policy was validated this time, and the download is started.
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher = fetcher_factory_.GetFetcherByID(0);
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(fetcher);
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(GURL(kTestDownload), fetcher->GetOriginalURL());
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher->set_response_code(200);
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher->SetResponseString(kTestPolicy);
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher->delegate()->OnURLFetchComplete(fetcher);
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunUntilIdle();
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&delegate_);
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The policy is now being served.
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PolicyBundle expected_bundle;
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected_bundle.Get(ns).CopyFrom(expected_policy_);
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ComponentCloudPolicyServiceTest, SignOut) {
5055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Initialize everything and serve policy for a component.
506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PopulateCache();
507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  LoadStore();
508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeRegistry();
509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The initial, cached policy will be served once the backend is initialized.
511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunUntilIdle();
513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&delegate_);
514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyBundle expected_bundle;
515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  expected_bundle.Get(ns).CopyFrom(expected_policy_);
517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::map<std::string, std::string> contents;
519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  cache_->LoadAllSubkeys("extension-policy", &contents);
520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1u, contents.size());
521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Now sign in.
523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Connect(2u);
524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Signing out removes all of the component policies from the service and
526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // from the cache. It does not trigger a refresh.
527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  core_.Disconnect();
529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  store_.policy_.reset();
530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  store_.NotifyStoreLoaded();
531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunUntilIdle();
532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&delegate_);
533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const PolicyBundle empty_bundle;
534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(service_->policy().Equals(empty_bundle));
535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  cache_->LoadAllSubkeys("extension-policy", &contents);
536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(0u, contents.size());
537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ComponentCloudPolicyServiceTest, LoadInvalidPolicyFromCache) {
540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Put the invalid test policy in the cache. One of its policies will be
541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // loaded, the other should be filtered out by the schema.
5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  builder_.payload().set_secure_hash(
5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      crypto::SHA256HashString(kInvalidTestPolicy));
544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(cache_->Store(
545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "extension-policy", kTestExtension, CreateSerializedResponse()));
546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(cache_->Store(
547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "extension-policy-data", kTestExtension, kInvalidTestPolicy));
548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  LoadStore();
550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeRegistry();
551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The initial, cached policy will be served once the backend is initialized.
553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunUntilIdle();
555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&delegate_);
556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyBundle expected_bundle;
558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
5595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  expected_bundle.Get(ns).Set("Name",
5605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              POLICY_LEVEL_MANDATORY,
5615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              POLICY_SCOPE_USER,
5625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              new base::StringValue("published"),
563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              NULL);
564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(service_->policy().Equals(expected_bundle));
565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace policy
568