Home | History | Annotate | Download | only in prefs
      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 <string>
      6 
      7 #include "base/json/json_string_value_serializer.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/time/time.h"
     10 #include "base/values.h"
     11 #include "chrome/browser/policy/browser_policy_connector.h"
     12 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
     13 #include "chrome/browser/policy/policy_map.h"
     14 #include "chrome/browser/prefs/synced_pref_change_registrar.h"
     15 #include "chrome/browser/ui/browser.h"
     16 #include "chrome/common/pref_names.h"
     17 #include "chrome/test/base/in_process_browser_test.h"
     18 #include "chrome/test/base/testing_pref_service_syncable.h"
     19 #include "chrome/test/base/testing_profile.h"
     20 #include "content/public/test/test_utils.h"
     21 #include "policy/policy_constants.h"
     22 #include "sync/api/sync_change.h"
     23 #include "sync/api/sync_error_factory.h"
     24 #include "sync/api/sync_error_factory_mock.h"
     25 #include "sync/api/syncable_service.h"
     26 #include "sync/protocol/sync.pb.h"
     27 
     28 namespace {
     29 
     30 using testing::AnyNumber;
     31 using testing::Return;
     32 using testing::_;
     33 
     34 class TestSyncProcessorStub : public syncer::SyncChangeProcessor {
     35   virtual syncer::SyncError ProcessSyncChanges(
     36       const tracked_objects::Location& from_here,
     37       const syncer::SyncChangeList& change_list) OVERRIDE {
     38     return syncer::SyncError();
     39   }
     40 };
     41 
     42 class SyncedPrefChangeRegistrarTest : public InProcessBrowserTest {
     43  public:
     44   SyncedPrefChangeRegistrarTest() : next_sync_data_id_(0) {}
     45   virtual ~SyncedPrefChangeRegistrarTest() {}
     46 
     47   void UpdateChromePolicy(const policy::PolicyMap& policies) {
     48     policy_provider_.UpdateChromePolicy(policies);
     49     DCHECK(base::MessageLoop::current());
     50     base::RunLoop loop;
     51     loop.RunUntilIdle();
     52   }
     53 
     54   void SetBooleanPrefValueFromSync(const std::string& name, bool value) {
     55     std::string serialized_value;
     56     JSONStringValueSerializer json(&serialized_value);
     57     json.Serialize(base::FundamentalValue(value));
     58 
     59     sync_pb::EntitySpecifics specifics;
     60     sync_pb::PreferenceSpecifics* pref_specifics =
     61         specifics.mutable_preference();
     62     pref_specifics->set_name(name);
     63     pref_specifics->set_value(serialized_value);
     64 
     65     syncer::SyncData change_data = syncer::SyncData::CreateRemoteData(
     66         ++next_sync_data_id_, specifics, base::Time());
     67     syncer::SyncChange change(
     68         FROM_HERE, syncer::SyncChange::ACTION_UPDATE, change_data);
     69 
     70     syncer::SyncChangeList change_list;
     71     change_list.push_back(change);
     72 
     73     syncer_->ProcessSyncChanges(FROM_HERE, change_list);
     74   }
     75 
     76   void SetBooleanPrefValueFromLocal(const std::string& name, bool value) {
     77     prefs_->SetBoolean(name.c_str(), value);
     78   }
     79 
     80   bool GetBooleanPrefValue(const std::string& name) {
     81     return prefs_->GetBoolean(name.c_str());
     82   }
     83 
     84   PrefServiceSyncable* prefs() const {
     85     return prefs_;
     86   }
     87 
     88   SyncedPrefChangeRegistrar* registrar() const {
     89     return registrar_.get();
     90   }
     91 
     92  private:
     93   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
     94     EXPECT_CALL(policy_provider_, IsInitializationComplete(_))
     95         .WillRepeatedly(Return(true));
     96     EXPECT_CALL(policy_provider_, RegisterPolicyDomain(_)).Times(AnyNumber());
     97     policy::BrowserPolicyConnector::SetPolicyProviderForTesting(
     98         &policy_provider_);
     99   }
    100 
    101   virtual void SetUpOnMainThread() OVERRIDE {
    102     prefs_ = PrefServiceSyncable::FromProfile(browser()->profile());
    103     syncer_ = prefs_->GetSyncableService(syncer::PREFERENCES);
    104     syncer_->MergeDataAndStartSyncing(
    105         syncer::PREFERENCES,
    106         syncer::SyncDataList(),
    107         scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
    108         scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock));
    109     registrar_.reset(new SyncedPrefChangeRegistrar(prefs_));
    110   }
    111 
    112   virtual void CleanUpOnMainThread() OVERRIDE {
    113     registrar_.reset();
    114   }
    115 
    116   PrefServiceSyncable* prefs_;
    117   syncer::SyncableService* syncer_;
    118   int next_sync_data_id_;
    119 
    120   scoped_ptr<SyncedPrefChangeRegistrar> registrar_;
    121   policy::MockConfigurationPolicyProvider policy_provider_;
    122 };
    123 
    124 struct TestSyncedPrefObserver {
    125   bool last_seen_value;
    126   bool last_update_is_from_sync;
    127   bool has_been_notified;
    128 };
    129 
    130 void TestPrefChangeCallback(PrefService* prefs,
    131                             TestSyncedPrefObserver* observer,
    132                             const std::string& path,
    133                             bool from_sync) {
    134   observer->last_seen_value = prefs->GetBoolean(path.c_str());
    135   observer->last_update_is_from_sync = from_sync;
    136   observer->has_been_notified = true;
    137 }
    138 
    139 }  // namespace
    140 
    141 IN_PROC_BROWSER_TEST_F(SyncedPrefChangeRegistrarTest,
    142                        DifferentiateRemoteAndLocalChanges) {
    143   TestSyncedPrefObserver observer = {};
    144   registrar()->Add(prefs::kShowHomeButton,
    145       base::Bind(&TestPrefChangeCallback, prefs(), &observer));
    146 
    147   EXPECT_FALSE(observer.has_been_notified);
    148 
    149   SetBooleanPrefValueFromSync(prefs::kShowHomeButton, true);
    150   EXPECT_TRUE(observer.has_been_notified);
    151   EXPECT_TRUE(GetBooleanPrefValue(prefs::kShowHomeButton));
    152   EXPECT_TRUE(observer.last_update_is_from_sync);
    153   EXPECT_TRUE(observer.last_seen_value);
    154 
    155   observer.has_been_notified = false;
    156   SetBooleanPrefValueFromLocal(prefs::kShowHomeButton, false);
    157   EXPECT_TRUE(observer.has_been_notified);
    158   EXPECT_FALSE(GetBooleanPrefValue(prefs::kShowHomeButton));
    159   EXPECT_FALSE(observer.last_update_is_from_sync);
    160   EXPECT_FALSE(observer.last_seen_value);
    161 
    162   observer.has_been_notified = false;
    163   SetBooleanPrefValueFromLocal(prefs::kShowHomeButton, true);
    164   EXPECT_TRUE(observer.has_been_notified);
    165   EXPECT_TRUE(GetBooleanPrefValue(prefs::kShowHomeButton));
    166   EXPECT_FALSE(observer.last_update_is_from_sync);
    167   EXPECT_TRUE(observer.last_seen_value);
    168 
    169   observer.has_been_notified = false;
    170   SetBooleanPrefValueFromSync(prefs::kShowHomeButton, false);
    171   EXPECT_TRUE(observer.has_been_notified);
    172   EXPECT_FALSE(GetBooleanPrefValue(prefs::kShowHomeButton));
    173   EXPECT_TRUE(observer.last_update_is_from_sync);
    174   EXPECT_FALSE(observer.last_seen_value);
    175 }
    176 
    177 IN_PROC_BROWSER_TEST_F(SyncedPrefChangeRegistrarTest,
    178                        IgnoreLocalChangesToManagedPrefs) {
    179   TestSyncedPrefObserver observer = {};
    180   registrar()->Add(prefs::kShowHomeButton,
    181       base::Bind(&TestPrefChangeCallback, prefs(), &observer));
    182 
    183   policy::PolicyMap policies;
    184   policies.Set(policy::key::kShowHomeButton,
    185                policy::POLICY_LEVEL_MANDATORY,
    186                policy::POLICY_SCOPE_USER,
    187                base::Value::CreateBooleanValue(true),
    188                NULL);
    189   UpdateChromePolicy(policies);
    190 
    191   EXPECT_TRUE(prefs()->IsManagedPreference(prefs::kShowHomeButton));
    192 
    193   SetBooleanPrefValueFromLocal(prefs::kShowHomeButton, false);
    194   EXPECT_FALSE(observer.has_been_notified);
    195   EXPECT_TRUE(GetBooleanPrefValue(prefs::kShowHomeButton));
    196 }
    197 
    198 IN_PROC_BROWSER_TEST_F(SyncedPrefChangeRegistrarTest,
    199                        IgnoreSyncChangesToManagedPrefs) {
    200   TestSyncedPrefObserver observer = {};
    201   registrar()->Add(prefs::kShowHomeButton,
    202       base::Bind(&TestPrefChangeCallback, prefs(), &observer));
    203 
    204   policy::PolicyMap policies;
    205   policies.Set(policy::key::kShowHomeButton,
    206                policy::POLICY_LEVEL_MANDATORY,
    207                policy::POLICY_SCOPE_USER,
    208                base::Value::CreateBooleanValue(true),
    209                NULL);
    210   UpdateChromePolicy(policies);
    211 
    212   EXPECT_TRUE(prefs()->IsManagedPreference(prefs::kShowHomeButton));
    213   SetBooleanPrefValueFromSync(prefs::kShowHomeButton, false);
    214   EXPECT_FALSE(observer.has_been_notified);
    215   EXPECT_TRUE(GetBooleanPrefValue(prefs::kShowHomeButton));
    216 }
    217