- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / policy / cloud / cloud_policy_service_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/policy/cloud/cloud_policy_service.h"
6
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "chrome/browser/policy/cloud/cloud_policy_constants.h"
10 #include "chrome/browser/policy/cloud/mock_cloud_policy_client.h"
11 #include "chrome/browser/policy/cloud/mock_cloud_policy_store.h"
12 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace em = enterprise_management;
17
18 using testing::_;
19
20 namespace policy {
21
22 class MockCloudPolicyServiceObserver : public CloudPolicyService::Observer {
23  public:
24   MockCloudPolicyServiceObserver() {}
25   virtual ~MockCloudPolicyServiceObserver() {}
26
27   MOCK_METHOD1(OnInitializationCompleted, void(CloudPolicyService* service));
28  private:
29   DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyServiceObserver);
30 };
31
32 class CloudPolicyServiceTest : public testing::Test {
33  public:
34   CloudPolicyServiceTest()
35       : policy_ns_key_(dm_protocol::kChromeUserPolicyType, std::string()),
36         service_(policy_ns_key_, &client_, &store_) {}
37
38   MOCK_METHOD1(OnPolicyRefresh, void(bool));
39
40  protected:
41   PolicyNamespaceKey policy_ns_key_;
42   MockCloudPolicyClient client_;
43   MockCloudPolicyStore store_;
44   CloudPolicyService service_;
45 };
46
47 MATCHER_P(ProtoMatches, proto, "") {
48   return arg.SerializePartialAsString() == proto.SerializePartialAsString();
49 }
50
51 TEST_F(CloudPolicyServiceTest, ManagedByEmptyPolicy) {
52   EXPECT_EQ("", service_.ManagedBy());
53 }
54
55 TEST_F(CloudPolicyServiceTest, ManagedByValidPolicy) {
56   store_.policy_.reset(new em::PolicyData());
57   store_.policy_->set_username("user@example.com");
58   EXPECT_EQ("example.com", service_.ManagedBy());
59 }
60
61 TEST_F(CloudPolicyServiceTest, PolicyUpdateSuccess) {
62   em::PolicyFetchResponse policy;
63   policy.set_policy_data("fake policy");
64   client_.SetPolicy(policy_ns_key_, policy);
65   EXPECT_CALL(store_, Store(ProtoMatches(policy))).Times(1);
66   client_.NotifyPolicyFetched();
67
68   // After |store_| initializes, credentials and other meta data should be
69   // transferred to |client_|.
70   store_.policy_.reset(new em::PolicyData());
71   store_.policy_->set_request_token("fake token");
72   store_.policy_->set_device_id("fake client id");
73   store_.policy_->set_timestamp(32);
74   store_.policy_->set_valid_serial_number_missing(true);
75   store_.policy_->set_public_key_version(17);
76   EXPECT_CALL(client_,
77               SetupRegistration(store_.policy_->request_token(),
78                                 store_.policy_->device_id())).Times(1);
79   store_.NotifyStoreLoaded();
80   EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMilliseconds(32),
81             client_.last_policy_timestamp_);
82   EXPECT_TRUE(client_.submit_machine_id_);
83   EXPECT_TRUE(client_.public_key_version_valid_);
84   EXPECT_EQ(17, client_.public_key_version_);
85 }
86
87 TEST_F(CloudPolicyServiceTest, PolicyUpdateClientFailure) {
88   client_.SetStatus(DM_STATUS_REQUEST_FAILED);
89   EXPECT_CALL(store_, Store(_)).Times(0);
90   client_.NotifyPolicyFetched();
91 }
92
93 TEST_F(CloudPolicyServiceTest, RefreshPolicySuccess) {
94   testing::InSequence seq;
95
96   EXPECT_CALL(*this, OnPolicyRefresh(_)).Times(0);
97   client_.SetDMToken("fake token");
98
99   // Trigger a fetch on the client.
100   EXPECT_CALL(client_, FetchPolicy()).Times(1);
101   service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
102                                     base::Unretained(this)));
103
104   // Client responds, push policy to store.
105   em::PolicyFetchResponse policy;
106   policy.set_policy_data("fake policy");
107   client_.SetPolicy(policy_ns_key_, policy);
108   client_.fetched_invalidation_version_ = 12345;
109   EXPECT_CALL(store_, Store(ProtoMatches(policy))).Times(1);
110   EXPECT_EQ(0, store_.invalidation_version());
111   client_.NotifyPolicyFetched();
112   EXPECT_EQ(12345, store_.invalidation_version());
113
114   // Store reloads policy, callback gets triggered.
115   store_.policy_.reset(new em::PolicyData());
116   store_.policy_->set_request_token("token");
117   store_.policy_->set_device_id("device-id");
118   EXPECT_CALL(*this, OnPolicyRefresh(true)).Times(1);
119   store_.NotifyStoreLoaded();
120 }
121
122 TEST_F(CloudPolicyServiceTest, RefreshPolicyNotRegistered) {
123   // Clear the token so the client is not registered.
124   client_.SetDMToken(std::string());
125
126   EXPECT_CALL(client_, FetchPolicy()).Times(0);
127   EXPECT_CALL(*this, OnPolicyRefresh(false)).Times(1);
128   service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
129                                     base::Unretained(this)));
130 }
131
132 TEST_F(CloudPolicyServiceTest, RefreshPolicyClientError) {
133   testing::InSequence seq;
134
135   EXPECT_CALL(*this, OnPolicyRefresh(_)).Times(0);
136   client_.SetDMToken("fake token");
137
138   // Trigger a fetch on the client.
139   EXPECT_CALL(client_, FetchPolicy()).Times(1);
140   service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
141                                     base::Unretained(this)));
142
143   // Client responds with an error, which should trigger the callback.
144   client_.SetStatus(DM_STATUS_REQUEST_FAILED);
145   EXPECT_CALL(*this, OnPolicyRefresh(false)).Times(1);
146   client_.NotifyClientError();
147 }
148
149 TEST_F(CloudPolicyServiceTest, RefreshPolicyStoreError) {
150   testing::InSequence seq;
151
152   EXPECT_CALL(*this, OnPolicyRefresh(_)).Times(0);
153   client_.SetDMToken("fake token");
154
155   // Trigger a fetch on the client.
156   EXPECT_CALL(client_, FetchPolicy()).Times(1);
157   service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
158                                     base::Unretained(this)));
159
160   // Client responds, push policy to store.
161   em::PolicyFetchResponse policy;
162   policy.set_policy_data("fake policy");
163   client_.SetPolicy(policy_ns_key_, policy);
164   EXPECT_CALL(store_, Store(ProtoMatches(policy))).Times(1);
165   client_.NotifyPolicyFetched();
166
167   // Store fails, which should trigger the callback.
168   EXPECT_CALL(*this, OnPolicyRefresh(false)).Times(1);
169   store_.NotifyStoreError();
170 }
171
172 TEST_F(CloudPolicyServiceTest, RefreshPolicyConcurrent) {
173   testing::InSequence seq;
174
175   EXPECT_CALL(*this, OnPolicyRefresh(_)).Times(0);
176   client_.SetDMToken("fake token");
177
178   // Trigger a fetch on the client.
179   EXPECT_CALL(client_, FetchPolicy()).Times(1);
180   service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
181                                     base::Unretained(this)));
182
183   // Triggering another policy refresh should generate a new fetch request.
184   EXPECT_CALL(client_, FetchPolicy()).Times(1);
185   service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
186                                     base::Unretained(this)));
187
188   // Client responds, push policy to store.
189   em::PolicyFetchResponse policy;
190   policy.set_policy_data("fake policy");
191   client_.SetPolicy(policy_ns_key_, policy);
192   EXPECT_CALL(store_, Store(ProtoMatches(policy))).Times(1);
193   client_.NotifyPolicyFetched();
194
195   // Trigger another policy fetch.
196   EXPECT_CALL(client_, FetchPolicy()).Times(1);
197   service_.RefreshPolicy(base::Bind(&CloudPolicyServiceTest::OnPolicyRefresh,
198                                     base::Unretained(this)));
199
200   // The store finishing the first load should not generate callbacks.
201   EXPECT_CALL(*this, OnPolicyRefresh(_)).Times(0);
202   store_.NotifyStoreLoaded();
203
204   // Second policy fetch finishes.
205   EXPECT_CALL(store_, Store(ProtoMatches(policy))).Times(1);
206   client_.NotifyPolicyFetched();
207
208   // Corresponding store operation finishes, all _three_ callbacks fire.
209   EXPECT_CALL(*this, OnPolicyRefresh(true)).Times(3);
210   store_.NotifyStoreLoaded();
211 }
212
213 TEST_F(CloudPolicyServiceTest, StoreAlreadyInitialized) {
214   // Service should start off initialized if the store has already loaded
215   // policy.
216   store_.NotifyStoreLoaded();
217   CloudPolicyService service(policy_ns_key_, &client_, &store_);
218   EXPECT_TRUE(service.IsInitializationComplete());
219 }
220
221 TEST_F(CloudPolicyServiceTest, StoreLoadAfterCreation) {
222   // Service should start off un-initialized if the store has not yet loaded
223   // policy.
224   EXPECT_FALSE(service_.IsInitializationComplete());
225   MockCloudPolicyServiceObserver observer;
226   service_.AddObserver(&observer);
227   // Service should be marked as initialized and observer should be called back.
228   EXPECT_CALL(observer, OnInitializationCompleted(&service_)).Times(1);
229   store_.NotifyStoreLoaded();
230   EXPECT_TRUE(service_.IsInitializationComplete());
231   testing::Mock::VerifyAndClearExpectations(&observer);
232
233   // Now, the next time the store is loaded, the observer should not be called
234   // again.
235   EXPECT_CALL(observer, OnInitializationCompleted(&service_)).Times(0);
236   store_.NotifyStoreLoaded();
237   service_.RemoveObserver(&observer);
238 }
239
240 }  // namespace policy