1// Copyright (c) 2011 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 "base/prefs/mock_pref_change_callback.h"
6#include "base/prefs/pref_change_registrar.h"
7#include "chrome/browser/prefs/scoped_user_pref_update.h"
8#include "chrome/test/base/testing_pref_service_syncable.h"
9#include "components/user_prefs/pref_registry_syncable.h"
10#include "testing/gmock/include/gmock/gmock.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13using testing::_;
14using testing::Mock;
15
16class ScopedUserPrefUpdateTest : public testing::Test {
17 public:
18  ScopedUserPrefUpdateTest() : observer_(&prefs_) {}
19  virtual ~ScopedUserPrefUpdateTest() {}
20
21 protected:
22  virtual void SetUp() {
23    prefs_.registry()->RegisterDictionaryPref(
24        kPref,
25        user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
26    registrar_.Init(&prefs_);
27    registrar_.Add(kPref, observer_.GetCallback());
28  }
29
30  static const char kPref[];
31  static const char kKey[];
32  static const char kValue[];
33
34  TestingPrefServiceSyncable prefs_;
35  MockPrefChangeCallback observer_;
36  PrefChangeRegistrar registrar_;
37};
38
39const char ScopedUserPrefUpdateTest::kPref[] = "name";
40const char ScopedUserPrefUpdateTest::kKey[] = "key";
41const char ScopedUserPrefUpdateTest::kValue[] = "value";
42
43TEST_F(ScopedUserPrefUpdateTest, RegularUse) {
44  // Dictionary that will be expected to be set at the end.
45  DictionaryValue expected_dictionary;
46  expected_dictionary.SetString(kKey, kValue);
47
48  {
49    EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0);
50    DictionaryPrefUpdate update(&prefs_, kPref);
51    DictionaryValue* value = update.Get();
52    ASSERT_TRUE(value);
53    value->SetString(kKey, kValue);
54
55    // The dictionary was created for us but the creation should have happened
56    // silently without notifications.
57    Mock::VerifyAndClearExpectations(&observer_);
58
59    // Modifications happen online and are instantly visible, though.
60    const DictionaryValue* current_value = prefs_.GetDictionary(kPref);
61    ASSERT_TRUE(current_value);
62    EXPECT_TRUE(expected_dictionary.Equals(current_value));
63
64    // Now we are leaving the scope of the update so we should be notified.
65    observer_.Expect(kPref, &expected_dictionary);
66  }
67  Mock::VerifyAndClearExpectations(&observer_);
68
69  const DictionaryValue* current_value = prefs_.GetDictionary(kPref);
70  ASSERT_TRUE(current_value);
71  EXPECT_TRUE(expected_dictionary.Equals(current_value));
72}
73
74TEST_F(ScopedUserPrefUpdateTest, NeverTouchAnything) {
75  const DictionaryValue* old_value = prefs_.GetDictionary(kPref);
76  EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0);
77  {
78    DictionaryPrefUpdate update(&prefs_, kPref);
79  }
80  const DictionaryValue* new_value = prefs_.GetDictionary(kPref);
81  EXPECT_EQ(old_value, new_value);
82  Mock::VerifyAndClearExpectations(&observer_);
83}
84