- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / policy / cloud / user_cloud_policy_store_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/user_cloud_policy_store.h"
6
7 #include "base/file_util.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/run_loop.h"
13 #include "chrome/browser/policy/cloud/mock_cloud_external_data_manager.h"
14 #include "chrome/browser/policy/cloud/mock_cloud_policy_store.h"
15 #include "chrome/browser/policy/cloud/policy_builder.h"
16 #include "chrome/browser/signin/fake_signin_manager.h"
17 #include "chrome/browser/signin/signin_manager.h"
18 #include "chrome/browser/signin/signin_manager_factory.h"
19 #include "chrome/common/pref_names.h"
20 #include "chrome/test/base/testing_profile.h"
21 #include "net/url_request/url_request_context_getter.h"
22 #include "policy/policy_constants.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25
26 using testing::AllOf;
27 using testing::Eq;
28 using testing::Mock;
29 using testing::Property;
30 using testing::Sequence;
31
32 namespace policy {
33
34 namespace {
35
36 void RunUntilIdle() {
37   base::RunLoop run_loop;
38   run_loop.RunUntilIdle();
39 }
40
41 class UserCloudPolicyStoreTest : public testing::Test {
42  public:
43   UserCloudPolicyStoreTest()
44       : loop_(base::MessageLoop::TYPE_UI),
45         profile_(new TestingProfile()) {}
46
47   virtual void SetUp() OVERRIDE {
48     ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir());
49     SigninManager* signin = static_cast<SigninManager*>(
50       SigninManagerFactory::GetInstance()->SetTestingFactoryAndUse(
51           profile_.get(), FakeSigninManager::Build));
52     profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
53                                     PolicyBuilder::kFakeUsername);
54     signin->Initialize(profile_.get(), NULL);
55     store_.reset(new UserCloudPolicyStore(
56         profile_.get(), policy_file(), loop_.message_loop_proxy()));
57     external_data_manager_.reset(new MockCloudExternalDataManager);
58     external_data_manager_->SetPolicyStore(store_.get());
59     store_->AddObserver(&observer_);
60
61     policy_.payload().mutable_passwordmanagerenabled()->set_value(true);
62     policy_.payload().mutable_urlblacklist()->mutable_value()->add_entries(
63         "chromium.org");
64
65     policy_.Build();
66   }
67
68   virtual void TearDown() OVERRIDE {
69     store_->RemoveObserver(&observer_);
70     external_data_manager_.reset();
71     store_.reset();
72     RunUntilIdle();
73   }
74
75   base::FilePath policy_file() {
76     return tmp_dir_.path().AppendASCII("policy");
77   }
78
79   // Verifies that store_->policy_map() has the appropriate entries.
80   void VerifyPolicyMap(CloudPolicyStore* store) {
81     EXPECT_EQ(2U, store->policy_map().size());
82     const PolicyMap::Entry* entry =
83         store->policy_map().Get(key::kPasswordManagerEnabled);
84     ASSERT_TRUE(entry);
85     EXPECT_TRUE(base::FundamentalValue(true).Equals(entry->value));
86     ASSERT_TRUE(store->policy_map().Get(key::kURLBlacklist));
87   }
88
89   // Install an expectation on |observer_| for an error code.
90   void ExpectError(CloudPolicyStore* store, CloudPolicyStore::Status error) {
91     EXPECT_CALL(observer_,
92                 OnStoreError(AllOf(Eq(store),
93                                    Property(&CloudPolicyStore::status,
94                                             Eq(error)))));
95   }
96
97   UserPolicyBuilder policy_;
98   MockCloudPolicyStoreObserver observer_;
99   scoped_ptr<UserCloudPolicyStore> store_;
100   scoped_ptr<MockCloudExternalDataManager> external_data_manager_;
101
102   // CloudPolicyValidator() requires a FILE thread so declare one here. Both
103   // |ui_thread_| and |file_thread_| share the same MessageLoop |loop_| so
104   // callers can use RunLoop to manage both virtual threads.
105   base::MessageLoop loop_;
106
107   scoped_ptr<TestingProfile> profile_;
108   base::ScopedTempDir tmp_dir_;
109
110   DISALLOW_COPY_AND_ASSIGN(UserCloudPolicyStoreTest);
111 };
112
113 TEST_F(UserCloudPolicyStoreTest, LoadWithNoFile) {
114   EXPECT_FALSE(store_->policy());
115   EXPECT_TRUE(store_->policy_map().empty());
116
117   Sequence s;
118   EXPECT_CALL(*external_data_manager_, OnPolicyStoreLoaded()).InSequence(s);
119   EXPECT_CALL(observer_, OnStoreLoaded(store_.get())).InSequence(s);
120   store_->Load();
121   RunUntilIdle();
122
123   EXPECT_FALSE(store_->policy());
124   EXPECT_TRUE(store_->policy_map().empty());
125 }
126
127 TEST_F(UserCloudPolicyStoreTest, LoadWithInvalidFile) {
128   EXPECT_FALSE(store_->policy());
129   EXPECT_TRUE(store_->policy_map().empty());
130
131   // Create a bogus file.
132   ASSERT_TRUE(file_util::CreateDirectory(policy_file().DirName()));
133   std::string bogus_data = "bogus_data";
134   int size = bogus_data.size();
135   ASSERT_EQ(size, file_util::WriteFile(policy_file(),
136                                        bogus_data.c_str(),
137                                        bogus_data.size()));
138
139   ExpectError(store_.get(), CloudPolicyStore::STATUS_LOAD_ERROR);
140   store_->Load();
141   RunUntilIdle();
142
143   EXPECT_FALSE(store_->policy());
144   EXPECT_TRUE(store_->policy_map().empty());
145 }
146
147 TEST_F(UserCloudPolicyStoreTest, LoadImmediatelyWithNoFile) {
148   EXPECT_FALSE(store_->policy());
149   EXPECT_TRUE(store_->policy_map().empty());
150
151   Sequence s;
152   EXPECT_CALL(*external_data_manager_, OnPolicyStoreLoaded()).InSequence(s);
153   EXPECT_CALL(observer_, OnStoreLoaded(store_.get())).InSequence(s);
154   store_->LoadImmediately();  // Should load without running the message loop.
155
156   EXPECT_FALSE(store_->policy());
157   EXPECT_TRUE(store_->policy_map().empty());
158 }
159
160 TEST_F(UserCloudPolicyStoreTest, LoadImmediatelyWithInvalidFile) {
161   EXPECT_FALSE(store_->policy());
162   EXPECT_TRUE(store_->policy_map().empty());
163
164   // Create a bogus file.
165   ASSERT_TRUE(file_util::CreateDirectory(policy_file().DirName()));
166   std::string bogus_data = "bogus_data";
167   int size = bogus_data.size();
168   ASSERT_EQ(size, file_util::WriteFile(policy_file(),
169                                        bogus_data.c_str(),
170                                        bogus_data.size()));
171
172   ExpectError(store_.get(), CloudPolicyStore::STATUS_LOAD_ERROR);
173   store_->LoadImmediately();  // Should load without running the message loop.
174
175   EXPECT_FALSE(store_->policy());
176   EXPECT_TRUE(store_->policy_map().empty());
177 }
178
179 TEST_F(UserCloudPolicyStoreTest, Store) {
180   EXPECT_FALSE(store_->policy());
181   EXPECT_TRUE(store_->policy_map().empty());
182
183   // Store a simple policy and make sure it ends up as the currently active
184   // policy.
185   Sequence s;
186   EXPECT_CALL(*external_data_manager_, OnPolicyStoreLoaded()).InSequence(s);
187   EXPECT_CALL(observer_, OnStoreLoaded(store_.get())).InSequence(s);
188   store_->Store(policy_.policy());
189   RunUntilIdle();
190
191   // Policy should be decoded and stored.
192   ASSERT_TRUE(store_->policy());
193   EXPECT_EQ(policy_.policy_data().SerializeAsString(),
194             store_->policy()->SerializeAsString());
195   VerifyPolicyMap(store_.get());
196   EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
197 }
198
199 TEST_F(UserCloudPolicyStoreTest, StoreThenClear) {
200   EXPECT_FALSE(store_->policy());
201   EXPECT_TRUE(store_->policy_map().empty());
202
203   // Store a simple policy and make sure the file exists.
204   // policy.
205   Sequence s1;
206   EXPECT_CALL(*external_data_manager_, OnPolicyStoreLoaded()).InSequence(s1);
207   EXPECT_CALL(observer_, OnStoreLoaded(store_.get())).InSequence(s1);
208   store_->Store(policy_.policy());
209   RunUntilIdle();
210
211   EXPECT_TRUE(store_->policy());
212   EXPECT_FALSE(store_->policy_map().empty());
213
214   Mock::VerifyAndClearExpectations(external_data_manager_.get());
215   Mock::VerifyAndClearExpectations(&observer_);
216
217   // Policy file should exist.
218   ASSERT_TRUE(base::PathExists(policy_file()));
219
220   Sequence s2;
221   EXPECT_CALL(*external_data_manager_, OnPolicyStoreLoaded()).InSequence(s2);
222   EXPECT_CALL(observer_, OnStoreLoaded(store_.get())).InSequence(s2);
223   store_->Clear();
224   RunUntilIdle();
225
226   // Policy file should not exist.
227   ASSERT_TRUE(!base::PathExists(policy_file()));
228
229   // Policy should be gone.
230   EXPECT_FALSE(store_->policy());
231   EXPECT_TRUE(store_->policy_map().empty());
232   EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
233 }
234
235 TEST_F(UserCloudPolicyStoreTest, StoreTwoTimes) {
236   EXPECT_FALSE(store_->policy());
237   EXPECT_TRUE(store_->policy_map().empty());
238
239   // Store a simple policy then store a second policy before the first one
240   // finishes validating, and make sure the second policy ends up as the active
241   // policy.
242   Sequence s1;
243   EXPECT_CALL(*external_data_manager_, OnPolicyStoreLoaded()).InSequence(s1);
244   EXPECT_CALL(observer_, OnStoreLoaded(store_.get())).InSequence(s1);
245
246   UserPolicyBuilder first_policy;
247   first_policy.payload().mutable_passwordmanagerenabled()->set_value(false);
248   first_policy.Build();
249   store_->Store(first_policy.policy());
250   RunUntilIdle();
251
252   Mock::VerifyAndClearExpectations(external_data_manager_.get());
253   Mock::VerifyAndClearExpectations(&observer_);
254
255   Sequence s2;
256   EXPECT_CALL(*external_data_manager_, OnPolicyStoreLoaded()).InSequence(s2);
257   EXPECT_CALL(observer_, OnStoreLoaded(store_.get())).InSequence(s2);
258
259   store_->Store(policy_.policy());
260   RunUntilIdle();
261
262   // Policy should be decoded and stored.
263   ASSERT_TRUE(store_->policy());
264   EXPECT_EQ(policy_.policy_data().SerializeAsString(),
265             store_->policy()->SerializeAsString());
266   VerifyPolicyMap(store_.get());
267   EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
268 }
269
270 TEST_F(UserCloudPolicyStoreTest, StoreThenLoad) {
271   // Store a simple policy and make sure it can be read back in.
272   // policy.
273   Sequence s;
274   EXPECT_CALL(*external_data_manager_, OnPolicyStoreLoaded()).InSequence(s);
275   EXPECT_CALL(observer_, OnStoreLoaded(store_.get())).InSequence(s);
276   store_->Store(policy_.policy());
277   RunUntilIdle();
278
279   // Now, make sure the policy can be read back in from a second store.
280   scoped_ptr<UserCloudPolicyStore> store2(new UserCloudPolicyStore(
281       profile_.get(), policy_file(), loop_.message_loop_proxy()));
282   store2->AddObserver(&observer_);
283   EXPECT_CALL(observer_, OnStoreLoaded(store2.get()));
284   store2->Load();
285   RunUntilIdle();
286
287   ASSERT_TRUE(store2->policy());
288   EXPECT_EQ(policy_.policy_data().SerializeAsString(),
289             store2->policy()->SerializeAsString());
290   VerifyPolicyMap(store2.get());
291   EXPECT_EQ(CloudPolicyStore::STATUS_OK, store2->status());
292   store2->RemoveObserver(&observer_);
293 }
294
295 TEST_F(UserCloudPolicyStoreTest, StoreThenLoadImmediately) {
296   // Store a simple policy and make sure it can be read back in.
297   // policy.
298   Sequence s;
299   EXPECT_CALL(*external_data_manager_, OnPolicyStoreLoaded()).InSequence(s);
300   EXPECT_CALL(observer_, OnStoreLoaded(store_.get())).InSequence(s);
301   store_->Store(policy_.policy());
302   RunUntilIdle();
303
304   // Now, make sure the policy can be read back in from a second store.
305   scoped_ptr<UserCloudPolicyStore> store2(new UserCloudPolicyStore(
306       profile_.get(), policy_file(), loop_.message_loop_proxy()));
307   store2->AddObserver(&observer_);
308   EXPECT_CALL(observer_, OnStoreLoaded(store2.get()));
309   store2->LoadImmediately();  // Should load without running the message loop.
310
311   ASSERT_TRUE(store2->policy());
312   EXPECT_EQ(policy_.policy_data().SerializeAsString(),
313             store2->policy()->SerializeAsString());
314   VerifyPolicyMap(store2.get());
315   EXPECT_EQ(CloudPolicyStore::STATUS_OK, store2->status());
316   store2->RemoveObserver(&observer_);
317 }
318
319 TEST_F(UserCloudPolicyStoreTest, StoreValidationError) {
320   // Create an invalid policy (no policy type).
321   policy_.policy_data().clear_policy_type();
322   policy_.Build();
323
324   // Store policy.
325   ExpectError(store_.get(), CloudPolicyStore::STATUS_VALIDATION_ERROR);
326   store_->Store(policy_.policy());
327   RunUntilIdle();
328   ASSERT_FALSE(store_->policy());
329 }
330
331 TEST_F(UserCloudPolicyStoreTest, LoadValidationError) {
332   // Force a validation error by changing the username after policy is stored.
333   Sequence s;
334   EXPECT_CALL(*external_data_manager_, OnPolicyStoreLoaded()).InSequence(s);
335   EXPECT_CALL(observer_, OnStoreLoaded(store_.get())).InSequence(s);
336   store_->Store(policy_.policy());
337   RunUntilIdle();
338
339   // Sign out, and sign back in as a different user, and try to load the profile
340   // data (should fail due to mismatched username).
341   SigninManagerFactory::GetForProfile(profile_.get())->SignOut();
342   SigninManagerFactory::GetForProfile(profile_.get())->SetAuthenticatedUsername(
343       "foobar@foobar.com");
344
345   scoped_ptr<UserCloudPolicyStore> store2(new UserCloudPolicyStore(
346       profile_.get(), policy_file(), loop_.message_loop_proxy()));
347   store2->AddObserver(&observer_);
348   ExpectError(store2.get(), CloudPolicyStore::STATUS_VALIDATION_ERROR);
349   store2->Load();
350   RunUntilIdle();
351
352   ASSERT_FALSE(store2->policy());
353   store2->RemoveObserver(&observer_);
354
355   // Sign out - we should be able to load the policy (don't check usernames
356   // when signed out).
357   SigninManagerFactory::GetForProfile(profile_.get())->SignOut();
358   scoped_ptr<UserCloudPolicyStore> store3(new UserCloudPolicyStore(
359       profile_.get(), policy_file(), loop_.message_loop_proxy()));
360   store3->AddObserver(&observer_);
361   EXPECT_CALL(observer_, OnStoreLoaded(store3.get()));
362   store3->Load();
363   RunUntilIdle();
364
365   ASSERT_TRUE(store3->policy());
366   store3->RemoveObserver(&observer_);
367
368   // Now start a signin as a different user - this should fail validation.
369   FakeSigninManager* signin = static_cast<FakeSigninManager*>(
370       SigninManagerFactory::GetForProfile(profile_.get()));
371   signin->set_auth_in_progress("foobar@foobar.com");
372
373   scoped_ptr<UserCloudPolicyStore> store4(new UserCloudPolicyStore(
374       profile_.get(), policy_file(), loop_.message_loop_proxy()));
375   store4->AddObserver(&observer_);
376   ExpectError(store4.get(), CloudPolicyStore::STATUS_VALIDATION_ERROR);
377   store4->Load();
378   RunUntilIdle();
379
380   ASSERT_FALSE(store4->policy());
381   store4->RemoveObserver(&observer_);
382 }
383
384 }  // namespace
385
386 }  // namespace policy