blob: 4c9c847708f5f2d3f9845759bfffb7598b68e832 [file] [log] [blame]
[email protected]ea3e4972012-04-12 03:41:371// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]277404c22010-04-22 13:09:452// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]00c87822012-11-27 19:09:175#include "base/prefs/json_pref_store.h"
6
[email protected]e33c9512014-05-12 02:24:137#include "base/bind.h"
[email protected]277404c22010-04-22 13:09:458#include "base/file_util.h"
[email protected]ea1a3f62012-11-16 20:34:239#include "base/files/scoped_temp_dir.h"
[email protected]3b63f8f42011-03-28 01:54:1510#include "base/memory/ref_counted.h"
11#include "base/memory/scoped_ptr.h"
[email protected]e33c9512014-05-12 02:24:1312#include "base/message_loop/message_loop.h"
[email protected]277404c22010-04-22 13:09:4513#include "base/path_service.h"
[email protected]56cbcb3a2013-12-23 21:24:4614#include "base/prefs/pref_filter.h"
[email protected]f7b98b32013-02-05 08:14:1515#include "base/run_loop.h"
[email protected]dfa049e2013-02-07 02:57:2216#include "base/strings/string_number_conversions.h"
[email protected]d529cb02013-06-10 19:06:5717#include "base/strings/string_util.h"
[email protected]a4ea1f12013-06-07 18:37:0718#include "base/strings/utf_string_conversions.h"
[email protected]0de615a2012-11-08 04:40:5919#include "base/threading/sequenced_worker_pool.h"
[email protected]34b99632011-01-01 01:01:0620#include "base/threading/thread.h"
[email protected]277404c22010-04-22 13:09:4521#include "base/values.h"
[email protected]845b43a82011-05-11 10:14:4322#include "testing/gmock/include/gmock/gmock.h"
[email protected]277404c22010-04-22 13:09:4523#include "testing/gtest/include/gtest/gtest.h"
24
[email protected]7e3ec42c2012-12-16 05:13:2125namespace base {
[email protected]845b43a82011-05-11 10:14:4326namespace {
27
[email protected]5bfdcfd2012-11-22 22:08:2428const char kHomePage[] = "homepage";
29
[email protected]e33c9512014-05-12 02:24:1330// A PrefFilter that will intercept all calls to FilterOnLoad() and hold on
31// to the |prefs| until explicitly asked to release them.
32class InterceptingPrefFilter : public PrefFilter {
33 public:
34 InterceptingPrefFilter();
35 virtual ~InterceptingPrefFilter();
36
37 // PrefFilter implementation:
38 virtual void FilterOnLoad(
39 const PostFilterOnLoadCallback& post_filter_on_load_callback,
40 scoped_ptr<base::DictionaryValue> pref_store_contents) OVERRIDE;
41 virtual void FilterUpdate(const std::string& path) OVERRIDE {}
42 virtual void FilterSerializeData(
43 const base::DictionaryValue* pref_store_contents) OVERRIDE {}
44
45 bool has_intercepted_prefs() const { return intercepted_prefs_ != NULL; }
46
47 // Finalize an intercepted read, handing |intercept_prefs_| back to its
48 // JsonPrefStore.
49 void ReleasePrefs();
50
51 private:
52 PostFilterOnLoadCallback post_filter_on_load_callback_;
53 scoped_ptr<base::DictionaryValue> intercepted_prefs_;
54
55 DISALLOW_COPY_AND_ASSIGN(InterceptingPrefFilter);
56};
57
58InterceptingPrefFilter::InterceptingPrefFilter() {}
59InterceptingPrefFilter::~InterceptingPrefFilter() {}
60
61void InterceptingPrefFilter::FilterOnLoad(
62 const PostFilterOnLoadCallback& post_filter_on_load_callback,
63 scoped_ptr<base::DictionaryValue> pref_store_contents) {
64 post_filter_on_load_callback_ = post_filter_on_load_callback;
65 intercepted_prefs_ = pref_store_contents.Pass();
66}
67
68void InterceptingPrefFilter::ReleasePrefs() {
69 EXPECT_FALSE(post_filter_on_load_callback_.is_null());
70 post_filter_on_load_callback_.Run(intercepted_prefs_.Pass(), false);
71 post_filter_on_load_callback_.Reset();
72}
73
[email protected]845b43a82011-05-11 10:14:4374class MockPrefStoreObserver : public PrefStore::Observer {
75 public:
76 MOCK_METHOD1(OnPrefValueChanged, void (const std::string&));
77 MOCK_METHOD1(OnInitializationCompleted, void (bool));
78};
79
80class MockReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate {
81 public:
82 MOCK_METHOD1(OnError, void(PersistentPrefStore::PrefReadError));
83};
84
85} // namespace
86
[email protected]277404c22010-04-22 13:09:4587class JsonPrefStoreTest : public testing::Test {
88 protected:
[email protected]0de615a2012-11-08 04:40:5989 virtual void SetUp() OVERRIDE {
[email protected]3a305db2011-04-12 13:40:5390 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
[email protected]277404c22010-04-22 13:09:4591
[email protected]fd1d067b2013-04-07 16:27:4692 ASSERT_TRUE(PathService::Get(base::DIR_TEST_DATA, &data_dir_));
[email protected]00c87822012-11-27 19:09:1793 data_dir_ = data_dir_.AppendASCII("prefs");
[email protected]7567484142013-07-11 17:36:0794 ASSERT_TRUE(PathExists(data_dir_));
[email protected]277404c22010-04-22 13:09:4595 }
96
[email protected]e33c9512014-05-12 02:24:1397 virtual void TearDown() OVERRIDE {
98 // Make sure all pending tasks have been processed (e.g., deleting the
99 // JsonPrefStore may post write tasks).
100 message_loop_.PostTask(FROM_HERE, MessageLoop::QuitWhenIdleClosure());
101 message_loop_.Run();
102 }
103
[email protected]3a305db2011-04-12 13:40:53104 // The path to temporary directory used to contain the test operations.
[email protected]ea1a3f62012-11-16 20:34:23105 base::ScopedTempDir temp_dir_;
[email protected]3a305db2011-04-12 13:40:53106 // The path to the directory where the test data is stored.
[email protected]023ad6ab2013-02-17 05:07:23107 base::FilePath data_dir_;
[email protected]ea587b02010-05-21 15:01:35108 // A message loop that we can use as the file thread message loop.
109 MessageLoop message_loop_;
[email protected]277404c22010-04-22 13:09:45110};
111
112// Test fallback behavior for a nonexistent file.
113TEST_F(JsonPrefStoreTest, NonExistentFile) {
[email protected]023ad6ab2013-02-17 05:07:23114 base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
[email protected]7567484142013-07-11 17:36:07115 ASSERT_FALSE(PathExists(bogus_input_file));
[email protected]cadac622013-06-11 16:46:36116 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
[email protected]56cbcb3a2013-12-23 21:24:46117 bogus_input_file,
118 message_loop_.message_loop_proxy().get(),
119 scoped_ptr<PrefFilter>());
[email protected]f2d1f612010-12-09 15:10:17120 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE,
[email protected]9a8c4022011-01-25 14:25:33121 pref_store->ReadPrefs());
122 EXPECT_FALSE(pref_store->ReadOnly());
[email protected]277404c22010-04-22 13:09:45123}
124
125// Test fallback behavior for an invalid file.
126TEST_F(JsonPrefStoreTest, InvalidFile) {
[email protected]023ad6ab2013-02-17 05:07:23127 base::FilePath invalid_file_original = data_dir_.AppendASCII("invalid.json");
128 base::FilePath invalid_file = temp_dir_.path().AppendASCII("invalid.json");
[email protected]f0ff2ad2013-07-09 17:42:26129 ASSERT_TRUE(base::CopyFile(invalid_file_original, invalid_file));
[email protected]9a8c4022011-01-25 14:25:33130 scoped_refptr<JsonPrefStore> pref_store =
[email protected]56cbcb3a2013-12-23 21:24:46131 new JsonPrefStore(invalid_file,
132 message_loop_.message_loop_proxy().get(),
133 scoped_ptr<PrefFilter>());
[email protected]f2d1f612010-12-09 15:10:17134 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE,
[email protected]9a8c4022011-01-25 14:25:33135 pref_store->ReadPrefs());
136 EXPECT_FALSE(pref_store->ReadOnly());
[email protected]277404c22010-04-22 13:09:45137
138 // The file should have been moved aside.
[email protected]7567484142013-07-11 17:36:07139 EXPECT_FALSE(PathExists(invalid_file));
[email protected]023ad6ab2013-02-17 05:07:23140 base::FilePath moved_aside = temp_dir_.path().AppendASCII("invalid.bad");
[email protected]7567484142013-07-11 17:36:07141 EXPECT_TRUE(PathExists(moved_aside));
[email protected]dcd16612013-07-15 20:18:09142 EXPECT_TRUE(TextContentsEqual(invalid_file_original, moved_aside));
[email protected]277404c22010-04-22 13:09:45143}
144
[email protected]845b43a82011-05-11 10:14:43145// This function is used to avoid code duplication while testing synchronous and
146// asynchronous version of the JsonPrefStore loading.
[email protected]0de615a2012-11-08 04:40:59147void RunBasicJsonPrefStoreTest(JsonPrefStore* pref_store,
[email protected]023ad6ab2013-02-17 05:07:23148 const base::FilePath& output_file,
149 const base::FilePath& golden_output_file) {
[email protected]57ecc4b2010-08-11 03:02:51150 const char kNewWindowsInTabs[] = "tabs.new_windows_in_tabs";
151 const char kMaxTabs[] = "tabs.max_tabs";
152 const char kLongIntPref[] = "long_int.pref";
[email protected]277404c22010-04-22 13:09:45153
[email protected]57ecc4b2010-08-11 03:02:51154 std::string cnn("http://www.cnn.com");
[email protected]277404c22010-04-22 13:09:45155
[email protected]68bf41a2011-03-25 16:38:31156 const Value* actual;
[email protected]5bfdcfd2012-11-22 22:08:24157 EXPECT_TRUE(pref_store->GetValue(kHomePage, &actual));
[email protected]57ecc4b2010-08-11 03:02:51158 std::string string_value;
[email protected]f2d1f612010-12-09 15:10:17159 EXPECT_TRUE(actual->GetAsString(&string_value));
[email protected]277404c22010-04-22 13:09:45160 EXPECT_EQ(cnn, string_value);
161
[email protected]57ecc4b2010-08-11 03:02:51162 const char kSomeDirectory[] = "some_directory";
[email protected]277404c22010-04-22 13:09:45163
[email protected]892f1d62012-11-08 18:24:34164 EXPECT_TRUE(pref_store->GetValue(kSomeDirectory, &actual));
[email protected]023ad6ab2013-02-17 05:07:23165 base::FilePath::StringType path;
[email protected]f2d1f612010-12-09 15:10:17166 EXPECT_TRUE(actual->GetAsString(&path));
[email protected]023ad6ab2013-02-17 05:07:23167 EXPECT_EQ(base::FilePath::StringType(FILE_PATH_LITERAL("/usr/local/")), path);
168 base::FilePath some_path(FILE_PATH_LITERAL("/usr/sbin/"));
[email protected]f2d1f612010-12-09 15:10:17169
[email protected]7e3ec42c2012-12-16 05:13:21170 pref_store->SetValue(kSomeDirectory, new StringValue(some_path.value()));
[email protected]892f1d62012-11-08 18:24:34171 EXPECT_TRUE(pref_store->GetValue(kSomeDirectory, &actual));
[email protected]f2d1f612010-12-09 15:10:17172 EXPECT_TRUE(actual->GetAsString(&path));
[email protected]277404c22010-04-22 13:09:45173 EXPECT_EQ(some_path.value(), path);
174
175 // Test reading some other data types from sub-dictionaries.
[email protected]892f1d62012-11-08 18:24:34176 EXPECT_TRUE(pref_store->GetValue(kNewWindowsInTabs, &actual));
[email protected]f2d1f612010-12-09 15:10:17177 bool boolean = false;
178 EXPECT_TRUE(actual->GetAsBoolean(&boolean));
[email protected]277404c22010-04-22 13:09:45179 EXPECT_TRUE(boolean);
180
[email protected]7e3ec42c2012-12-16 05:13:21181 pref_store->SetValue(kNewWindowsInTabs, new FundamentalValue(false));
[email protected]892f1d62012-11-08 18:24:34182 EXPECT_TRUE(pref_store->GetValue(kNewWindowsInTabs, &actual));
[email protected]f2d1f612010-12-09 15:10:17183 EXPECT_TRUE(actual->GetAsBoolean(&boolean));
[email protected]277404c22010-04-22 13:09:45184 EXPECT_FALSE(boolean);
185
[email protected]892f1d62012-11-08 18:24:34186 EXPECT_TRUE(pref_store->GetValue(kMaxTabs, &actual));
[email protected]f2d1f612010-12-09 15:10:17187 int integer = 0;
188 EXPECT_TRUE(actual->GetAsInteger(&integer));
[email protected]277404c22010-04-22 13:09:45189 EXPECT_EQ(20, integer);
[email protected]7e3ec42c2012-12-16 05:13:21190 pref_store->SetValue(kMaxTabs, new FundamentalValue(10));
[email protected]892f1d62012-11-08 18:24:34191 EXPECT_TRUE(pref_store->GetValue(kMaxTabs, &actual));
[email protected]f2d1f612010-12-09 15:10:17192 EXPECT_TRUE(actual->GetAsInteger(&integer));
[email protected]277404c22010-04-22 13:09:45193 EXPECT_EQ(10, integer);
194
[email protected]9a8c4022011-01-25 14:25:33195 pref_store->SetValue(kLongIntPref,
[email protected]7e3ec42c2012-12-16 05:13:21196 new StringValue(base::Int64ToString(214748364842LL)));
[email protected]892f1d62012-11-08 18:24:34197 EXPECT_TRUE(pref_store->GetValue(kLongIntPref, &actual));
[email protected]f2d1f612010-12-09 15:10:17198 EXPECT_TRUE(actual->GetAsString(&string_value));
[email protected]e83326f2010-07-31 17:29:25199 int64 value;
[email protected]57ecc4b2010-08-11 03:02:51200 base::StringToInt64(string_value, &value);
[email protected]e83326f2010-07-31 17:29:25201 EXPECT_EQ(214748364842LL, value);
[email protected]277404c22010-04-22 13:09:45202
203 // Serialize and compare to expected output.
[email protected]7567484142013-07-11 17:36:07204 ASSERT_TRUE(PathExists(golden_output_file));
[email protected]fbe17c8a2011-12-27 16:41:48205 pref_store->CommitPendingWrite();
[email protected]f7b98b32013-02-05 08:14:15206 RunLoop().RunUntilIdle();
[email protected]dcd16612013-07-15 20:18:09207 EXPECT_TRUE(TextContentsEqual(golden_output_file, output_file));
[email protected]dd3aa792013-07-16 19:10:23208 ASSERT_TRUE(base::DeleteFile(output_file, false));
[email protected]277404c22010-04-22 13:09:45209}
[email protected]845b43a82011-05-11 10:14:43210
211TEST_F(JsonPrefStoreTest, Basic) {
[email protected]f0ff2ad2013-07-09 17:42:26212 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"),
[email protected]e33c9512014-05-12 02:24:13213 temp_dir_.path().AppendASCII("write.json")));
[email protected]845b43a82011-05-11 10:14:43214
215 // Test that the persistent value can be loaded.
[email protected]023ad6ab2013-02-17 05:07:23216 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
[email protected]7567484142013-07-11 17:36:07217 ASSERT_TRUE(PathExists(input_file));
[email protected]56cbcb3a2013-12-23 21:24:46218 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
219 input_file,
220 message_loop_.message_loop_proxy().get(),
221 scoped_ptr<PrefFilter>());
[email protected]845b43a82011-05-11 10:14:43222 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
[email protected]e33c9512014-05-12 02:24:13223 EXPECT_FALSE(pref_store->ReadOnly());
224 EXPECT_TRUE(pref_store->IsInitializationComplete());
[email protected]845b43a82011-05-11 10:14:43225
226 // The JSON file looks like this:
227 // {
228 // "homepage": "http://www.cnn.com",
229 // "some_directory": "/usr/local/",
230 // "tabs": {
231 // "new_windows_in_tabs": true,
232 // "max_tabs": 20
233 // }
234 // }
235
[email protected]3703e922013-05-31 21:37:53236 RunBasicJsonPrefStoreTest(
237 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
[email protected]845b43a82011-05-11 10:14:43238}
239
240TEST_F(JsonPrefStoreTest, BasicAsync) {
[email protected]f0ff2ad2013-07-09 17:42:26241 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"),
[email protected]e33c9512014-05-12 02:24:13242 temp_dir_.path().AppendASCII("write.json")));
[email protected]845b43a82011-05-11 10:14:43243
244 // Test that the persistent value can be loaded.
[email protected]023ad6ab2013-02-17 05:07:23245 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
[email protected]7567484142013-07-11 17:36:07246 ASSERT_TRUE(PathExists(input_file));
[email protected]56cbcb3a2013-12-23 21:24:46247 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
248 input_file,
249 message_loop_.message_loop_proxy().get(),
250 scoped_ptr<PrefFilter>());
[email protected]845b43a82011-05-11 10:14:43251
[email protected]0de615a2012-11-08 04:40:59252 {
253 MockPrefStoreObserver mock_observer;
254 pref_store->AddObserver(&mock_observer);
[email protected]845b43a82011-05-11 10:14:43255
[email protected]0de615a2012-11-08 04:40:59256 MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate;
257 pref_store->ReadPrefsAsync(mock_error_delegate);
[email protected]845b43a82011-05-11 10:14:43258
[email protected]0de615a2012-11-08 04:40:59259 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
260 EXPECT_CALL(*mock_error_delegate,
261 OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
[email protected]7ff48ca2013-02-06 16:56:19262 RunLoop().RunUntilIdle();
[email protected]0de615a2012-11-08 04:40:59263 pref_store->RemoveObserver(&mock_observer);
[email protected]845b43a82011-05-11 10:14:43264
[email protected]e33c9512014-05-12 02:24:13265 EXPECT_FALSE(pref_store->ReadOnly());
266 EXPECT_TRUE(pref_store->IsInitializationComplete());
[email protected]0de615a2012-11-08 04:40:59267 }
[email protected]845b43a82011-05-11 10:14:43268
269 // The JSON file looks like this:
270 // {
271 // "homepage": "http://www.cnn.com",
272 // "some_directory": "/usr/local/",
273 // "tabs": {
274 // "new_windows_in_tabs": true,
275 // "max_tabs": 20
276 // }
277 // }
278
[email protected]3703e922013-05-31 21:37:53279 RunBasicJsonPrefStoreTest(
280 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
[email protected]845b43a82011-05-11 10:14:43281}
282
[email protected]aa3283392013-11-27 01:38:24283TEST_F(JsonPrefStoreTest, PreserveEmptyValues) {
284 FilePath pref_file = temp_dir_.path().AppendASCII("empty_values.json");
285
[email protected]56cbcb3a2013-12-23 21:24:46286 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
287 pref_file,
288 message_loop_.message_loop_proxy(),
289 scoped_ptr<PrefFilter>());
[email protected]aa3283392013-11-27 01:38:24290
291 // Set some keys with empty values.
292 pref_store->SetValue("list", new base::ListValue);
293 pref_store->SetValue("dict", new base::DictionaryValue);
294
295 // Write to file.
296 pref_store->CommitPendingWrite();
297 MessageLoop::current()->RunUntilIdle();
298
299 // Reload.
[email protected]56cbcb3a2013-12-23 21:24:46300 pref_store = new JsonPrefStore(
301 pref_file,
302 message_loop_.message_loop_proxy(),
303 scoped_ptr<PrefFilter>());
[email protected]aa3283392013-11-27 01:38:24304 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
305 ASSERT_FALSE(pref_store->ReadOnly());
306
307 // Check values.
308 const Value* result = NULL;
309 EXPECT_TRUE(pref_store->GetValue("list", &result));
310 EXPECT_TRUE(ListValue().Equals(result));
311 EXPECT_TRUE(pref_store->GetValue("dict", &result));
312 EXPECT_TRUE(DictionaryValue().Equals(result));
313}
314
[email protected]eeedaa692014-01-30 09:22:27315// This test is just documenting some potentially non-obvious behavior. It
316// shouldn't be taken as normative.
317TEST_F(JsonPrefStoreTest, RemoveClearsEmptyParent) {
318 FilePath pref_file = temp_dir_.path().AppendASCII("empty_values.json");
319
320 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
321 pref_file,
322 message_loop_.message_loop_proxy(),
323 scoped_ptr<PrefFilter>());
324
325 base::DictionaryValue* dict = new base::DictionaryValue;
326 dict->SetString("key", "value");
327 pref_store->SetValue("dict", dict);
328
329 pref_store->RemoveValue("dict.key");
330
331 const base::Value* retrieved_dict = NULL;
332 bool has_dict = pref_store->GetValue("dict", &retrieved_dict);
333 EXPECT_FALSE(has_dict);
334}
335
[email protected]845b43a82011-05-11 10:14:43336// Tests asynchronous reading of the file when there is no file.
337TEST_F(JsonPrefStoreTest, AsyncNonExistingFile) {
[email protected]023ad6ab2013-02-17 05:07:23338 base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
[email protected]7567484142013-07-11 17:36:07339 ASSERT_FALSE(PathExists(bogus_input_file));
[email protected]cadac622013-06-11 16:46:36340 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
[email protected]56cbcb3a2013-12-23 21:24:46341 bogus_input_file,
342 message_loop_.message_loop_proxy().get(),
343 scoped_ptr<PrefFilter>());
[email protected]845b43a82011-05-11 10:14:43344 MockPrefStoreObserver mock_observer;
345 pref_store->AddObserver(&mock_observer);
346
347 MockReadErrorDelegate *mock_error_delegate = new MockReadErrorDelegate;
348 pref_store->ReadPrefsAsync(mock_error_delegate);
349
350 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
351 EXPECT_CALL(*mock_error_delegate,
352 OnError(PersistentPrefStore::PREF_READ_ERROR_NO_FILE)).Times(1);
[email protected]7ff48ca2013-02-06 16:56:19353 RunLoop().RunUntilIdle();
[email protected]845b43a82011-05-11 10:14:43354 pref_store->RemoveObserver(&mock_observer);
355
356 EXPECT_FALSE(pref_store->ReadOnly());
357}
[email protected]ea3e4972012-04-12 03:41:37358
[email protected]e33c9512014-05-12 02:24:13359TEST_F(JsonPrefStoreTest, ReadWithInterceptor) {
360 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"),
361 temp_dir_.path().AppendASCII("write.json")));
362
363 // Test that the persistent value can be loaded.
364 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
365 ASSERT_TRUE(PathExists(input_file));
366
367 scoped_ptr<InterceptingPrefFilter> intercepting_pref_filter(
368 new InterceptingPrefFilter());
369 InterceptingPrefFilter* raw_intercepting_pref_filter_ =
370 intercepting_pref_filter.get();
371 scoped_refptr<JsonPrefStore> pref_store =
372 new JsonPrefStore(input_file,
373 message_loop_.message_loop_proxy().get(),
374 intercepting_pref_filter.PassAs<PrefFilter>());
375
376 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE,
377 pref_store->ReadPrefs());
378 EXPECT_FALSE(pref_store->ReadOnly());
379
380 // The store shouldn't be considered initialized until the interceptor
381 // returns.
382 EXPECT_TRUE(raw_intercepting_pref_filter_->has_intercepted_prefs());
383 EXPECT_FALSE(pref_store->IsInitializationComplete());
384 EXPECT_FALSE(pref_store->GetValue(kHomePage, NULL));
385
386 raw_intercepting_pref_filter_->ReleasePrefs();
387
388 EXPECT_FALSE(raw_intercepting_pref_filter_->has_intercepted_prefs());
389 EXPECT_TRUE(pref_store->IsInitializationComplete());
390 EXPECT_TRUE(pref_store->GetValue(kHomePage, NULL));
391
392 // The JSON file looks like this:
393 // {
394 // "homepage": "http://www.cnn.com",
395 // "some_directory": "/usr/local/",
396 // "tabs": {
397 // "new_windows_in_tabs": true,
398 // "max_tabs": 20
399 // }
400 // }
401
402 RunBasicJsonPrefStoreTest(
403 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
404}
405
406TEST_F(JsonPrefStoreTest, ReadAsyncWithInterceptor) {
407 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"),
408 temp_dir_.path().AppendASCII("write.json")));
409
410 // Test that the persistent value can be loaded.
411 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
412 ASSERT_TRUE(PathExists(input_file));
413
414 scoped_ptr<InterceptingPrefFilter> intercepting_pref_filter(
415 new InterceptingPrefFilter());
416 InterceptingPrefFilter* raw_intercepting_pref_filter_ =
417 intercepting_pref_filter.get();
418 scoped_refptr<JsonPrefStore> pref_store =
419 new JsonPrefStore(input_file,
420 message_loop_.message_loop_proxy().get(),
421 intercepting_pref_filter.PassAs<PrefFilter>());
422
423 MockPrefStoreObserver mock_observer;
424 pref_store->AddObserver(&mock_observer);
425
426 // Ownership of the |mock_error_delegate| is handed to the |pref_store| below.
427 MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate;
428
429 {
430 pref_store->ReadPrefsAsync(mock_error_delegate);
431
432 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(0);
433 // EXPECT_CALL(*mock_error_delegate,
434 // OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
435 RunLoop().RunUntilIdle();
436
437 EXPECT_FALSE(pref_store->ReadOnly());
438 EXPECT_TRUE(raw_intercepting_pref_filter_->has_intercepted_prefs());
439 EXPECT_FALSE(pref_store->IsInitializationComplete());
440 EXPECT_FALSE(pref_store->GetValue(kHomePage, NULL));
441 }
442
443 {
444 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
445 // EXPECT_CALL(*mock_error_delegate,
446 // OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
447
448 raw_intercepting_pref_filter_->ReleasePrefs();
449
450 EXPECT_FALSE(pref_store->ReadOnly());
451 EXPECT_FALSE(raw_intercepting_pref_filter_->has_intercepted_prefs());
452 EXPECT_TRUE(pref_store->IsInitializationComplete());
453 EXPECT_TRUE(pref_store->GetValue(kHomePage, NULL));
454 }
455
456 pref_store->RemoveObserver(&mock_observer);
457
458 // The JSON file looks like this:
459 // {
460 // "homepage": "http://www.cnn.com",
461 // "some_directory": "/usr/local/",
462 // "tabs": {
463 // "new_windows_in_tabs": true,
464 // "max_tabs": 20
465 // }
466 // }
467
468 RunBasicJsonPrefStoreTest(
469 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
470}
471
[email protected]7e3ec42c2012-12-16 05:13:21472} // namespace base