15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_service.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_constants.h"
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "policy/proto/device_management_backend.pb.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace em = enterprise_management;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MockCloudPolicyServiceObserver : public CloudPolicyService::Observer {
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockCloudPolicyServiceObserver() {}
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~MockCloudPolicyServiceObserver() {}
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD1(OnInitializationCompleted, void(CloudPolicyService* service));
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyServiceObserver);
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CloudPolicyServiceTest : public testing::Test {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CloudPolicyServiceTest()
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : policy_ns_key_(dm_protocol::kChromeUserPolicyType, std::string()),
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        service_(policy_ns_key_, &client_, &store_) {}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD1(OnPolicyRefresh, void(bool));
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PolicyNamespaceKey policy_ns_key_;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockCloudPolicyClient client_;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockCloudPolicyStore store_;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CloudPolicyService service_;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MATCHER_P(ProtoMatches, proto, "") {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return arg.SerializePartialAsString() == proto.SerializePartialAsString();
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyServiceTest, ManagedByEmptyPolicy) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", service_.ManagedBy());
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyServiceTest, ManagedByValidPolicy) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_.policy_.reset(new em::PolicyData());
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_.policy_->set_username("user@example.com");
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("example.com", service_.ManagedBy());
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyServiceTest, PolicyUpdateSuccess) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  em::PolicyFetchResponse policy;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.set_policy_data("fake policy");
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client_.SetPolicy(policy_ns_key_, policy);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(store_, Store(ProtoMatches(policy))).Times(1);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_.NotifyPolicyFetched();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After |store_| initializes, credentials and other meta data should be
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transferred to |client_|.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_.policy_.reset(new em::PolicyData());
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_.policy_->set_request_token("fake token");
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_.policy_->set_device_id("fake client id");
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_.policy_->set_timestamp(32);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_.policy_->set_valid_serial_number_missing(true);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_.policy_->set_public_key_version(17);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(client_,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              SetupRegistration(store_.policy_->request_token(),
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                store_.policy_->device_id())).Times(1);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_.NotifyStoreLoaded();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMilliseconds(32),
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            client_.last_policy_timestamp_);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(client_.submit_machine_id_);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(client_.public_key_version_valid_);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(17, client_.public_key_version_);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyServiceTest, PolicyUpdateClientFailure) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_.SetStatus(DM_STATUS_REQUEST_FAILED);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(store_, Store(_)).Times(0);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_.NotifyPolicyFetched();
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyServiceTest, RefreshPolicySuccess) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  testing::InSequence seq;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnPolicyRefresh(_)).Times(0);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_.SetDMToken("fake token");
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Trigger a fetch on the client.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(client_, FetchPolicy()).Times(1);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    base::Unretained(this)));
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Client responds, push policy to store.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  em::PolicyFetchResponse policy;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.set_policy_data("fake policy");
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client_.SetPolicy(policy_ns_key_, policy);
108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  client_.fetched_invalidation_version_ = 12345;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(store_, Store(ProtoMatches(policy))).Times(1);
110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(0, store_.invalidation_version());
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_.NotifyPolicyFetched();
112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(12345, store_.invalidation_version());
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Store reloads policy, callback gets triggered.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_.policy_.reset(new em::PolicyData());
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_.policy_->set_request_token("token");
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_.policy_->set_device_id("device-id");
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnPolicyRefresh(true)).Times(1);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_.NotifyStoreLoaded();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyServiceTest, RefreshPolicyNotRegistered) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear the token so the client is not registered.
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  client_.SetDMToken(std::string());
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(client_, FetchPolicy()).Times(0);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnPolicyRefresh(false)).Times(1);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    base::Unretained(this)));
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyServiceTest, RefreshPolicyClientError) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  testing::InSequence seq;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnPolicyRefresh(_)).Times(0);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_.SetDMToken("fake token");
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Trigger a fetch on the client.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(client_, FetchPolicy()).Times(1);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    base::Unretained(this)));
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Client responds with an error, which should trigger the callback.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_.SetStatus(DM_STATUS_REQUEST_FAILED);
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnPolicyRefresh(false)).Times(1);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_.NotifyClientError();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyServiceTest, RefreshPolicyStoreError) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  testing::InSequence seq;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnPolicyRefresh(_)).Times(0);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_.SetDMToken("fake token");
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Trigger a fetch on the client.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(client_, FetchPolicy()).Times(1);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    base::Unretained(this)));
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Client responds, push policy to store.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  em::PolicyFetchResponse policy;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.set_policy_data("fake policy");
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client_.SetPolicy(policy_ns_key_, policy);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(store_, Store(ProtoMatches(policy))).Times(1);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_.NotifyPolicyFetched();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Store fails, which should trigger the callback.
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnPolicyRefresh(false)).Times(1);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_.NotifyStoreError();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyServiceTest, RefreshPolicyConcurrent) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  testing::InSequence seq;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnPolicyRefresh(_)).Times(0);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_.SetDMToken("fake token");
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Trigger a fetch on the client.
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(client_, FetchPolicy()).Times(1);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    base::Unretained(this)));
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Triggering another policy refresh should generate a new fetch request.
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(client_, FetchPolicy()).Times(1);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    base::Unretained(this)));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Client responds, push policy to store.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  em::PolicyFetchResponse policy;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy.set_policy_data("fake policy");
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client_.SetPolicy(policy_ns_key_, policy);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(store_, Store(ProtoMatches(policy))).Times(1);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_.NotifyPolicyFetched();
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Trigger another policy fetch.
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(client_, FetchPolicy()).Times(1);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    base::Unretained(this)));
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The store finishing the first load should not generate callbacks.
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnPolicyRefresh(_)).Times(0);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_.NotifyStoreLoaded();
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second policy fetch finishes.
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(store_, Store(ProtoMatches(policy))).Times(1);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_.NotifyPolicyFetched();
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Corresponding store operation finishes, all _three_ callbacks fire.
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnPolicyRefresh(true)).Times(3);
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  store_.NotifyStoreLoaded();
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(CloudPolicyServiceTest, StoreAlreadyInitialized) {
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Service should start off initialized if the store has already loaded
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // policy.
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  store_.NotifyStoreLoaded();
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CloudPolicyService service(policy_ns_key_, &client_, &store_);
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(service.IsInitializationComplete());
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(CloudPolicyServiceTest, StoreLoadAfterCreation) {
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Service should start off un-initialized if the store has not yet loaded
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // policy.
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(service_.IsInitializationComplete());
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockCloudPolicyServiceObserver observer;
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  service_.AddObserver(&observer);
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Service should be marked as initialized and observer should be called back.
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(observer, OnInitializationCompleted(&service_)).Times(1);
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  store_.NotifyStoreLoaded();
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(service_.IsInitializationComplete());
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  testing::Mock::VerifyAndClearExpectations(&observer);
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now, the next time the store is loaded, the observer should not be called
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // again.
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(observer, OnInitializationCompleted(&service_)).Times(0);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_.NotifyStoreLoaded();
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  service_.RemoveObserver(&observer);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace policy
241