| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright 2016 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/prefs/preferences_service.h" |  | 
| 6 |  | 
| 7 #include "base/macros.h" |  | 
| 8 #include "base/memory/ptr_util.h" |  | 
| 9 #include "base/run_loop.h" |  | 
| 10 #include "base/strings/utf_string_conversions.h" |  | 
| 11 #include "base/values.h" |  | 
| 12 #include "chrome/browser/prefs/browser_prefs.h" |  | 
| 13 #include "chrome/test/base/testing_browser_process.h" |  | 
| 14 #include "chrome/test/base/testing_profile.h" |  | 
| 15 #include "chrome/test/base/testing_profile_manager.h" |  | 
| 16 #include "components/pref_registry/pref_registry_syncable.h" |  | 
| 17 #include "components/prefs/pref_change_registrar.h" |  | 
| 18 #include "components/prefs/pref_service.h" |  | 
| 19 #include "components/sync_preferences/testing_pref_service_syncable.h" |  | 
| 20 #include "content/public/test/test_browser_thread_bundle.h" |  | 
| 21 #include "mojo/public/cpp/bindings/binding.h" |  | 
| 22 #include "services/preferences/public/interfaces/preferences.mojom.h" |  | 
| 23 #include "testing/gtest/include/gtest/gtest.h" |  | 
| 24 |  | 
| 25 namespace { |  | 
| 26 |  | 
| 27 // Test implementation of prefs::mojom::PreferencesServiceClient which just |  | 
| 28 // tracks |  | 
| 29 // calls to OnPreferencesChanged. |  | 
| 30 class TestPreferencesServiceClient |  | 
| 31     : public prefs::mojom::PreferencesServiceClient { |  | 
| 32  public: |  | 
| 33   TestPreferencesServiceClient( |  | 
| 34       mojo::InterfaceRequest<prefs::mojom::PreferencesServiceClient> request) |  | 
| 35       : on_preferences_changed_called_(false), |  | 
| 36         binding_(this, std::move(request)) {} |  | 
| 37   ~TestPreferencesServiceClient() override {} |  | 
| 38 |  | 
| 39   // Returns true is |key| was in the last set of preferences changed. |  | 
| 40   bool KeyReceived(const std::string& key); |  | 
| 41 |  | 
| 42   // Clears the values set from the last OnPreferencesChanged. |  | 
| 43   void Reset(); |  | 
| 44 |  | 
| 45   bool on_preferences_changed_called() { |  | 
| 46     return on_preferences_changed_called_; |  | 
| 47   } |  | 
| 48 |  | 
| 49   const base::Value* on_preferences_changed_values() { |  | 
| 50     return on_preferences_changed_values_.get(); |  | 
| 51   } |  | 
| 52 |  | 
| 53  private: |  | 
| 54   // prefs::mojom::PreferencesServiceClient: |  | 
| 55   void OnPreferencesChanged( |  | 
| 56       std::unique_ptr<base::DictionaryValue> preferences) override { |  | 
| 57     on_preferences_changed_called_ = true; |  | 
| 58     on_preferences_changed_values_ = std::move(preferences); |  | 
| 59   } |  | 
| 60 |  | 
| 61   bool on_preferences_changed_called_; |  | 
| 62   std::unique_ptr<base::Value> on_preferences_changed_values_; |  | 
| 63 |  | 
| 64   mojo::Binding<PreferencesServiceClient> binding_; |  | 
| 65 |  | 
| 66   DISALLOW_COPY_AND_ASSIGN(TestPreferencesServiceClient); |  | 
| 67 }; |  | 
| 68 |  | 
| 69 bool TestPreferencesServiceClient::KeyReceived(const std::string& key) { |  | 
| 70   base::DictionaryValue* dictionary = nullptr; |  | 
| 71   on_preferences_changed_values_->GetAsDictionary(&dictionary); |  | 
| 72   return dictionary->HasKey(key); |  | 
| 73 } |  | 
| 74 |  | 
| 75 void TestPreferencesServiceClient::Reset() { |  | 
| 76   on_preferences_changed_called_ = false; |  | 
| 77   on_preferences_changed_values_.reset(); |  | 
| 78 } |  | 
| 79 |  | 
| 80 }  // namespace |  | 
| 81 |  | 
| 82 namespace test { |  | 
| 83 class PreferencesServiceTest : public testing::Test { |  | 
| 84  public: |  | 
| 85   PreferencesServiceTest(); |  | 
| 86   ~PreferencesServiceTest() override; |  | 
| 87 |  | 
| 88   // Initializes the connection between |client_| and |service_|, subscribing |  | 
| 89   // to changes to |preferences|. |  | 
| 90   void InitObserver(const std::vector<std::string>& preferences); |  | 
| 91 |  | 
| 92   // Initializes a preference with |registry_| with a default |value|. |  | 
| 93   void InitPreference(const std::string& key, int value); |  | 
| 94 |  | 
| 95   // Has |service_| update the PrefStore with |preferences|. |  | 
| 96   void SetPreferences(std::unique_ptr<base::DictionaryValue> preferences); |  | 
| 97 |  | 
| 98   TestPreferencesServiceClient* client() { return client_.get(); } |  | 
| 99   PrefChangeRegistrar* preferences_change_registrar() { |  | 
| 100     return service_->preferences_change_registrar_.get(); |  | 
| 101   } |  | 
| 102   TestingProfile* profile() { return profile_; } |  | 
| 103   user_prefs::PrefRegistrySyncable* registry() { return registry_; } |  | 
| 104   PrefService* service() { return profile_->GetPrefs(); } |  | 
| 105 |  | 
| 106   // testing::Test: |  | 
| 107   void SetUp() override; |  | 
| 108   void TearDown() override; |  | 
| 109 |  | 
| 110  private: |  | 
| 111   // Sets up threads needed for |testing_profile_manager_| |  | 
| 112   content::TestBrowserThreadBundle thread_bundle_; |  | 
| 113 |  | 
| 114   // Handles creation of profiles for testing. |  | 
| 115   TestingProfileManager testing_profile_manager_; |  | 
| 116 |  | 
| 117   // Not owned |  | 
| 118   TestingProfile* profile_; |  | 
| 119   user_prefs::PrefRegistrySyncable* registry_; |  | 
| 120 |  | 
| 121   prefs::mojom::PreferencesServiceClientPtr proxy_; |  | 
| 122   std::unique_ptr<TestPreferencesServiceClient> client_; |  | 
| 123   std::unique_ptr<PreferencesService> service_; |  | 
| 124 |  | 
| 125   DISALLOW_COPY_AND_ASSIGN(PreferencesServiceTest); |  | 
| 126 }; |  | 
| 127 |  | 
| 128 PreferencesServiceTest::PreferencesServiceTest() |  | 
| 129     : testing_profile_manager_(TestingBrowserProcess::GetGlobal()) {} |  | 
| 130 |  | 
| 131 PreferencesServiceTest::~PreferencesServiceTest() {} |  | 
| 132 |  | 
| 133 void PreferencesServiceTest::InitObserver( |  | 
| 134     const std::vector<std::string>& preferences) { |  | 
| 135   service_->Subscribe(preferences); |  | 
| 136   base::RunLoop().RunUntilIdle(); |  | 
| 137 } |  | 
| 138 |  | 
| 139 void PreferencesServiceTest::InitPreference(const std::string& key, int value) { |  | 
| 140   registry_->RegisterIntegerPref(key, value); |  | 
| 141   base::Value fundamental_value(value); |  | 
| 142   profile_->GetPrefs()->Set(key, fundamental_value); |  | 
| 143 } |  | 
| 144 |  | 
| 145 void PreferencesServiceTest::SetPreferences( |  | 
| 146     std::unique_ptr<base::DictionaryValue> preferences) { |  | 
| 147   service_->SetPreferences(std::move(preferences)); |  | 
| 148   base::RunLoop().RunUntilIdle(); |  | 
| 149 } |  | 
| 150 |  | 
| 151 void PreferencesServiceTest::SetUp() { |  | 
| 152   ASSERT_TRUE(testing_profile_manager_.SetUp()); |  | 
| 153 |  | 
| 154   std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> service( |  | 
| 155       base::MakeUnique<sync_preferences::TestingPrefServiceSyncable>()); |  | 
| 156   registry_ = service->registry(); |  | 
| 157   chrome::RegisterUserProfilePrefs(registry_); |  | 
| 158 |  | 
| 159   const std::string kName = "navi"; |  | 
| 160   profile_ = testing_profile_manager_.CreateTestingProfile( |  | 
| 161       kName, std::move(service), base::UTF8ToUTF16(kName), 0, std::string(), |  | 
| 162       TestingProfile::TestingFactories()); |  | 
| 163   ASSERT_NE(nullptr, profile_->GetPrefs()); |  | 
| 164 |  | 
| 165   client_.reset(new TestPreferencesServiceClient(mojo::MakeRequest(&proxy_))); |  | 
| 166   service_ = base::MakeUnique<PreferencesService>(std::move(proxy_), profile_); |  | 
| 167   ASSERT_TRUE(service_->preferences_change_registrar_->IsEmpty()); |  | 
| 168 } |  | 
| 169 |  | 
| 170 void PreferencesServiceTest::TearDown() { |  | 
| 171   testing_profile_manager_.DeleteAllTestingProfiles(); |  | 
| 172 } |  | 
| 173 |  | 
| 174 // Tests that when the PrefService is empty that no subscriptions are made. |  | 
| 175 TEST_F(PreferencesServiceTest, EmptyService) { |  | 
| 176   const std::string kKey = "hey"; |  | 
| 177   std::vector<std::string> preferences; |  | 
| 178   preferences.push_back(kKey); |  | 
| 179   InitObserver(preferences); |  | 
| 180   EXPECT_FALSE(preferences_change_registrar()->IsObserved(kKey)); |  | 
| 181   EXPECT_FALSE(client()->on_preferences_changed_called()); |  | 
| 182 } |  | 
| 183 |  | 
| 184 // Tests that when the PrefService has the desired key, that a subscription is |  | 
| 185 // setup and that the PreferenceObserver is notified. |  | 
| 186 TEST_F(PreferencesServiceTest, ServiceHasValues) { |  | 
| 187   const std::string kKey = "hey"; |  | 
| 188   const int kValue = 42; |  | 
| 189   InitPreference(kKey, kValue); |  | 
| 190 |  | 
| 191   std::vector<std::string> preferences; |  | 
| 192   preferences.push_back(kKey); |  | 
| 193   InitObserver(preferences); |  | 
| 194   EXPECT_TRUE(preferences_change_registrar()->IsObserved(kKey)); |  | 
| 195   EXPECT_TRUE(client()->on_preferences_changed_called()); |  | 
| 196   EXPECT_TRUE(client()->KeyReceived(kKey)); |  | 
| 197 } |  | 
| 198 |  | 
| 199 // Tests that mulitple keys can be subscribed to. |  | 
| 200 TEST_F(PreferencesServiceTest, MultipleSubscriptions) { |  | 
| 201   const std::string kKey1 = "hey"; |  | 
| 202   const int kValue1 = 42; |  | 
| 203   InitPreference(kKey1, kValue1); |  | 
| 204 |  | 
| 205   const std::string kKey2 = "listen"; |  | 
| 206   const int kValue2 = 9001; |  | 
| 207   InitPreference(kKey2, kValue2); |  | 
| 208 |  | 
| 209   std::vector<std::string> preferences; |  | 
| 210   preferences.push_back(kKey1); |  | 
| 211   preferences.push_back(kKey2); |  | 
| 212   InitObserver(preferences); |  | 
| 213   EXPECT_TRUE(preferences_change_registrar()->IsObserved(kKey1)); |  | 
| 214   EXPECT_TRUE(preferences_change_registrar()->IsObserved(kKey2)); |  | 
| 215   EXPECT_TRUE(client()->KeyReceived(kKey1)); |  | 
| 216   EXPECT_TRUE(client()->KeyReceived(kKey2)); |  | 
| 217 } |  | 
| 218 |  | 
| 219 // Tests that when all keys are not in the PrefService that subscriptions are |  | 
| 220 // set for the available key. |  | 
| 221 TEST_F(PreferencesServiceTest, PartialSubsriptionAvailable) { |  | 
| 222   const std::string kKey1 = "hey"; |  | 
| 223   const int kValue1 = 42; |  | 
| 224   InitPreference(kKey1, kValue1); |  | 
| 225 |  | 
| 226   const std::string kKey2 = "listen"; |  | 
| 227   std::vector<std::string> preferences; |  | 
| 228   preferences.push_back(kKey1); |  | 
| 229   preferences.push_back(kKey2); |  | 
| 230   InitObserver(preferences); |  | 
| 231   EXPECT_TRUE(preferences_change_registrar()->IsObserved(kKey1)); |  | 
| 232   EXPECT_FALSE(preferences_change_registrar()->IsObserved(kKey2)); |  | 
| 233   EXPECT_TRUE(client()->KeyReceived(kKey1)); |  | 
| 234   EXPECT_FALSE(client()->KeyReceived(kKey2)); |  | 
| 235 } |  | 
| 236 |  | 
| 237 // Tests that when a preference is changed that the PreferenceObserver is |  | 
| 238 // notified. |  | 
| 239 TEST_F(PreferencesServiceTest, PreferenceChanged) { |  | 
| 240   const std::string kKey = "hey"; |  | 
| 241   const int kValue = 42; |  | 
| 242   InitPreference(kKey, kValue); |  | 
| 243 |  | 
| 244   std::vector<std::string> preferences; |  | 
| 245   preferences.push_back(kKey); |  | 
| 246   InitObserver(preferences); |  | 
| 247   client()->Reset(); |  | 
| 248 |  | 
| 249   const int kNewValue = 1337; |  | 
| 250   service()->SetInteger(kKey, kNewValue); |  | 
| 251   base::RunLoop().RunUntilIdle(); |  | 
| 252 |  | 
| 253   EXPECT_TRUE(client()->on_preferences_changed_called()); |  | 
| 254   const base::Value* values = client()->on_preferences_changed_values(); |  | 
| 255   const base::DictionaryValue* dictionary = nullptr; |  | 
| 256   values->GetAsDictionary(&dictionary); |  | 
| 257   int result = 0; |  | 
| 258   dictionary->GetInteger(kKey, &result); |  | 
| 259   EXPECT_EQ(kNewValue, result); |  | 
| 260 } |  | 
| 261 |  | 
| 262 // Tests that when a non subscribed preference is changed that the |  | 
| 263 // PreferenceObserver is not notified. |  | 
| 264 TEST_F(PreferencesServiceTest, UnrelatedPreferenceChanged) { |  | 
| 265   const std::string kKey1 = "hey"; |  | 
| 266   const int kValue1 = 42; |  | 
| 267   InitPreference(kKey1, kValue1); |  | 
| 268 |  | 
| 269   const std::string kKey2 = "listen"; |  | 
| 270   const int kValue2 = 9001; |  | 
| 271   InitPreference(kKey2, kValue2); |  | 
| 272 |  | 
| 273   std::vector<std::string> preferences; |  | 
| 274   preferences.push_back(kKey1); |  | 
| 275   InitObserver(preferences); |  | 
| 276   client()->Reset(); |  | 
| 277 |  | 
| 278   const int kNewValue = 1337; |  | 
| 279   service()->SetInteger(kKey2, kNewValue); |  | 
| 280   base::RunLoop().RunUntilIdle(); |  | 
| 281 |  | 
| 282   EXPECT_FALSE(client()->on_preferences_changed_called()); |  | 
| 283 } |  | 
| 284 |  | 
| 285 // Tests that when the PreferenceManager updates a preference that the |  | 
| 286 // PreferenceObserver is not notified. |  | 
| 287 TEST_F(PreferencesServiceTest, NoNotificationsForSelfChange) { |  | 
| 288   const std::string kKey = "hey"; |  | 
| 289   const int kValue = 42; |  | 
| 290   InitPreference(kKey, kValue); |  | 
| 291 |  | 
| 292   std::vector<std::string> preferences; |  | 
| 293   preferences.push_back(kKey); |  | 
| 294   InitObserver(preferences); |  | 
| 295   client()->Reset(); |  | 
| 296 |  | 
| 297   const int kNewValue = 1337; |  | 
| 298   std::unique_ptr<base::DictionaryValue> dictionary = |  | 
| 299       base::MakeUnique<base::DictionaryValue>(); |  | 
| 300   dictionary->SetInteger(kKey, kNewValue); |  | 
| 301   SetPreferences(std::move(dictionary)); |  | 
| 302 |  | 
| 303   EXPECT_FALSE(client()->on_preferences_changed_called()); |  | 
| 304   EXPECT_EQ(kNewValue, service()->GetInteger(kKey)); |  | 
| 305 } |  | 
| 306 |  | 
| 307 }  // namespace test |  | 
| OLD | NEW | 
|---|