1// Copyright 2014 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/tracked/segregated_pref_store.h" 6 7#include <set> 8#include <string> 9 10#include "base/bind.h" 11#include "base/callback.h" 12#include "base/memory/ref_counted.h" 13#include "base/memory/scoped_ptr.h" 14#include "base/prefs/persistent_pref_store.h" 15#include "base/prefs/pref_store_observer_mock.h" 16#include "base/prefs/testing_pref_store.h" 17#include "base/values.h" 18#include "chrome/browser/prefs/tracked/segregated_pref_store.h" 19#include "testing/gtest/include/gtest/gtest.h" 20 21namespace { 22 23const char kSelectedPref[] = "selected_pref"; 24const char kUnselectedPref[] = "unselected_pref"; 25 26const char kValue1[] = "value1"; 27const char kValue2[] = "value2"; 28 29class MockReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate { 30 public: 31 struct Data { 32 Data(bool invoked_in, PersistentPrefStore::PrefReadError read_error_in) 33 : invoked(invoked_in), read_error(read_error_in) {} 34 35 bool invoked; 36 PersistentPrefStore::PrefReadError read_error; 37 }; 38 39 explicit MockReadErrorDelegate(Data* data) : data_(data) { 40 DCHECK(data_); 41 EXPECT_FALSE(data_->invoked); 42 } 43 44 // PersistentPrefStore::ReadErrorDelegate implementation 45 virtual void OnError(PersistentPrefStore::PrefReadError read_error) OVERRIDE { 46 EXPECT_FALSE(data_->invoked); 47 data_->invoked = true; 48 data_->read_error = read_error; 49 } 50 51 private: 52 Data* data_; 53}; 54 55} // namespace 56 57class SegregatedPrefStoreTest : public testing::Test { 58 public: 59 SegregatedPrefStoreTest() 60 : read_error_delegate_data_(false, 61 PersistentPrefStore::PREF_READ_ERROR_NONE), 62 read_error_delegate_( 63 new MockReadErrorDelegate(&read_error_delegate_data_)) {} 64 65 virtual void SetUp() OVERRIDE { 66 selected_store_ = new TestingPrefStore; 67 default_store_ = new TestingPrefStore; 68 69 std::set<std::string> selected_pref_names; 70 selected_pref_names.insert(kSelectedPref); 71 72 segregated_store_ = new SegregatedPrefStore( 73 default_store_, 74 selected_store_, 75 selected_pref_names); 76 77 segregated_store_->AddObserver(&observer_); 78 } 79 80 virtual void TearDown() OVERRIDE { 81 segregated_store_->RemoveObserver(&observer_); 82 } 83 84 protected: 85 scoped_ptr<PersistentPrefStore::ReadErrorDelegate> GetReadErrorDelegate() { 86 EXPECT_TRUE(read_error_delegate_); 87 return read_error_delegate_ 88 .PassAs<PersistentPrefStore::ReadErrorDelegate>(); 89 } 90 91 PrefStoreObserverMock observer_; 92 93 scoped_refptr<TestingPrefStore> default_store_; 94 scoped_refptr<TestingPrefStore> selected_store_; 95 scoped_refptr<SegregatedPrefStore> segregated_store_; 96 97 MockReadErrorDelegate::Data read_error_delegate_data_; 98 99 private: 100 scoped_ptr<MockReadErrorDelegate> read_error_delegate_; 101}; 102 103TEST_F(SegregatedPrefStoreTest, StoreValues) { 104 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 105 segregated_store_->ReadPrefs()); 106 107 // Properly stores new values. 108 segregated_store_->SetValue(kSelectedPref, new base::StringValue(kValue1)); 109 segregated_store_->SetValue(kUnselectedPref, new base::StringValue(kValue2)); 110 111 ASSERT_TRUE(selected_store_->GetValue(kSelectedPref, NULL)); 112 ASSERT_FALSE(selected_store_->GetValue(kUnselectedPref, NULL)); 113 ASSERT_FALSE(default_store_->GetValue(kSelectedPref, NULL)); 114 ASSERT_TRUE(default_store_->GetValue(kUnselectedPref, NULL)); 115 116 ASSERT_TRUE(segregated_store_->GetValue(kSelectedPref, NULL)); 117 ASSERT_TRUE(segregated_store_->GetValue(kUnselectedPref, NULL)); 118 119 ASSERT_FALSE(selected_store_->committed()); 120 ASSERT_FALSE(default_store_->committed()); 121 122 segregated_store_->CommitPendingWrite(); 123 124 ASSERT_TRUE(selected_store_->committed()); 125 ASSERT_TRUE(default_store_->committed()); 126} 127 128TEST_F(SegregatedPrefStoreTest, ReadValues) { 129 selected_store_->SetValue(kSelectedPref, new base::StringValue(kValue1)); 130 default_store_->SetValue(kUnselectedPref, 131 new base::StringValue(kValue2)); 132 133 // Works properly with values that are already there. 134 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 135 segregated_store_->ReadPrefs()); 136 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 137 segregated_store_->GetReadError()); 138 139 ASSERT_TRUE(selected_store_->GetValue(kSelectedPref, NULL)); 140 ASSERT_FALSE(selected_store_->GetValue(kUnselectedPref, NULL)); 141 ASSERT_FALSE(default_store_->GetValue(kSelectedPref, NULL)); 142 ASSERT_TRUE(default_store_->GetValue(kUnselectedPref, NULL)); 143 144 ASSERT_TRUE(segregated_store_->GetValue(kSelectedPref, NULL)); 145 ASSERT_TRUE(segregated_store_->GetValue(kUnselectedPref, NULL)); 146} 147 148TEST_F(SegregatedPrefStoreTest, Observer) { 149 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 150 segregated_store_->ReadPrefs()); 151 EXPECT_TRUE(observer_.initialized); 152 EXPECT_TRUE(observer_.initialization_success); 153 EXPECT_TRUE(observer_.changed_keys.empty()); 154 segregated_store_->SetValue(kSelectedPref, new base::StringValue(kValue1)); 155 observer_.VerifyAndResetChangedKey(kSelectedPref); 156 segregated_store_->SetValue(kUnselectedPref, new base::StringValue(kValue2)); 157 observer_.VerifyAndResetChangedKey(kUnselectedPref); 158} 159 160TEST_F(SegregatedPrefStoreTest, SelectedPrefReadNoFileError) { 161 // PREF_READ_ERROR_NO_FILE for the selected prefs file is silently converted 162 // to PREF_READ_ERROR_NONE. 163 selected_store_->set_read_error( 164 PersistentPrefStore::PREF_READ_ERROR_NO_FILE); 165 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 166 segregated_store_->ReadPrefs()); 167 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 168 segregated_store_->GetReadError()); 169} 170 171TEST_F(SegregatedPrefStoreTest, SelectedPrefReadError) { 172 selected_store_->set_read_error( 173 PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED); 174 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED, 175 segregated_store_->ReadPrefs()); 176 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED, 177 segregated_store_->GetReadError()); 178} 179 180TEST_F(SegregatedPrefStoreTest, SelectedPrefReadNoFileErrorAsync) { 181 // PREF_READ_ERROR_NO_FILE for the selected prefs file is silently converted 182 // to PREF_READ_ERROR_NONE. 183 selected_store_->set_read_error( 184 PersistentPrefStore::PREF_READ_ERROR_NO_FILE); 185 186 default_store_->SetBlockAsyncRead(true); 187 188 EXPECT_FALSE(read_error_delegate_data_.invoked); 189 190 segregated_store_->ReadPrefsAsync(GetReadErrorDelegate().release()); 191 192 EXPECT_FALSE(read_error_delegate_data_.invoked); 193 194 default_store_->SetBlockAsyncRead(false); 195 196 // ReadErrorDelegate is not invoked for ERROR_NONE. 197 EXPECT_FALSE(read_error_delegate_data_.invoked); 198 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 199 segregated_store_->GetReadError()); 200 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, 201 segregated_store_->GetReadError()); 202} 203 204TEST_F(SegregatedPrefStoreTest, UnselectedPrefReadNoFileError) { 205 default_store_->set_read_error( 206 PersistentPrefStore::PREF_READ_ERROR_NO_FILE); 207 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, 208 segregated_store_->ReadPrefs()); 209 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, 210 segregated_store_->GetReadError()); 211} 212 213TEST_F(SegregatedPrefStoreTest, UnselectedPrefReadError) { 214 default_store_->set_read_error( 215 PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED); 216 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED, 217 segregated_store_->ReadPrefs()); 218 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED, 219 segregated_store_->GetReadError()); 220} 221 222TEST_F(SegregatedPrefStoreTest, BothPrefReadError) { 223 default_store_->set_read_error( 224 PersistentPrefStore::PREF_READ_ERROR_NO_FILE); 225 selected_store_->set_read_error( 226 PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED); 227 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, 228 segregated_store_->ReadPrefs()); 229 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, 230 segregated_store_->GetReadError()); 231} 232 233TEST_F(SegregatedPrefStoreTest, BothPrefReadErrorAsync) { 234 default_store_->set_read_error( 235 PersistentPrefStore::PREF_READ_ERROR_NO_FILE); 236 selected_store_->set_read_error( 237 PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED); 238 239 selected_store_->SetBlockAsyncRead(true); 240 241 EXPECT_FALSE(read_error_delegate_data_.invoked); 242 243 segregated_store_->ReadPrefsAsync(GetReadErrorDelegate().release()); 244 245 EXPECT_FALSE(read_error_delegate_data_.invoked); 246 247 selected_store_->SetBlockAsyncRead(false); 248 249 EXPECT_TRUE(read_error_delegate_data_.invoked); 250 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, 251 segregated_store_->GetReadError()); 252 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, 253 segregated_store_->GetReadError()); 254} 255 256TEST_F(SegregatedPrefStoreTest, IsInitializationComplete) { 257 EXPECT_FALSE(segregated_store_->IsInitializationComplete()); 258 segregated_store_->ReadPrefs(); 259 EXPECT_TRUE(segregated_store_->IsInitializationComplete()); 260} 261 262TEST_F(SegregatedPrefStoreTest, IsInitializationCompleteAsync) { 263 selected_store_->SetBlockAsyncRead(true); 264 default_store_->SetBlockAsyncRead(true); 265 EXPECT_FALSE(segregated_store_->IsInitializationComplete()); 266 segregated_store_->ReadPrefsAsync(NULL); 267 EXPECT_FALSE(segregated_store_->IsInitializationComplete()); 268 selected_store_->SetBlockAsyncRead(false); 269 EXPECT_FALSE(segregated_store_->IsInitializationComplete()); 270 default_store_->SetBlockAsyncRead(false); 271 EXPECT_TRUE(segregated_store_->IsInitializationComplete()); 272} 273