1// Copyright 2013 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/chromeos/policy/cloud_external_data_policy_observer.h"
6
7#include <utility>
8#include <vector>
9
10#include "base/files/file_path.h"
11#include "base/files/file_util.h"
12#include "base/json/json_writer.h"
13#include "base/memory/ref_counted.h"
14#include "base/message_loop/message_loop.h"
15#include "base/message_loop/message_loop_proxy.h"
16#include "base/path_service.h"
17#include "base/run_loop.h"
18#include "base/values.h"
19#include "chrome/browser/chrome_notification_types.h"
20#include "chrome/browser/chromeos/policy/cloud_external_data_manager_base_test_util.h"
21#include "chrome/browser/chromeos/policy/device_local_account.h"
22#include "chrome/browser/chromeos/policy/device_local_account_external_data_manager.h"
23#include "chrome/browser/chromeos/policy/device_local_account_policy_provider.h"
24#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
25#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
26#include "chrome/browser/chromeos/profiles/profile_helper.h"
27#include "chrome/browser/chromeos/settings/device_settings_service.h"
28#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
29#include "chrome/browser/profiles/profile.h"
30#include "chrome/common/chrome_paths.h"
31#include "chrome/test/base/testing_browser_process.h"
32#include "chrome/test/base/testing_profile.h"
33#include "chrome/test/base/testing_profile_manager.h"
34#include "components/policy/core/common/cloud/cloud_policy_core.h"
35#include "components/policy/core/common/cloud/cloud_policy_store.h"
36#include "components/policy/core/common/cloud/mock_cloud_external_data_manager.h"
37#include "components/policy/core/common/cloud/policy_builder.h"
38#include "components/policy/core/common/external_data_fetcher.h"
39#include "components/policy/core/common/mock_configuration_policy_provider.h"
40#include "components/policy/core/common/policy_map.h"
41#include "components/policy/core/common/policy_service.h"
42#include "components/policy/core/common/policy_service_impl.h"
43#include "components/policy/core/common/policy_types.h"
44#include "content/public/browser/notification_details.h"
45#include "content/public/browser/notification_service.h"
46#include "content/public/browser/notification_source.h"
47#include "net/url_request/test_url_fetcher_factory.h"
48#include "net/url_request/url_fetcher_delegate.h"
49#include "net/url_request/url_request_context_getter.h"
50#include "net/url_request/url_request_status.h"
51#include "policy/policy_constants.h"
52#include "policy/proto/cloud_policy.pb.h"
53#include "testing/gmock/include/gmock/gmock.h"
54#include "testing/gtest/include/gtest/gtest.h"
55#include "url/gurl.h"
56
57namespace em = enterprise_management;
58
59using ::testing::Mock;
60using ::testing::Return;
61using ::testing::SaveArg;
62using ::testing::_;
63
64namespace policy {
65
66namespace {
67
68const char kDeviceLocalAccount[] = "device_local_account@localhost";
69
70const char kRegularUserID[] = "user@example.com";
71
72const char kAvatar1URL[] = "http://localhost/avatar1.jpg";
73const char kAvatar2URL[] = "http://localhost/avatar2.jpg";
74
75void ConstructAvatarPolicy(const std::string& file_name,
76                           const std::string& url,
77                           std::string* policy_data,
78                           std::string* policy) {
79  base::FilePath test_data_dir;
80  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
81  ASSERT_TRUE(base::ReadFileToString(
82      test_data_dir.Append("chromeos").Append(file_name),
83      policy_data));
84  base::JSONWriter::Write(
85      test::ConstructExternalDataReference(url, *policy_data).get(),
86      policy);
87}
88
89}  // namespace
90
91class CloudExternalDataPolicyObserverTest
92    : public chromeos::DeviceSettingsTestBase,
93      public CloudExternalDataPolicyObserver::Delegate {
94 public:
95  typedef std::pair<std::string, std::string> FetchedCall;
96
97  CloudExternalDataPolicyObserverTest();
98  virtual ~CloudExternalDataPolicyObserverTest();
99
100  // chromeos::DeviceSettingsTestBase:
101  virtual void SetUp() OVERRIDE;
102  virtual void TearDown() OVERRIDE;
103
104  // CloudExternalDataPolicyObserver::Delegate:
105  virtual void OnExternalDataSet(const std::string& policy,
106                                 const std::string& user_id) OVERRIDE;
107  virtual void OnExternalDataCleared(const std::string& policy,
108                                     const std::string& user_id) OVERRIDE;
109  virtual void OnExternalDataFetched(const std::string& policy,
110                                     const std::string& user_id,
111                                     scoped_ptr<std::string> data) OVERRIDE;
112
113  void CreateObserver();
114
115  void ClearObservations();
116
117  void SetDeviceLocalAccountAvatarPolicy(const std::string& account_id,
118                                         const std::string& value);
119
120  void AddDeviceLocalAccount(const std::string& account_id);
121  void RemoveDeviceLocalAccount(const std::string& account_id);
122
123  DeviceLocalAccountPolicyBroker* GetBrokerForDeviceLocalAccountUser();
124
125  void RefreshDeviceLocalAccountPolicy(DeviceLocalAccountPolicyBroker* broker);
126
127  void LogInAsDeviceLocalAccount(const std::string& user_id);
128
129  void SetRegularUserAvatarPolicy(const std::string& value);
130
131  void LogInAsRegularUser();
132
133  const std::string device_local_account_user_id_;
134
135  std::string avatar_policy_1_data_;
136  std::string avatar_policy_2_data_;
137  std::string avatar_policy_1_;
138  std::string avatar_policy_2_;
139
140  chromeos::CrosSettings cros_settings_;
141  scoped_ptr<DeviceLocalAccountPolicyService>
142      device_local_account_policy_service_;
143  net::TestURLFetcherFactory url_fetcher_factory_;
144
145  scoped_ptr<DeviceLocalAccountPolicyProvider>
146      device_local_account_policy_provider_;
147
148  MockCloudExternalDataManager external_data_manager_;
149  MockConfigurationPolicyProvider user_policy_provider_;
150
151  scoped_ptr<TestingProfile> profile_;
152
153  scoped_ptr<CloudExternalDataPolicyObserver> observer_;
154
155  std::vector<std::string> set_calls_;
156  std::vector<std::string> cleared_calls_;
157  std::vector<FetchedCall> fetched_calls_;
158
159  ExternalDataFetcher::FetchCallback fetch_callback_;
160
161  TestingProfileManager profile_manager_;
162
163 private:
164  DISALLOW_COPY_AND_ASSIGN(CloudExternalDataPolicyObserverTest);
165};
166
167CloudExternalDataPolicyObserverTest::CloudExternalDataPolicyObserverTest()
168    : device_local_account_user_id_(GenerateDeviceLocalAccountUserId(
169          kDeviceLocalAccount,
170          DeviceLocalAccount::TYPE_PUBLIC_SESSION)),
171      cros_settings_(&device_settings_service_),
172      profile_manager_(TestingBrowserProcess::GetGlobal()) {
173}
174
175CloudExternalDataPolicyObserverTest::~CloudExternalDataPolicyObserverTest() {
176}
177
178void CloudExternalDataPolicyObserverTest::SetUp() {
179  chromeos::DeviceSettingsTestBase::SetUp();
180  ASSERT_TRUE(profile_manager_.SetUp());
181  device_local_account_policy_service_.reset(
182      new DeviceLocalAccountPolicyService(&device_settings_test_helper_,
183                                          &device_settings_service_,
184                                          &cros_settings_,
185                                          base::MessageLoopProxy::current(),
186                                          base::MessageLoopProxy::current(),
187                                          base::MessageLoopProxy::current(),
188                                          base::MessageLoopProxy::current(),
189                                          NULL));
190  url_fetcher_factory_.set_remove_fetcher_on_delete(true);
191
192  EXPECT_CALL(user_policy_provider_, IsInitializationComplete(_))
193      .WillRepeatedly(Return(true));
194  user_policy_provider_.Init();
195
196  ConstructAvatarPolicy("avatar1.jpg",
197                        kAvatar1URL,
198                        &avatar_policy_1_data_,
199                        &avatar_policy_1_);
200  ConstructAvatarPolicy("avatar2.jpg",
201                        kAvatar2URL,
202                        &avatar_policy_2_data_,
203                        &avatar_policy_2_);
204}
205
206void CloudExternalDataPolicyObserverTest::TearDown() {
207  observer_.reset();
208  user_policy_provider_.Shutdown();
209  profile_.reset();
210  if (device_local_account_policy_provider_) {
211    device_local_account_policy_provider_->Shutdown();
212    device_local_account_policy_provider_.reset();
213  }
214  device_local_account_policy_service_->Shutdown();
215  device_local_account_policy_service_.reset();
216  chromeos::DeviceSettingsTestBase::TearDown();
217}
218
219
220void CloudExternalDataPolicyObserverTest::OnExternalDataSet(
221    const std::string& policy,
222    const std::string& user_id) {
223  EXPECT_EQ(key::kUserAvatarImage, policy);
224  set_calls_.push_back(user_id);
225}
226
227void CloudExternalDataPolicyObserverTest::OnExternalDataCleared(
228    const std::string& policy,
229    const std::string& user_id) {
230  EXPECT_EQ(key::kUserAvatarImage, policy);
231  cleared_calls_.push_back(user_id);
232}
233
234void CloudExternalDataPolicyObserverTest::OnExternalDataFetched(
235    const std::string& policy,
236    const std::string& user_id,
237    scoped_ptr<std::string> data) {
238  EXPECT_EQ(key::kUserAvatarImage, policy);
239  fetched_calls_.push_back(make_pair(user_id, std::string()));
240  fetched_calls_.back().second.swap(*data);
241}
242
243void CloudExternalDataPolicyObserverTest::CreateObserver() {
244  observer_.reset(new CloudExternalDataPolicyObserver(
245      &cros_settings_,
246      device_local_account_policy_service_.get(),
247      key::kUserAvatarImage,
248      this));
249  observer_->Init();
250}
251
252void CloudExternalDataPolicyObserverTest::ClearObservations() {
253  set_calls_.clear();
254  cleared_calls_.clear();
255  fetched_calls_.clear();
256}
257
258void CloudExternalDataPolicyObserverTest::SetDeviceLocalAccountAvatarPolicy(
259    const std::string& account_id,
260    const std::string& value) {
261  UserPolicyBuilder builder;
262  builder.policy_data().set_policy_type(
263      dm_protocol::kChromePublicAccountPolicyType);
264  builder.policy_data().set_settings_entity_id(account_id);
265  builder.policy_data().set_username(account_id);
266  if (!value.empty())
267    builder.payload().mutable_useravatarimage()->set_value(value);
268  builder.Build();
269  device_settings_test_helper_.set_device_local_account_policy_blob(
270      account_id,
271      builder.GetBlob());
272}
273
274void CloudExternalDataPolicyObserverTest::AddDeviceLocalAccount(
275    const std::string& account_id) {
276  em::DeviceLocalAccountInfoProto* account =
277      device_policy_.payload().mutable_device_local_accounts()->add_account();
278  account->set_account_id(account_id);
279  account->set_type(
280      em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION);
281  device_policy_.Build();
282  device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob());
283  ReloadDeviceSettings();
284}
285
286void CloudExternalDataPolicyObserverTest::RemoveDeviceLocalAccount(
287    const std::string& account_id) {
288  em::DeviceLocalAccountsProto* accounts =
289      device_policy_.payload().mutable_device_local_accounts();
290  std::vector<std::string> account_ids;
291  for (int i = 0; i < accounts->account_size(); ++i) {
292    if (accounts->account(i).account_id() != account_id)
293      account_ids.push_back(accounts->account(i).account_id());
294  }
295  accounts->clear_account();
296  for (std::vector<std::string>::const_iterator it = account_ids.begin();
297       it != account_ids.end(); ++it) {
298    em::DeviceLocalAccountInfoProto* account = accounts->add_account();
299    account->set_account_id(*it);
300    account->set_type(
301        em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION);
302  }
303  device_policy_.Build();
304  device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob());
305  ReloadDeviceSettings();
306}
307
308DeviceLocalAccountPolicyBroker*
309    CloudExternalDataPolicyObserverTest::GetBrokerForDeviceLocalAccountUser() {
310  return device_local_account_policy_service_->GetBrokerForUser(
311      device_local_account_user_id_);
312}
313
314void CloudExternalDataPolicyObserverTest::RefreshDeviceLocalAccountPolicy(
315    DeviceLocalAccountPolicyBroker* broker) {
316  broker->core()->store()->Load();
317  device_settings_test_helper_.Flush();
318}
319
320void CloudExternalDataPolicyObserverTest::LogInAsDeviceLocalAccount(
321    const std::string& user_id) {
322  user_manager_->AddUser(user_id);
323
324  device_local_account_policy_provider_.reset(
325      new DeviceLocalAccountPolicyProvider(
326          user_id,
327          device_local_account_policy_service_.get(),
328          scoped_ptr<PolicyMap>()));
329
330  PolicyServiceImpl::Providers providers;
331  providers.push_back(device_local_account_policy_provider_.get());
332  TestingProfile::Builder builder;
333  builder.SetPolicyService(
334      scoped_ptr<PolicyService>(new PolicyServiceImpl(providers)));
335  builder.SetPath(chromeos::ProfileHelper::Get()->GetProfilePathByUserIdHash(
336      chromeos::ProfileHelper::GetUserIdHashByUserIdForTesting(user_id)));
337
338  profile_ = builder.Build();
339  profile_->set_profile_name(user_id);
340
341  content::NotificationService::current()->Notify(
342      chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
343      content::NotificationService::AllSources(),
344      content::Details<Profile>(profile_.get()));
345}
346
347void CloudExternalDataPolicyObserverTest::SetRegularUserAvatarPolicy(
348    const std::string& value) {
349  PolicyMap policy_map;
350  if (!value.empty()) {
351    policy_map.Set(
352        key::kUserAvatarImage,
353        POLICY_LEVEL_MANDATORY,
354        POLICY_SCOPE_USER,
355        new base::StringValue(value),
356        external_data_manager_.CreateExternalDataFetcher(
357            key::kUserAvatarImage).release());
358  }
359  user_policy_provider_.UpdateChromePolicy(policy_map);
360}
361
362void CloudExternalDataPolicyObserverTest::LogInAsRegularUser() {
363  user_manager_->AddUser(kRegularUserID);
364
365  PolicyServiceImpl::Providers providers;
366  providers.push_back(&user_policy_provider_);
367  TestingProfile::Builder builder;
368  builder.SetPolicyService(
369      scoped_ptr<PolicyService>(new PolicyServiceImpl(providers)));
370  builder.SetPath(chromeos::ProfileHelper::Get()->GetProfilePathByUserIdHash(
371      chromeos::ProfileHelper::GetUserIdHashByUserIdForTesting(
372          kRegularUserID)));
373
374  profile_ = builder.Build();
375  profile_->set_profile_name(kRegularUserID);
376
377  content::NotificationService::current()->Notify(
378      chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
379      content::NotificationService::AllSources(),
380      content::Details<Profile>(profile_.get()));
381}
382
383// Verifies that when an external data reference is set for a device-local
384// account, a corresponding notification is emitted and a fetch is started.
385// Further verifies that when the fetch succeeds, a notification containing the
386// external data is emitted.
387TEST_F(CloudExternalDataPolicyObserverTest,
388       ExistingDeviceLocalAccountFetchSuccess) {
389  SetDeviceLocalAccountAvatarPolicy(kDeviceLocalAccount, avatar_policy_1_);
390  AddDeviceLocalAccount(kDeviceLocalAccount);
391
392  DeviceLocalAccountPolicyBroker* broker = GetBrokerForDeviceLocalAccountUser();
393  ASSERT_TRUE(broker);
394  broker->external_data_manager()->Connect(NULL);
395  base::RunLoop().RunUntilIdle();
396
397  CreateObserver();
398
399  EXPECT_TRUE(cleared_calls_.empty());
400  EXPECT_TRUE(fetched_calls_.empty());
401  ASSERT_EQ(1u, set_calls_.size());
402  EXPECT_EQ(device_local_account_user_id_, set_calls_.front());
403  ClearObservations();
404
405  net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
406  ASSERT_TRUE(fetcher);
407  EXPECT_EQ(GURL(kAvatar1URL), fetcher->GetOriginalURL());
408
409  fetcher->SetResponseString(avatar_policy_1_data_);
410  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
411                                            net::OK));
412  fetcher->set_response_code(200);
413  fetcher->delegate()->OnURLFetchComplete(fetcher);
414  base::RunLoop().RunUntilIdle();
415
416  EXPECT_TRUE(set_calls_.empty());
417  EXPECT_TRUE(cleared_calls_.empty());
418  ASSERT_EQ(1u, fetched_calls_.size());
419  EXPECT_EQ(device_local_account_user_id_, fetched_calls_.front().first);
420  EXPECT_EQ(avatar_policy_1_data_, fetched_calls_.front().second);
421  ClearObservations();
422
423  EXPECT_FALSE(url_fetcher_factory_.GetFetcherByID(1));
424}
425
426// Verifies that when an external data reference is set for a device-local
427// account, a corresponding notification is emitted and a fetch is started.
428// Further verifies that when the fetch fails, no notification is emitted.
429TEST_F(CloudExternalDataPolicyObserverTest,
430       ExistingDeviceLocalAccountFetchFailure) {
431  SetDeviceLocalAccountAvatarPolicy(kDeviceLocalAccount, avatar_policy_1_);
432  AddDeviceLocalAccount(kDeviceLocalAccount);
433
434  DeviceLocalAccountPolicyBroker* broker = GetBrokerForDeviceLocalAccountUser();
435  ASSERT_TRUE(broker);
436  broker->external_data_manager()->Connect(NULL);
437  base::RunLoop().RunUntilIdle();
438
439  CreateObserver();
440
441  EXPECT_TRUE(cleared_calls_.empty());
442  EXPECT_TRUE(fetched_calls_.empty());
443  ASSERT_EQ(1u, set_calls_.size());
444  EXPECT_EQ(device_local_account_user_id_, set_calls_.front());
445  ClearObservations();
446
447  net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
448  ASSERT_TRUE(fetcher);
449  EXPECT_EQ(GURL(kAvatar1URL), fetcher->GetOriginalURL());
450
451  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
452                                            net::OK));
453  fetcher->set_response_code(400);
454  fetcher->delegate()->OnURLFetchComplete(fetcher);
455  base::RunLoop().RunUntilIdle();
456
457  EXPECT_TRUE(set_calls_.empty());
458  EXPECT_TRUE(cleared_calls_.empty());
459  EXPECT_TRUE(fetched_calls_.empty());
460  ClearObservations();
461
462  EXPECT_FALSE(url_fetcher_factory_.GetFetcherByID(1));
463}
464
465// Verifies that when the external data reference for a device-local account is
466// initially not set, no notifications are emitted. Further verifies that when
467// the external data reference is then cleared (which is a no-op), again, no
468// notifications are emitted.
469TEST_F(CloudExternalDataPolicyObserverTest,
470       ExistingDeviceLocalAccountClearUnset) {
471  AddDeviceLocalAccount(kDeviceLocalAccount);
472
473  DeviceLocalAccountPolicyBroker* broker = GetBrokerForDeviceLocalAccountUser();
474  ASSERT_TRUE(broker);
475  broker->external_data_manager()->Connect(NULL);
476  base::RunLoop().RunUntilIdle();
477
478  CreateObserver();
479
480  EXPECT_TRUE(set_calls_.empty());
481  EXPECT_TRUE(cleared_calls_.empty());
482  EXPECT_TRUE(fetched_calls_.empty());
483  ClearObservations();
484
485  EXPECT_FALSE(url_fetcher_factory_.GetFetcherByID(0));
486
487  SetDeviceLocalAccountAvatarPolicy(kDeviceLocalAccount, "");
488  RefreshDeviceLocalAccountPolicy(broker);
489
490  EXPECT_TRUE(set_calls_.empty());
491  EXPECT_TRUE(cleared_calls_.empty());
492  EXPECT_TRUE(fetched_calls_.empty());
493  ClearObservations();
494
495  EXPECT_FALSE(url_fetcher_factory_.GetFetcherByID(0));
496}
497
498// Verifies that when the external data reference for a device-local account is
499// initially set, a corresponding notification is emitted and a fetch is
500// started. Further verifies that when the external data reference is then
501// cleared, a corresponding notification is emitted and the fetch is canceled.
502TEST_F(CloudExternalDataPolicyObserverTest,
503       ExistingDeviceLocalAccountClearSet) {
504  SetDeviceLocalAccountAvatarPolicy(kDeviceLocalAccount, avatar_policy_1_);
505  AddDeviceLocalAccount(kDeviceLocalAccount);
506
507  DeviceLocalAccountPolicyBroker* broker = GetBrokerForDeviceLocalAccountUser();
508  ASSERT_TRUE(broker);
509  broker->external_data_manager()->Connect(NULL);
510  base::RunLoop().RunUntilIdle();
511
512  CreateObserver();
513
514  EXPECT_TRUE(cleared_calls_.empty());
515  EXPECT_TRUE(fetched_calls_.empty());
516  ASSERT_EQ(1u, set_calls_.size());
517  EXPECT_EQ(device_local_account_user_id_, set_calls_.front());
518  ClearObservations();
519
520  net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
521  ASSERT_TRUE(fetcher);
522  EXPECT_EQ(GURL(kAvatar1URL), fetcher->GetOriginalURL());
523
524  SetDeviceLocalAccountAvatarPolicy(kDeviceLocalAccount, "");
525  RefreshDeviceLocalAccountPolicy(broker);
526
527  EXPECT_TRUE(set_calls_.empty());
528  EXPECT_TRUE(fetched_calls_.empty());
529  ASSERT_EQ(1u, cleared_calls_.size());
530  EXPECT_EQ(device_local_account_user_id_, cleared_calls_.front());
531  ClearObservations();
532
533  EXPECT_FALSE(url_fetcher_factory_.GetFetcherByID(0));
534}
535
536// Verifies that when the external data reference for a device-local account is
537// initially not set, no notifications are emitted. Further verifies that when
538// the external data reference is then set, a corresponding notification is
539// emitted and a fetch is started. Also verifies that when the fetch eventually
540// succeeds, a notification containing the external data is emitted.
541TEST_F(CloudExternalDataPolicyObserverTest,
542       ExistingDeviceLocalAccountSetUnset) {
543  AddDeviceLocalAccount(kDeviceLocalAccount);
544
545  DeviceLocalAccountPolicyBroker* broker = GetBrokerForDeviceLocalAccountUser();
546  ASSERT_TRUE(broker);
547  broker->external_data_manager()->Connect(NULL);
548  base::RunLoop().RunUntilIdle();
549
550  CreateObserver();
551
552  EXPECT_TRUE(set_calls_.empty());
553  EXPECT_TRUE(cleared_calls_.empty());
554  EXPECT_TRUE(fetched_calls_.empty());
555  ClearObservations();
556
557  SetDeviceLocalAccountAvatarPolicy(kDeviceLocalAccount, avatar_policy_1_);
558  RefreshDeviceLocalAccountPolicy(broker);
559
560  EXPECT_TRUE(cleared_calls_.empty());
561  EXPECT_TRUE(fetched_calls_.empty());
562  ASSERT_EQ(1u, set_calls_.size());
563  EXPECT_EQ(device_local_account_user_id_, set_calls_.front());
564  ClearObservations();
565
566  net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
567  ASSERT_TRUE(fetcher);
568  EXPECT_EQ(GURL(kAvatar1URL), fetcher->GetOriginalURL());
569
570  fetcher->SetResponseString(avatar_policy_1_data_);
571  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
572                                            net::OK));
573  fetcher->set_response_code(200);
574  fetcher->delegate()->OnURLFetchComplete(fetcher);
575  base::RunLoop().RunUntilIdle();
576
577  EXPECT_TRUE(set_calls_.empty());
578  EXPECT_TRUE(cleared_calls_.empty());
579  ASSERT_EQ(1u, fetched_calls_.size());
580  EXPECT_EQ(device_local_account_user_id_, fetched_calls_.front().first);
581  EXPECT_EQ(avatar_policy_1_data_, fetched_calls_.front().second);
582  ClearObservations();
583
584  EXPECT_FALSE(url_fetcher_factory_.GetFetcherByID(1));
585}
586
587// Verifies that when the external data reference for a device-local account is
588// initially set, a corresponding notification is emitted and a fetch is
589// started. Further verifies that when the external data reference is then
590// updated, a corresponding notification is emitted and the fetch is restarted.
591// Also verifies that when the fetch eventually succeeds, a notification
592// containing the external data is emitted.
593TEST_F(CloudExternalDataPolicyObserverTest, ExistingDeviceLocalAccountSetSet) {
594  SetDeviceLocalAccountAvatarPolicy(kDeviceLocalAccount, avatar_policy_1_);
595  AddDeviceLocalAccount(kDeviceLocalAccount);
596
597  DeviceLocalAccountPolicyBroker* broker = GetBrokerForDeviceLocalAccountUser();
598  ASSERT_TRUE(broker);
599  broker->external_data_manager()->Connect(NULL);
600  base::RunLoop().RunUntilIdle();
601
602  CreateObserver();
603
604  EXPECT_TRUE(cleared_calls_.empty());
605  EXPECT_TRUE(fetched_calls_.empty());
606  ASSERT_EQ(1u, set_calls_.size());
607  EXPECT_EQ(device_local_account_user_id_, set_calls_.front());
608  ClearObservations();
609
610  net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
611  ASSERT_TRUE(fetcher);
612  EXPECT_EQ(GURL(kAvatar1URL), fetcher->GetOriginalURL());
613
614  SetDeviceLocalAccountAvatarPolicy(kDeviceLocalAccount, avatar_policy_2_);
615  RefreshDeviceLocalAccountPolicy(broker);
616
617  EXPECT_TRUE(cleared_calls_.empty());
618  EXPECT_TRUE(fetched_calls_.empty());
619  ASSERT_EQ(1u, set_calls_.size());
620  EXPECT_EQ(device_local_account_user_id_, set_calls_.front());
621  ClearObservations();
622
623  fetcher = url_fetcher_factory_.GetFetcherByID(1);
624  ASSERT_TRUE(fetcher);
625  EXPECT_EQ(GURL(kAvatar2URL), fetcher->GetOriginalURL());
626
627  fetcher->SetResponseString(avatar_policy_2_data_);
628  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
629                                            net::OK));
630  fetcher->set_response_code(200);
631  fetcher->delegate()->OnURLFetchComplete(fetcher);
632  base::RunLoop().RunUntilIdle();
633
634  EXPECT_TRUE(set_calls_.empty());
635  EXPECT_TRUE(cleared_calls_.empty());
636  ASSERT_EQ(1u, fetched_calls_.size());
637  EXPECT_EQ(device_local_account_user_id_, fetched_calls_.front().first);
638  EXPECT_EQ(avatar_policy_2_data_, fetched_calls_.front().second);
639  ClearObservations();
640
641  EXPECT_FALSE(url_fetcher_factory_.GetFetcherByID(2));
642}
643
644// Verifies that when the external data reference for a device-local account is
645// initially not set, no notifications are emitted during login into the
646// account. Further verifies that when the external data reference is then set,
647// a corresponding notification is emitted only once and a fetch is started.
648// Also verifies that when the fetch eventually succeeds, a notification
649// containing the external data is emitted, again, only once.
650TEST_F(CloudExternalDataPolicyObserverTest,
651       ExistingDeviceLocalAccountSetAfterLogin) {
652  AddDeviceLocalAccount(kDeviceLocalAccount);
653
654  DeviceLocalAccountPolicyBroker* broker = GetBrokerForDeviceLocalAccountUser();
655  ASSERT_TRUE(broker);
656  broker->external_data_manager()->Connect(NULL);
657  base::RunLoop().RunUntilIdle();
658
659  CreateObserver();
660
661  LogInAsDeviceLocalAccount(kDeviceLocalAccount);
662
663  EXPECT_TRUE(set_calls_.empty());
664  EXPECT_TRUE(cleared_calls_.empty());
665  EXPECT_TRUE(fetched_calls_.empty());
666  ClearObservations();
667
668  SetDeviceLocalAccountAvatarPolicy(kDeviceLocalAccount, avatar_policy_1_);
669  RefreshDeviceLocalAccountPolicy(broker);
670
671  EXPECT_TRUE(cleared_calls_.empty());
672  EXPECT_TRUE(fetched_calls_.empty());
673  ASSERT_EQ(1u, set_calls_.size());
674  EXPECT_EQ(device_local_account_user_id_, set_calls_.front());
675  ClearObservations();
676
677  net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
678  ASSERT_TRUE(fetcher);
679  EXPECT_EQ(GURL(kAvatar1URL), fetcher->GetOriginalURL());
680
681  fetcher->SetResponseString(avatar_policy_1_data_);
682  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
683                                            net::OK));
684  fetcher->set_response_code(200);
685  fetcher->delegate()->OnURLFetchComplete(fetcher);
686  base::RunLoop().RunUntilIdle();
687
688  EXPECT_TRUE(set_calls_.empty());
689  EXPECT_TRUE(cleared_calls_.empty());
690  ASSERT_EQ(1u, fetched_calls_.size());
691  EXPECT_EQ(device_local_account_user_id_, fetched_calls_.front().first);
692  EXPECT_EQ(avatar_policy_1_data_, fetched_calls_.front().second);
693  ClearObservations();
694
695  EXPECT_FALSE(url_fetcher_factory_.GetFetcherByID(1));
696}
697
698// Verifies that when the external data reference for a device-local account is
699// initially not set, no notifications are emitted. Further verifies that when
700// the device-local account is then removed, again, no notifications are sent.
701TEST_F(CloudExternalDataPolicyObserverTest,
702       ExistingDeviceLocalAccountRemoveAccountUnset) {
703  AddDeviceLocalAccount(kDeviceLocalAccount);
704
705  DeviceLocalAccountPolicyBroker* broker = GetBrokerForDeviceLocalAccountUser();
706  ASSERT_TRUE(broker);
707  broker->external_data_manager()->Connect(NULL);
708  base::RunLoop().RunUntilIdle();
709
710  CreateObserver();
711
712  EXPECT_TRUE(set_calls_.empty());
713  EXPECT_TRUE(cleared_calls_.empty());
714  EXPECT_TRUE(fetched_calls_.empty());
715  ClearObservations();
716
717  EXPECT_FALSE(url_fetcher_factory_.GetFetcherByID(0));
718
719  RemoveDeviceLocalAccount(kDeviceLocalAccount);
720
721  EXPECT_TRUE(set_calls_.empty());
722  EXPECT_TRUE(cleared_calls_.empty());
723  EXPECT_TRUE(fetched_calls_.empty());
724  ClearObservations();
725
726  EXPECT_FALSE(url_fetcher_factory_.GetFetcherByID(0));
727}
728
729// Verifies that when the external data reference for a device-local account is
730// initially set, a corresponding notification is emitted and a fetch is
731// started. Further verifies that when the device-local account is then removed,
732// a notification indicating that the external data reference has been cleared
733// is emitted and the fetch is canceled.
734TEST_F(CloudExternalDataPolicyObserverTest,
735       ExistingDeviceLocalAccountRemoveAccountSet) {
736  SetDeviceLocalAccountAvatarPolicy(kDeviceLocalAccount, avatar_policy_1_);
737  AddDeviceLocalAccount(kDeviceLocalAccount);
738
739  DeviceLocalAccountPolicyBroker* broker = GetBrokerForDeviceLocalAccountUser();
740  ASSERT_TRUE(broker);
741  broker->external_data_manager()->Connect(NULL);
742  base::RunLoop().RunUntilIdle();
743
744  CreateObserver();
745
746  EXPECT_TRUE(cleared_calls_.empty());
747  EXPECT_TRUE(fetched_calls_.empty());
748  ASSERT_EQ(1u, set_calls_.size());
749  EXPECT_EQ(device_local_account_user_id_, set_calls_.front());
750  ClearObservations();
751
752  net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
753  ASSERT_TRUE(fetcher);
754  EXPECT_EQ(GURL(kAvatar1URL), fetcher->GetOriginalURL());
755
756  RemoveDeviceLocalAccount(kDeviceLocalAccount);
757
758  EXPECT_TRUE(set_calls_.empty());
759  EXPECT_TRUE(fetched_calls_.empty());
760  ASSERT_EQ(1u, cleared_calls_.size());
761  EXPECT_EQ(device_local_account_user_id_, cleared_calls_.front());
762  ClearObservations();
763
764  EXPECT_FALSE(url_fetcher_factory_.GetFetcherByID(0));
765}
766
767// Verifies that when an external data reference is set for a regular user and
768// the user logs in, a corresponding notification is emitted and a fetch is
769// started. Further verifies that when the fetch succeeds, a notification
770// containing the external data is emitted.
771TEST_F(CloudExternalDataPolicyObserverTest, RegularUserFetchSuccess) {
772  SetRegularUserAvatarPolicy(avatar_policy_1_);
773
774  CreateObserver();
775
776  EXPECT_CALL(external_data_manager_, Fetch(key::kUserAvatarImage, _))
777      .Times(1)
778      .WillOnce(SaveArg<1>(&fetch_callback_));
779
780  LogInAsRegularUser();
781
782  EXPECT_TRUE(cleared_calls_.empty());
783  EXPECT_TRUE(fetched_calls_.empty());
784  ASSERT_EQ(1u, set_calls_.size());
785  EXPECT_EQ(kRegularUserID, set_calls_.front());
786  ClearObservations();
787
788  Mock::VerifyAndClear(&external_data_manager_);
789  EXPECT_CALL(external_data_manager_, Fetch(key::kUserAvatarImage, _)).Times(0);
790
791  fetch_callback_.Run(make_scoped_ptr(new std::string(avatar_policy_1_data_)));
792
793  EXPECT_TRUE(set_calls_.empty());
794  EXPECT_TRUE(cleared_calls_.empty());
795  ASSERT_EQ(1u, fetched_calls_.size());
796  EXPECT_EQ(kRegularUserID, fetched_calls_.front().first);
797  EXPECT_EQ(avatar_policy_1_data_, fetched_calls_.front().second);
798  ClearObservations();
799}
800
801// Verifies that when the external data reference for a regular user is not set
802// while the user is logging in, no notifications are emitted. Further verifies
803// that when the external data reference is then cleared (which is a no-op),
804// again, no notifications are emitted.
805TEST_F(CloudExternalDataPolicyObserverTest, RegularUserClearUnset) {
806  CreateObserver();
807
808  EXPECT_CALL(external_data_manager_, Fetch(key::kUserAvatarImage, _)).Times(0);
809
810  LogInAsRegularUser();
811
812  EXPECT_TRUE(set_calls_.empty());
813  EXPECT_TRUE(cleared_calls_.empty());
814  EXPECT_TRUE(fetched_calls_.empty());
815  ClearObservations();
816
817  Mock::VerifyAndClear(&external_data_manager_);
818  EXPECT_CALL(external_data_manager_, Fetch(key::kUserAvatarImage, _)).Times(0);
819
820  SetRegularUserAvatarPolicy("");
821
822  EXPECT_TRUE(set_calls_.empty());
823  EXPECT_TRUE(cleared_calls_.empty());
824  EXPECT_TRUE(fetched_calls_.empty());
825  ClearObservations();
826}
827
828// Verifies that when the external data reference for a regular user is set
829// while the user is logging in, a corresponding notification is emitted and a
830// fetch is started. Further verifies that when the external data reference is
831// then cleared, a corresponding notification is emitted and no new fetch is
832// started.
833TEST_F(CloudExternalDataPolicyObserverTest, RegularUserClearSet) {
834  SetRegularUserAvatarPolicy(avatar_policy_1_);
835
836  CreateObserver();
837
838  EXPECT_CALL(external_data_manager_, Fetch(key::kUserAvatarImage, _))
839      .Times(1)
840      .WillOnce(SaveArg<1>(&fetch_callback_));
841
842  LogInAsRegularUser();
843
844  EXPECT_TRUE(cleared_calls_.empty());
845  EXPECT_TRUE(fetched_calls_.empty());
846  ASSERT_EQ(1u, set_calls_.size());
847  EXPECT_EQ(kRegularUserID, set_calls_.front());
848  ClearObservations();
849
850  Mock::VerifyAndClear(&external_data_manager_);
851  EXPECT_CALL(external_data_manager_, Fetch(key::kUserAvatarImage, _)).Times(0);
852
853  SetRegularUserAvatarPolicy("");
854
855  EXPECT_TRUE(set_calls_.empty());
856  EXPECT_TRUE(fetched_calls_.empty());
857  ASSERT_EQ(1u, cleared_calls_.size());
858  EXPECT_EQ(kRegularUserID, cleared_calls_.front());
859  ClearObservations();
860}
861
862
863// Verifies that when the external data reference for a regular user is not set
864// while the user is logging in, no notifications are emitted. Further verifies
865// that when the external data reference is then set, a corresponding
866// notification is emitted and a fetch is started. Also verifies that when the
867// fetch eventually succeeds, a notification containing the external data is
868// emitted.
869TEST_F(CloudExternalDataPolicyObserverTest, RegularUserSetUnset) {
870  CreateObserver();
871
872  EXPECT_CALL(external_data_manager_, Fetch(key::kUserAvatarImage, _)).Times(0);
873
874  LogInAsRegularUser();
875
876  EXPECT_TRUE(set_calls_.empty());
877  EXPECT_TRUE(cleared_calls_.empty());
878  EXPECT_TRUE(fetched_calls_.empty());
879  ClearObservations();
880
881  Mock::VerifyAndClear(&external_data_manager_);
882  EXPECT_CALL(external_data_manager_, Fetch(key::kUserAvatarImage, _))
883      .Times(1)
884      .WillOnce(SaveArg<1>(&fetch_callback_));
885
886  SetRegularUserAvatarPolicy(avatar_policy_1_);
887
888  EXPECT_TRUE(cleared_calls_.empty());
889  EXPECT_TRUE(fetched_calls_.empty());
890  ASSERT_EQ(1u, set_calls_.size());
891  EXPECT_EQ(kRegularUserID, set_calls_.front());
892  ClearObservations();
893
894  Mock::VerifyAndClear(&external_data_manager_);
895  EXPECT_CALL(external_data_manager_, Fetch(key::kUserAvatarImage, _)).Times(0);
896
897  fetch_callback_.Run(make_scoped_ptr(new std::string(avatar_policy_1_data_)));
898
899  EXPECT_TRUE(set_calls_.empty());
900  EXPECT_TRUE(cleared_calls_.empty());
901  ASSERT_EQ(1u, fetched_calls_.size());
902  EXPECT_EQ(kRegularUserID, fetched_calls_.front().first);
903  EXPECT_EQ(avatar_policy_1_data_, fetched_calls_.front().second);
904  ClearObservations();
905}
906
907// Verifies that when the external data reference for a regular user is set
908// while the user is logging in, a corresponding notification is emitted and a
909// fetch is started. Further verifies that when the external data reference is
910// then updated, a corresponding notification is emitted and the fetch is
911// restarted. Also verifies that when the fetch eventually succeeds, a
912// notification containing the external data is emitted.
913TEST_F(CloudExternalDataPolicyObserverTest, RegularUserSetSet) {
914  SetRegularUserAvatarPolicy(avatar_policy_1_);
915
916  CreateObserver();
917
918  EXPECT_CALL(external_data_manager_, Fetch(key::kUserAvatarImage, _))
919      .Times(1)
920      .WillOnce(SaveArg<1>(&fetch_callback_));
921
922  LogInAsRegularUser();
923
924  EXPECT_TRUE(cleared_calls_.empty());
925  EXPECT_TRUE(fetched_calls_.empty());
926  ASSERT_EQ(1u, set_calls_.size());
927  EXPECT_EQ(kRegularUserID, set_calls_.front());
928  ClearObservations();
929
930  Mock::VerifyAndClear(&external_data_manager_);
931  EXPECT_CALL(external_data_manager_, Fetch(key::kUserAvatarImage, _))
932      .Times(1)
933      .WillOnce(SaveArg<1>(&fetch_callback_));
934
935  SetRegularUserAvatarPolicy(avatar_policy_2_);
936
937  EXPECT_TRUE(cleared_calls_.empty());
938  EXPECT_TRUE(fetched_calls_.empty());
939  ASSERT_EQ(1u, set_calls_.size());
940  EXPECT_EQ(kRegularUserID, set_calls_.front());
941  ClearObservations();
942
943  Mock::VerifyAndClear(&external_data_manager_);
944  EXPECT_CALL(external_data_manager_, Fetch(key::kUserAvatarImage, _)).Times(0);
945
946  fetch_callback_.Run(make_scoped_ptr(new std::string(avatar_policy_2_data_)));
947
948  EXPECT_TRUE(set_calls_.empty());
949  EXPECT_TRUE(cleared_calls_.empty());
950  ASSERT_EQ(1u, fetched_calls_.size());
951  EXPECT_EQ(kRegularUserID, fetched_calls_.front().first);
952  EXPECT_EQ(avatar_policy_2_data_, fetched_calls_.front().second);
953  ClearObservations();
954}
955
956}  // namespace policy
957