test_extension_prefs.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/test_extension_prefs.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop_proxy.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/prefs/json_pref_store.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_value_store.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/run_loop.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sequenced_task_runner.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_pref_store.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_pref_value_map.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_prefs.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/pref_service_mock_builder.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/prefs/pref_service_syncable.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_manifest_constants.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/user_prefs/pref_registry_syncable.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/string_ordinal.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A TimeProvider which returns an incrementally later time each time
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// GetCurrentTime is called.
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class IncrementalTimeProvider : public ExtensionPrefs::TimeProvider {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IncrementalTimeProvider() : current_time_(base::Time::Now()) {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~IncrementalTimeProvider() {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual base::Time GetCurrentTime() const OVERRIDE {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_time_ += base::TimeDelta::FromSeconds(10);
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return current_time_;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(IncrementalTimeProvider);
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mutable base::Time current_time_;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TestExtensionPrefs::TestExtensionPrefs(base::SequencedTaskRunner* task_runner)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : pref_service_(NULL),
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      task_runner_(task_runner),
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions_disabled_(false) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  preferences_file_ = temp_dir_.path().AppendASCII("Preferences");
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions_dir_ = temp_dir_.path().AppendASCII("Extensions");
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(file_util::CreateDirectory(extensions_dir_));
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResetPrefRegistry();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RecreateExtensionPrefs();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestExtensionPrefs::~TestExtensionPrefs() {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrefService* TestExtensionPrefs::pref_service() {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return pref_service_.get();
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const scoped_refptr<PrefRegistrySyncable>& TestExtensionPrefs::pref_registry() {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return pref_registry_;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestExtensionPrefs::ResetPrefRegistry() {
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pref_registry_ = new PrefRegistrySyncable;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionPrefs::RegisterUserPrefs(pref_registry_);
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestExtensionPrefs::RecreateExtensionPrefs() {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We persist and reload the PrefService's PrefStores because this process
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deletes all empty dictionaries. The ExtensionPrefs implementation
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // needs to be able to handle this situation.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pref_service_.get()) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Commit a pending write (which posts a task to task_runner_) and wait for
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // it to finish.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pref_service_->CommitPendingWrite();
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::RunLoop run_loop;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        task_runner_->PostTaskAndReply(
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            FROM_HERE,
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            base::Bind(&base::DoNothing),
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            run_loop.QuitClosure()));
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    run_loop.Run();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_pref_value_map_.reset(new ExtensionPrefValueMap);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefServiceMockBuilder builder;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  builder.WithUserFilePrefs(preferences_file_, task_runner_);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  builder.WithExtensionPrefs(
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ExtensionPrefStore(extension_pref_value_map_.get(), false));
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pref_service_.reset(builder.CreateSyncable(pref_registry_));
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs_ = ExtensionPrefs::Create(
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pref_service_.get(),
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      temp_dir_.path(),
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension_pref_value_map_.get(),
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions_disabled_,
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Guarantee that no two extensions get the same installation time
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // stamp and we can reliably assert the installation order in the tests.
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<ExtensionPrefs::TimeProvider>(
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new IncrementalTimeProvider()));
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Extension> TestExtensionPrefs::AddExtension(std::string name) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue dictionary;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dictionary.SetString(extension_manifest_keys::kName, name);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dictionary.SetString(extension_manifest_keys::kVersion, "0.1");
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return AddExtensionWithManifest(dictionary, Manifest::INTERNAL);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Extension> TestExtensionPrefs::AddApp(std::string name) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue dictionary;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dictionary.SetString(extension_manifest_keys::kName, name);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dictionary.SetString(extension_manifest_keys::kVersion, "0.1");
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dictionary.SetString(extension_manifest_keys::kApp, "true");
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dictionary.SetString(extension_manifest_keys::kLaunchWebURL,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       "http://example.com");
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return AddExtensionWithManifest(dictionary, Manifest::INTERNAL);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Extension> TestExtensionPrefs::AddExtensionWithManifest(
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DictionaryValue& manifest, Manifest::Location location) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return AddExtensionWithManifestAndFlags(manifest, location,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          Extension::NO_FLAGS);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Extension> TestExtensionPrefs::AddExtensionWithManifestAndFlags(
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const DictionaryValue& manifest,
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Manifest::Location location,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int extra_flags) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string name;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(manifest.GetString(extension_manifest_keys::kName, &name));
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path =  extensions_dir_.AppendASCII(name);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string errors;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> extension = Extension::Create(
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path, location, manifest, extra_flags, &errors);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(extension) << errors;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extension)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Extension::IdIsValid(extension->id()));
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs_->OnExtensionInstalled(extension, Extension::ENABLED,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               syncer::StringOrdinal::CreateInitialOrdinal());
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extension;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestExtensionPrefs::AddExtensionAndReturnId(std::string name) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> extension(AddExtension(name));
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extension->id();
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrefService* TestExtensionPrefs::CreateIncognitoPrefService() const {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pref_service_->CreateIncognitoPrefService(
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ExtensionPrefStore(extension_pref_value_map_.get(), true));
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestExtensionPrefs::set_extensions_disabled(bool extensions_disabled) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions_disabled_ = extensions_disabled;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
183