blob: 45b840d38c33c48150ac09bc6e858124b53a4980 [file] [log] [blame]
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string>
#include "app/test/data/resource.h"
#include "base/scoped_ptr.h"
#include "base/values.h"
#include "chrome/browser/dummy_pref_store.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/pref_value_store.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/notification_observer_mock.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/pref_names.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::_;
using testing::Mock;
using testing::Pointee;
using testing::Property;
class TestPrefObserver : public NotificationObserver {
public:
TestPrefObserver(const PrefService* prefs,
const std::wstring& pref_name,
const std::string& new_pref_value)
: observer_fired_(false),
prefs_(prefs),
pref_name_(pref_name),
new_pref_value_(new_pref_value) {
}
virtual ~TestPrefObserver() {}
virtual void Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
EXPECT_EQ(type.value, NotificationType::PREF_CHANGED);
PrefService* prefs_in = Source<PrefService>(source).ptr();
EXPECT_EQ(prefs_in, prefs_);
std::wstring* pref_name_in = Details<std::wstring>(details).ptr();
EXPECT_EQ(*pref_name_in, pref_name_);
EXPECT_EQ(new_pref_value_, prefs_in->GetString(L"homepage"));
observer_fired_ = true;
}
bool observer_fired() { return observer_fired_; }
void Reset(const std::string& new_pref_value) {
observer_fired_ = false;
new_pref_value_ = new_pref_value;
}
private:
bool observer_fired_;
const PrefService* prefs_;
const std::wstring pref_name_;
std::string new_pref_value_;
};
// TODO(port): port this test to POSIX.
#if defined(OS_WIN)
TEST(PrefServiceTest, LocalizedPrefs) {
PrefService prefs(new PrefValueStore(NULL, NULL, NULL, new DummyPrefStore(),
NULL));
const wchar_t kBoolean[] = L"boolean";
const wchar_t kInteger[] = L"integer";
const wchar_t kString[] = L"string";
prefs.RegisterLocalizedBooleanPref(kBoolean, IDS_LOCALE_BOOL);
prefs.RegisterLocalizedIntegerPref(kInteger, IDS_LOCALE_INT);
prefs.RegisterLocalizedStringPref(kString, IDS_LOCALE_STRING);
// The locale default should take preference over the user default.
EXPECT_FALSE(prefs.GetBoolean(kBoolean));
EXPECT_EQ(1, prefs.GetInteger(kInteger));
EXPECT_EQ("hello", prefs.GetString(kString));
prefs.SetBoolean(kBoolean, true);
EXPECT_TRUE(prefs.GetBoolean(kBoolean));
prefs.SetInteger(kInteger, 5);
EXPECT_EQ(5, prefs.GetInteger(kInteger));
prefs.SetString(kString, "foo");
EXPECT_EQ("foo", prefs.GetString(kString));
}
#endif
TEST(PrefServiceTest, NoObserverFire) {
PrefService prefs(new PrefValueStore(NULL, NULL, NULL, new DummyPrefStore(),
NULL));
const wchar_t pref_name[] = L"homepage";
prefs.RegisterStringPref(pref_name, "");
const std::string new_pref_value("http://www.google.com/");
TestPrefObserver obs(&prefs, pref_name, new_pref_value);
prefs.AddPrefObserver(pref_name, &obs);
// This should fire the checks in TestPrefObserver::Observe.
prefs.SetString(pref_name, new_pref_value);
// Make sure the observer was actually fired.
EXPECT_TRUE(obs.observer_fired());
// Setting the pref to the same value should not set the pref value a second
// time.
obs.Reset(new_pref_value);
prefs.SetString(pref_name, new_pref_value);
EXPECT_FALSE(obs.observer_fired());
// Clearing the pref should cause the pref to fire.
obs.Reset("");
prefs.ClearPref(pref_name);
EXPECT_TRUE(obs.observer_fired());
// Clearing the pref again should not cause the pref to fire.
obs.Reset("");
prefs.ClearPref(pref_name);
EXPECT_FALSE(obs.observer_fired());
// Ok, clean up.
prefs.RemovePrefObserver(pref_name, &obs);
}
TEST(PrefServiceTest, HasPrefPath) {
PrefService prefs(new PrefValueStore(NULL, NULL, NULL, new DummyPrefStore(),
NULL));
const wchar_t path[] = L"fake.path";
// Shouldn't initially have a path.
EXPECT_FALSE(prefs.HasPrefPath(path));
// Register the path. This doesn't set a value, so the path still shouldn't
// exist.
prefs.RegisterStringPref(path, std::string());
EXPECT_FALSE(prefs.HasPrefPath(path));
// Set a value and make sure we have a path.
prefs.SetString(path, "blah");
EXPECT_TRUE(prefs.HasPrefPath(path));
}
TEST(PrefServiceTest, Observers) {
const wchar_t pref_name[] = L"homepage";
DictionaryValue* dict = new DictionaryValue();
dict->SetString(pref_name, std::string("http://www.cnn.com"));
DummyPrefStore* pref_store = new DummyPrefStore();
pref_store->set_prefs(dict);
PrefService prefs(new PrefValueStore(NULL, NULL, NULL, pref_store, NULL));
prefs.RegisterStringPref(pref_name, "");
const std::string new_pref_value("http://www.google.com/");
TestPrefObserver obs(&prefs, pref_name, new_pref_value);
prefs.AddPrefObserver(pref_name, &obs);
// This should fire the checks in TestPrefObserver::Observe.
prefs.SetString(pref_name, new_pref_value);
// Make sure the tests were actually run.
EXPECT_TRUE(obs.observer_fired());
// Now try adding a second pref observer.
const std::string new_pref_value2("http://www.youtube.com/");
obs.Reset(new_pref_value2);
TestPrefObserver obs2(&prefs, pref_name, new_pref_value2);
prefs.AddPrefObserver(pref_name, &obs2);
// This should fire the checks in obs and obs2.
prefs.SetString(pref_name, new_pref_value2);
EXPECT_TRUE(obs.observer_fired());
EXPECT_TRUE(obs2.observer_fired());
// Make sure obs2 still works after removing obs.
prefs.RemovePrefObserver(pref_name, &obs);
obs.Reset("");
obs2.Reset(new_pref_value);
// This should only fire the observer in obs2.
prefs.SetString(pref_name, new_pref_value);
EXPECT_FALSE(obs.observer_fired());
EXPECT_TRUE(obs2.observer_fired());
// Ok, clean up.
prefs.RemovePrefObserver(pref_name, &obs2);
}
class PrefServiceSetValueTest : public testing::Test {
protected:
static const wchar_t name_[];
static const char value_[];
PrefServiceSetValueTest()
: prefs_(new PrefValueStore(NULL, NULL, NULL, new DummyPrefStore(),
NULL)),
name_string_(name_),
null_value_(Value::CreateNullValue()) {}
void SetExpectNoNotification() {
EXPECT_CALL(observer_, Observe(_, _, _)).Times(0);
}
void SetExpectPrefChanged() {
EXPECT_CALL(observer_,
Observe(NotificationType(NotificationType::PREF_CHANGED), _,
Property(&Details<std::wstring>::ptr,
Pointee(name_string_))));
}
PrefService prefs_;
std::wstring name_string_;
scoped_ptr<Value> null_value_;
NotificationObserverMock observer_;
};
const wchar_t PrefServiceSetValueTest::name_[] = L"name";
const char PrefServiceSetValueTest::value_[] = "value";
TEST_F(PrefServiceSetValueTest, SetStringValue) {
const char default_string[] = "default";
scoped_ptr<Value> default_value(Value::CreateStringValue(default_string));
prefs_.RegisterStringPref(name_, default_string);
prefs_.AddPrefObserver(name_, &observer_);
SetExpectNoNotification();
prefs_.Set(name_, *default_value);
Mock::VerifyAndClearExpectations(&observer_);
scoped_ptr<Value> new_value(Value::CreateStringValue(value_));
SetExpectPrefChanged();
prefs_.Set(name_, *new_value);
EXPECT_EQ(value_, prefs_.GetString(name_));
prefs_.RemovePrefObserver(name_, &observer_);
}
TEST_F(PrefServiceSetValueTest, SetDictionaryValue) {
prefs_.RegisterDictionaryPref(name_);
prefs_.AddPrefObserver(name_, &observer_);
SetExpectNoNotification();
prefs_.Set(name_, *null_value_);
Mock::VerifyAndClearExpectations(&observer_);
DictionaryValue new_value;
new_value.SetString(name_, value_);
SetExpectPrefChanged();
prefs_.Set(name_, new_value);
Mock::VerifyAndClearExpectations(&observer_);
DictionaryValue* dict = prefs_.GetMutableDictionary(name_);
EXPECT_EQ(1U, dict->size());
std::string out_value;
dict->GetString(name_, &out_value);
EXPECT_EQ(value_, out_value);
SetExpectNoNotification();
prefs_.Set(name_, new_value);
Mock::VerifyAndClearExpectations(&observer_);
SetExpectPrefChanged();
prefs_.Set(name_, *null_value_);
Mock::VerifyAndClearExpectations(&observer_);
dict = prefs_.GetMutableDictionary(name_);
EXPECT_EQ(0U, dict->size());
prefs_.RemovePrefObserver(name_, &observer_);
}
TEST_F(PrefServiceSetValueTest, SetListValue) {
prefs_.RegisterListPref(name_);
prefs_.AddPrefObserver(name_, &observer_);
SetExpectNoNotification();
prefs_.Set(name_, *null_value_);
Mock::VerifyAndClearExpectations(&observer_);
ListValue new_value;
new_value.Append(Value::CreateStringValue(value_));
SetExpectPrefChanged();
prefs_.Set(name_, new_value);
Mock::VerifyAndClearExpectations(&observer_);
ListValue* list = prefs_.GetMutableList(name_);
ASSERT_EQ(1U, list->GetSize());
std::string out_value;
list->GetString(0, &out_value);
EXPECT_EQ(value_, out_value);
SetExpectNoNotification();
prefs_.Set(name_, new_value);
Mock::VerifyAndClearExpectations(&observer_);
SetExpectPrefChanged();
prefs_.Set(name_, *null_value_);
Mock::VerifyAndClearExpectations(&observer_);
list = prefs_.GetMutableList(name_);
EXPECT_EQ(0U, list->GetSize());
prefs_.RemovePrefObserver(name_, &observer_);
}