1// Copyright (c) 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 "base/observer_list.h"
6#include "base/prefs/writeable_pref_store.h"
7#include "base/values.h"
8#include "chrome/browser/devtools/devtools_window.h"
9#include "chrome/browser/prefs/browser_ui_prefs_migrator.h"
10#include "chrome/common/pref_names.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13namespace {
14
15class DictionaryPrefStore : public WriteablePrefStore {
16 public:
17  DictionaryPrefStore() : WriteablePrefStore() {}
18
19  // Overrides from PrefStore.
20  virtual void AddObserver(Observer* observer) OVERRIDE {
21    observers_.AddObserver(observer);
22  }
23
24  virtual void RemoveObserver(Observer* observer) OVERRIDE {
25    observers_.RemoveObserver(observer);
26  }
27
28  virtual bool GetValue(const std::string& key,
29                        const base::Value** result) const OVERRIDE {
30    return prefs_.Get(key, result);
31  }
32
33  // Overrides from WriteablePrefStore.
34  virtual void SetValue(const std::string& key, base::Value* value) OVERRIDE {
35    DCHECK(value);
36    prefs_.Set(key, value);
37    ReportValueChanged(key);
38  }
39
40  virtual void RemoveValue(const std::string& key) OVERRIDE {
41    if (prefs_.RemovePath(key, NULL))
42      ReportValueChanged(key);
43  }
44
45  virtual bool GetMutableValue(const std::string& key,
46                               base::Value** result) OVERRIDE {
47    return prefs_.Get(key, result);
48  }
49
50  virtual void ReportValueChanged(const std::string& key) OVERRIDE {}
51
52  virtual void SetValueSilently(const std::string& key,
53                                base::Value* value) OVERRIDE {
54    NOTIMPLEMENTED();
55  }
56
57  void SignalObservers() {
58    FOR_EACH_OBSERVER(
59        PrefStore::Observer, observers_, OnInitializationCompleted(true));
60  }
61
62 private:
63  virtual ~DictionaryPrefStore() {}
64
65  base::DictionaryValue prefs_;
66  ObserverList<PrefStore::Observer, true> observers_;
67
68  DISALLOW_COPY_AND_ASSIGN(DictionaryPrefStore);
69};
70
71}  // namespace
72
73TEST(UIPrefsMigratorTest, MigrateTest) {
74  scoped_refptr<DictionaryPrefStore> pref_store(new DictionaryPrefStore);
75  scoped_ptr<base::DictionaryValue> browser_window_placement(
76      new base::DictionaryValue);
77  browser_window_placement->SetInteger("bottom", 1000);
78  pref_store->SetValue(prefs::kBrowserWindowPlacement,
79                       browser_window_placement.release());
80
81  scoped_ptr<base::DictionaryValue> browser_window_placement_popup(
82      new base::DictionaryValue);
83  browser_window_placement_popup->SetInteger("top", 50);
84  pref_store->SetValue(prefs::kBrowserWindowPlacementPopup,
85                       browser_window_placement_popup.release());
86
87  scoped_ptr<base::DictionaryValue> single_app_placement_dict(
88      new base::DictionaryValue);
89  single_app_placement_dict->SetInteger("right", 986);
90  const char* kAppName("localhost_/some_app.html");
91  const std::string kOldPathToOneAppDictionary =
92      prefs::kBrowserWindowPlacement + std::string("_") + kAppName;
93  pref_store->SetValue(kOldPathToOneAppDictionary,
94                       single_app_placement_dict.release());
95  EXPECT_TRUE(pref_store->GetValue(kOldPathToOneAppDictionary, NULL));
96
97  scoped_ptr<base::DictionaryValue> devtools_placement_dict(
98      new base::DictionaryValue);
99  devtools_placement_dict->SetInteger("left", 700);
100  const std::string kOldPathToDevToolsDictionary =
101      prefs::kBrowserWindowPlacement + std::string("_") +
102      DevToolsWindow::kDevToolsApp;
103  pref_store->SetValue(kOldPathToDevToolsDictionary,
104                       devtools_placement_dict.release());
105  EXPECT_TRUE(pref_store->GetValue(kOldPathToDevToolsDictionary, NULL));
106
107  pref_store->AddObserver(new BrowserUIPrefsMigrator(pref_store.get()));
108  pref_store->SignalObservers();
109
110  EXPECT_FALSE(pref_store->GetValue(kOldPathToOneAppDictionary, NULL));
111  EXPECT_FALSE(pref_store->GetValue(kOldPathToDevToolsDictionary, NULL));
112
113  const base::Value* value = NULL;
114  const base::DictionaryValue* dictionary = NULL;
115  int out_value;
116
117  ASSERT_TRUE(pref_store->GetValue(prefs::kBrowserWindowPlacement, &value));
118  ASSERT_TRUE(value->GetAsDictionary(&dictionary));
119  EXPECT_TRUE(dictionary->GetInteger("bottom", &out_value));
120  EXPECT_EQ(1000, out_value);
121
122  ASSERT_TRUE(
123      pref_store->GetValue(prefs::kBrowserWindowPlacementPopup, &value));
124  ASSERT_TRUE(value->GetAsDictionary(&dictionary));
125  EXPECT_TRUE(dictionary->GetInteger("top", &out_value));
126  EXPECT_EQ(50, out_value);
127
128  ASSERT_TRUE(pref_store->GetValue(
129      prefs::kAppWindowPlacement + std::string(".") + kAppName, &value));
130  ASSERT_TRUE(value->GetAsDictionary(&dictionary));
131  EXPECT_TRUE(dictionary->GetInteger("right", &out_value));
132  EXPECT_EQ(986, out_value);
133
134  ASSERT_TRUE(pref_store->GetValue(prefs::kAppWindowPlacement +
135                                       std::string(".") +
136                                       DevToolsWindow::kDevToolsApp,
137                                   &value));
138  ASSERT_TRUE(value->GetAsDictionary(&dictionary));
139  EXPECT_TRUE(dictionary->GetInteger("left", &out_value));
140  EXPECT_EQ(700, out_value);
141}
142