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 "extensions/browser/value_store/value_store_unittest.h"
6
7#include "base/json/json_writer.h"
8#include "base/memory/linked_ptr.h"
9#include "base/values.h"
10
11using content::BrowserThread;
12
13namespace {
14
15// To save typing ValueStore::DEFAULTS everywhere.
16const ValueStore::WriteOptions DEFAULTS = ValueStore::DEFAULTS;
17
18// Gets the pretty-printed JSON for a value.
19std::string GetJSON(const base::Value& value) {
20  std::string json;
21  base::JSONWriter::WriteWithOptions(&value,
22                                     base::JSONWriter::OPTIONS_PRETTY_PRINT,
23                                     &json);
24  return json;
25}
26
27}  // namespace
28
29// Compares two possibly NULL values for equality, filling |error| with an
30// appropriate error message if they're different.
31bool ValuesEqual(const base::Value* expected,
32                 const base::Value* actual,
33                 std::string* error) {
34  if (expected == actual) {
35    return true;
36  }
37  if (expected && !actual) {
38    *error = "Expected: " + GetJSON(*expected) + ", actual: NULL";
39    return false;
40  }
41  if (actual && !expected) {
42    *error = "Expected: NULL, actual: " + GetJSON(*actual);
43    return false;
44  }
45  if (!expected->Equals(actual)) {
46    *error =
47        "Expected: " + GetJSON(*expected) + ", actual: " + GetJSON(*actual);
48    return false;
49  }
50  return true;
51}
52
53// Returns whether the read result of a storage operation has the expected
54// settings.
55testing::AssertionResult SettingsEq(
56    const char* _1, const char* _2,
57    const base::DictionaryValue& expected,
58    ValueStore::ReadResult actual_result) {
59  if (actual_result->HasError()) {
60    return testing::AssertionFailure() <<
61        "Result has error: " << actual_result->error().message;
62  }
63
64  std::string error;
65  if (!ValuesEqual(&expected, &actual_result->settings(), &error)) {
66    return testing::AssertionFailure() << error;
67  }
68
69  return testing::AssertionSuccess();
70}
71
72// Returns whether the write result of a storage operation has the expected
73// changes.
74testing::AssertionResult ChangesEq(
75    const char* _1, const char* _2,
76    const ValueStoreChangeList& expected,
77    ValueStore::WriteResult actual_result) {
78  if (actual_result->HasError()) {
79    return testing::AssertionFailure() <<
80        "Result has error: " << actual_result->error().message;
81  }
82
83  const ValueStoreChangeList& actual = actual_result->changes();
84  if (expected.size() != actual.size()) {
85    return testing::AssertionFailure() <<
86        "Actual has wrong size, expecting " << expected.size() <<
87        " but was " << actual.size();
88  }
89
90  std::map<std::string, linked_ptr<ValueStoreChange> > expected_as_map;
91  for (ValueStoreChangeList::const_iterator it = expected.begin();
92      it != expected.end(); ++it) {
93    expected_as_map[it->key()] =
94        linked_ptr<ValueStoreChange>(new ValueStoreChange(*it));
95  }
96
97  std::set<std::string> keys_seen;
98
99  for (ValueStoreChangeList::const_iterator it = actual.begin();
100      it != actual.end(); ++it) {
101    if (keys_seen.count(it->key())) {
102      return testing::AssertionFailure() <<
103          "Multiple changes seen for key: " << it->key();
104    }
105    keys_seen.insert(it->key());
106
107    if (!expected_as_map.count(it->key())) {
108      return testing::AssertionFailure() <<
109          "Actual has unexpected change for key: " << it->key();
110    }
111
112    ValueStoreChange expected_change = *expected_as_map[it->key()];
113    std::string error;
114    if (!ValuesEqual(expected_change.new_value(), it->new_value(), &error)) {
115      return testing::AssertionFailure() <<
116          "New value for " << it->key() << " was unexpected: " << error;
117    }
118    if (!ValuesEqual(expected_change.old_value(), it->old_value(), &error)) {
119      return testing::AssertionFailure() <<
120          "Old value for " << it->key() << " was unexpected: " << error;
121    }
122  }
123
124  return testing::AssertionSuccess();
125}
126
127ValueStoreTest::ValueStoreTest()
128    : key1_("foo"),
129      key2_("bar"),
130      key3_("baz"),
131      empty_dict_(new base::DictionaryValue()),
132      dict1_(new base::DictionaryValue()),
133      dict3_(new base::DictionaryValue()),
134      dict12_(new base::DictionaryValue()),
135      dict123_(new base::DictionaryValue()),
136      ui_thread_(BrowserThread::UI, base::MessageLoop::current()),
137      file_thread_(BrowserThread::FILE, base::MessageLoop::current()) {
138  val1_.reset(new base::StringValue(key1_ + "Value"));
139  val2_.reset(new base::StringValue(key2_ + "Value"));
140  val3_.reset(new base::StringValue(key3_ + "Value"));
141
142  list1_.push_back(key1_);
143  list2_.push_back(key2_);
144  list3_.push_back(key3_);
145  list12_.push_back(key1_);
146  list12_.push_back(key2_);
147  list13_.push_back(key1_);
148  list13_.push_back(key3_);
149  list123_.push_back(key1_);
150  list123_.push_back(key2_);
151  list123_.push_back(key3_);
152
153  set1_.insert(list1_.begin(), list1_.end());
154  set2_.insert(list2_.begin(), list2_.end());
155  set3_.insert(list3_.begin(), list3_.end());
156  set12_.insert(list12_.begin(), list12_.end());
157  set13_.insert(list13_.begin(), list13_.end());
158  set123_.insert(list123_.begin(), list123_.end());
159
160  dict1_->Set(key1_, val1_->DeepCopy());
161  dict3_->Set(key3_, val3_->DeepCopy());
162  dict12_->Set(key1_, val1_->DeepCopy());
163  dict12_->Set(key2_, val2_->DeepCopy());
164  dict123_->Set(key1_, val1_->DeepCopy());
165  dict123_->Set(key2_, val2_->DeepCopy());
166  dict123_->Set(key3_, val3_->DeepCopy());
167}
168
169ValueStoreTest::~ValueStoreTest() {}
170
171void ValueStoreTest::SetUp() {
172  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
173  storage_.reset((GetParam())(temp_dir_.path().AppendASCII("dbName")));
174  ASSERT_TRUE(storage_.get());
175}
176
177void ValueStoreTest::TearDown() {
178  storage_.reset();
179}
180
181TEST_P(ValueStoreTest, GetWhenEmpty) {
182  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_));
183  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_));
184  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list123_));
185  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get());
186}
187
188TEST_P(ValueStoreTest, GetWithSingleValue) {
189  {
190    ValueStoreChangeList changes;
191    changes.push_back(ValueStoreChange(key1_, NULL, val1_->DeepCopy()));
192    EXPECT_PRED_FORMAT2(ChangesEq,
193        changes, storage_->Set(DEFAULTS, key1_, *val1_));
194  }
195
196  EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(key1_));
197  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key2_));
198  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key3_));
199  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_));
200  EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(list123_));
201  EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get());
202}
203
204TEST_P(ValueStoreTest, GetWithMultipleValues) {
205  {
206    ValueStoreChangeList changes;
207    changes.push_back(ValueStoreChange(key1_, NULL, val1_->DeepCopy()));
208    changes.push_back(ValueStoreChange(key2_, NULL, val2_->DeepCopy()));
209    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, *dict12_));
210  }
211
212  EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(key1_));
213  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key3_));
214  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_));
215  EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get(list123_));
216  EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get());
217}
218
219TEST_P(ValueStoreTest, RemoveWhenEmpty) {
220  EXPECT_PRED_FORMAT2(ChangesEq, ValueStoreChangeList(),
221                      storage_->Remove(key1_));
222
223  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_));
224  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list1_));
225  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get());
226}
227
228TEST_P(ValueStoreTest, RemoveWithSingleValue) {
229  storage_->Set(DEFAULTS, *dict1_);
230  {
231    ValueStoreChangeList changes;
232    changes.push_back(ValueStoreChange(key1_, val1_->DeepCopy(), NULL));
233    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(key1_));
234  }
235
236  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_));
237  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key2_));
238  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list1_));
239  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list12_));
240  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get());
241}
242
243TEST_P(ValueStoreTest, RemoveWithMultipleValues) {
244  storage_->Set(DEFAULTS, *dict123_);
245  {
246    ValueStoreChangeList changes;
247    changes.push_back(ValueStoreChange(key3_, val3_->DeepCopy(), NULL));
248    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(key3_));
249  }
250
251  EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(key1_));
252  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key3_));
253  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_));
254  EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(list1_));
255  EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get(list12_));
256  EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(list13_));
257  EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get(list123_));
258  EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get());
259
260  {
261    ValueStoreChangeList changes;
262    changes.push_back(ValueStoreChange(key1_, val1_->DeepCopy(), NULL));
263    changes.push_back(ValueStoreChange(key2_, val2_->DeepCopy(), NULL));
264    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(list12_));
265  }
266
267  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_));
268  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key3_));
269  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_));
270  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list1_));
271  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list12_));
272  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list13_));
273  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list123_));
274  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get());
275}
276
277TEST_P(ValueStoreTest, SetWhenOverwriting) {
278  storage_->Set(DEFAULTS, key1_, *val2_);
279  {
280    ValueStoreChangeList changes;
281    changes.push_back(
282        ValueStoreChange(key1_, val2_->DeepCopy(), val1_->DeepCopy()));
283    changes.push_back(ValueStoreChange(key2_, NULL, val2_->DeepCopy()));
284    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, *dict12_));
285  }
286
287  EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(key1_));
288  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key3_));
289  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_));
290  EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(list1_));
291  EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get(list12_));
292  EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(list13_));
293  EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get(list123_));
294  EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get());
295}
296
297TEST_P(ValueStoreTest, ClearWhenEmpty) {
298  EXPECT_PRED_FORMAT2(ChangesEq, ValueStoreChangeList(), storage_->Clear());
299
300  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_));
301  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_));
302  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list123_));
303  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get());
304}
305
306TEST_P(ValueStoreTest, ClearWhenNotEmpty) {
307  storage_->Set(DEFAULTS, *dict12_);
308  {
309    ValueStoreChangeList changes;
310    changes.push_back(ValueStoreChange(key1_, val1_->DeepCopy(), NULL));
311    changes.push_back(ValueStoreChange(key2_, val2_->DeepCopy(), NULL));
312    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Clear());
313  }
314
315  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_));
316  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_));
317  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list123_));
318  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get());
319}
320
321// Dots should be allowed in key names; they shouldn't be interpreted as
322// indexing into a dictionary.
323TEST_P(ValueStoreTest, DotsInKeyNames) {
324  std::string dot_key("foo.bar");
325  base::StringValue dot_value("baz.qux");
326  std::vector<std::string> dot_list;
327  dot_list.push_back(dot_key);
328  base::DictionaryValue dot_dict;
329  dot_dict.SetWithoutPathExpansion(dot_key, dot_value.DeepCopy());
330
331  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(dot_key));
332
333  {
334    ValueStoreChangeList changes;
335    changes.push_back(
336        ValueStoreChange(dot_key, NULL, dot_value.DeepCopy()));
337    EXPECT_PRED_FORMAT2(ChangesEq,
338        changes, storage_->Set(DEFAULTS, dot_key, dot_value));
339  }
340  EXPECT_PRED_FORMAT2(ChangesEq,
341      ValueStoreChangeList(), storage_->Set(DEFAULTS, dot_key, dot_value));
342
343  EXPECT_PRED_FORMAT2(SettingsEq, dot_dict, storage_->Get(dot_key));
344
345  {
346    ValueStoreChangeList changes;
347    changes.push_back(
348        ValueStoreChange(dot_key, dot_value.DeepCopy(), NULL));
349    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(dot_key));
350  }
351  EXPECT_PRED_FORMAT2(ChangesEq,
352      ValueStoreChangeList(), storage_->Remove(dot_key));
353  {
354    ValueStoreChangeList changes;
355    changes.push_back(
356        ValueStoreChange(dot_key, NULL, dot_value.DeepCopy()));
357    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, dot_dict));
358  }
359
360  EXPECT_PRED_FORMAT2(SettingsEq, dot_dict, storage_->Get(dot_list));
361  EXPECT_PRED_FORMAT2(SettingsEq, dot_dict, storage_->Get());
362
363  {
364    ValueStoreChangeList changes;
365    changes.push_back(
366        ValueStoreChange(dot_key, dot_value.DeepCopy(), NULL));
367    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(dot_list));
368  }
369
370  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(dot_key));
371  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get());
372}
373
374TEST_P(ValueStoreTest, DotsInKeyNamesWithDicts) {
375  base::DictionaryValue outer_dict;
376  base::DictionaryValue* inner_dict = new base::DictionaryValue();
377  outer_dict.Set("foo", inner_dict);
378  inner_dict->SetString("bar", "baz");
379
380  {
381    ValueStoreChangeList changes;
382    changes.push_back(
383        ValueStoreChange("foo", NULL, inner_dict->DeepCopy()));
384    EXPECT_PRED_FORMAT2(ChangesEq,
385        changes, storage_->Set(DEFAULTS, outer_dict));
386  }
387
388  EXPECT_PRED_FORMAT2(SettingsEq, outer_dict, storage_->Get("foo"));
389  EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get("foo.bar"));
390}
391
392TEST_P(ValueStoreTest, ComplexChangedKeysScenarios) {
393  // Test:
394  //   - Setting over missing/changed/same keys, combinations.
395  //   - Removing over missing and present keys, combinations.
396  //   - Clearing.
397  std::vector<std::string> complex_list;
398  base::DictionaryValue complex_changed_dict;
399
400  storage_->Set(DEFAULTS, key1_, *val1_);
401  EXPECT_PRED_FORMAT2(ChangesEq,
402      ValueStoreChangeList(), storage_->Set(DEFAULTS, key1_, *val1_));
403  {
404    ValueStoreChangeList changes;
405    changes.push_back(ValueStoreChange(
406        key1_, val1_->DeepCopy(), val2_->DeepCopy()));
407    EXPECT_PRED_FORMAT2(ChangesEq,
408        changes, storage_->Set(DEFAULTS, key1_, *val2_));
409  }
410  {
411    ValueStoreChangeList changes;
412    changes.push_back(ValueStoreChange(key1_, val2_->DeepCopy(), NULL));
413    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(key1_));
414    EXPECT_PRED_FORMAT2(ChangesEq,
415        ValueStoreChangeList(), storage_->Remove(key1_));
416  }
417  {
418    ValueStoreChangeList changes;
419    changes.push_back(ValueStoreChange(key1_, NULL, val1_->DeepCopy()));
420    EXPECT_PRED_FORMAT2(ChangesEq,
421        changes, storage_->Set(DEFAULTS, key1_, *val1_));
422  }
423  {
424    ValueStoreChangeList changes;
425    changes.push_back(ValueStoreChange(key1_, val1_->DeepCopy(), NULL));
426    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Clear());
427    EXPECT_PRED_FORMAT2(ChangesEq, ValueStoreChangeList(), storage_->Clear());
428  }
429
430  {
431    ValueStoreChangeList changes;
432    changes.push_back(ValueStoreChange(key1_, NULL, val1_->DeepCopy()));
433    changes.push_back(ValueStoreChange(key2_, NULL, val2_->DeepCopy()));
434    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, *dict12_));
435    EXPECT_PRED_FORMAT2(ChangesEq,
436        ValueStoreChangeList(), storage_->Set(DEFAULTS, *dict12_));
437  }
438  {
439    ValueStoreChangeList changes;
440    changes.push_back(ValueStoreChange(key3_, NULL, val3_->DeepCopy()));
441    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, *dict123_));
442  }
443  {
444    base::DictionaryValue to_set;
445    to_set.Set(key1_, val2_->DeepCopy());
446    to_set.Set(key2_, val2_->DeepCopy());
447    to_set.Set("asdf", val1_->DeepCopy());
448    to_set.Set("qwerty", val3_->DeepCopy());
449
450    ValueStoreChangeList changes;
451    changes.push_back(
452        ValueStoreChange(key1_, val1_->DeepCopy(), val2_->DeepCopy()));
453    changes.push_back(ValueStoreChange("asdf", NULL, val1_->DeepCopy()));
454    changes.push_back(
455        ValueStoreChange("qwerty", NULL, val3_->DeepCopy()));
456    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, to_set));
457  }
458  {
459    ValueStoreChangeList changes;
460    changes.push_back(ValueStoreChange(key1_, val2_->DeepCopy(), NULL));
461    changes.push_back(ValueStoreChange(key2_, val2_->DeepCopy(), NULL));
462    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(list12_));
463  }
464  {
465    std::vector<std::string> to_remove;
466    to_remove.push_back(key1_);
467    to_remove.push_back("asdf");
468
469    ValueStoreChangeList changes;
470    changes.push_back(ValueStoreChange("asdf", val1_->DeepCopy(), NULL));
471    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(to_remove));
472  }
473  {
474    ValueStoreChangeList changes;
475    changes.push_back(ValueStoreChange(key3_, val3_->DeepCopy(), NULL));
476    changes.push_back(
477        ValueStoreChange("qwerty", val3_->DeepCopy(), NULL));
478    EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Clear());
479    EXPECT_PRED_FORMAT2(ChangesEq, ValueStoreChangeList(), storage_->Clear());
480  }
481}
482