Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2012 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 "chrome/browser/extensions/test_extension_prefs.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/bind_helpers.h"
      9 #include "base/file_util.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "base/message_loop/message_loop.h"
     12 #include "base/message_loop/message_loop_proxy.h"
     13 #include "base/prefs/json_pref_store.h"
     14 #include "base/prefs/pref_value_store.h"
     15 #include "base/run_loop.h"
     16 #include "base/sequenced_task_runner.h"
     17 #include "base/synchronization/waitable_event.h"
     18 #include "base/values.h"
     19 #include "chrome/browser/extensions/extension_pref_store.h"
     20 #include "chrome/browser/extensions/extension_pref_value_map.h"
     21 #include "chrome/browser/extensions/extension_prefs.h"
     22 #include "chrome/browser/prefs/pref_service_mock_builder.h"
     23 #include "chrome/browser/prefs/pref_service_syncable.h"
     24 #include "chrome/common/extensions/extension.h"
     25 #include "chrome/common/extensions/extension_manifest_constants.h"
     26 #include "components/user_prefs/pref_registry_syncable.h"
     27 #include "content/public/browser/browser_thread.h"
     28 #include "sync/api/string_ordinal.h"
     29 #include "testing/gtest/include/gtest/gtest.h"
     30 
     31 using content::BrowserThread;
     32 
     33 namespace extensions {
     34 
     35 namespace {
     36 
     37 // A TimeProvider which returns an incrementally later time each time
     38 // GetCurrentTime is called.
     39 class IncrementalTimeProvider : public ExtensionPrefs::TimeProvider {
     40  public:
     41   IncrementalTimeProvider() : current_time_(base::Time::Now()) {
     42   }
     43 
     44   virtual ~IncrementalTimeProvider() {
     45   }
     46 
     47   virtual base::Time GetCurrentTime() const OVERRIDE {
     48     current_time_ += base::TimeDelta::FromSeconds(10);
     49     return current_time_;
     50   }
     51 
     52  private:
     53   DISALLOW_COPY_AND_ASSIGN(IncrementalTimeProvider);
     54 
     55   mutable base::Time current_time_;
     56 };
     57 
     58 }  // namespace
     59 
     60 TestExtensionPrefs::TestExtensionPrefs(base::SequencedTaskRunner* task_runner)
     61     : task_runner_(task_runner), extensions_disabled_(false) {
     62   EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
     63   preferences_file_ = temp_dir_.path().AppendASCII("Preferences");
     64   extensions_dir_ = temp_dir_.path().AppendASCII("Extensions");
     65   EXPECT_TRUE(file_util::CreateDirectory(extensions_dir_));
     66 
     67   ResetPrefRegistry();
     68   RecreateExtensionPrefs();
     69 }
     70 
     71 TestExtensionPrefs::~TestExtensionPrefs() {
     72 }
     73 
     74 PrefService* TestExtensionPrefs::pref_service() {
     75   return pref_service_.get();
     76 }
     77 
     78 const scoped_refptr<user_prefs::PrefRegistrySyncable>&
     79 TestExtensionPrefs::pref_registry() {
     80   return pref_registry_;
     81 }
     82 
     83 void TestExtensionPrefs::ResetPrefRegistry() {
     84   pref_registry_ = new user_prefs::PrefRegistrySyncable;
     85   ExtensionPrefs::RegisterProfilePrefs(pref_registry_.get());
     86 }
     87 
     88 void TestExtensionPrefs::RecreateExtensionPrefs() {
     89   // We persist and reload the PrefService's PrefStores because this process
     90   // deletes all empty dictionaries. The ExtensionPrefs implementation
     91   // needs to be able to handle this situation.
     92   if (pref_service_) {
     93     // Commit a pending write (which posts a task to task_runner_) and wait for
     94     // it to finish.
     95     pref_service_->CommitPendingWrite();
     96     base::RunLoop run_loop;
     97     ASSERT_TRUE(
     98         task_runner_->PostTaskAndReply(
     99             FROM_HERE,
    100             base::Bind(&base::DoNothing),
    101             run_loop.QuitClosure()));
    102     run_loop.Run();
    103   }
    104 
    105   extension_pref_value_map_.reset(new ExtensionPrefValueMap);
    106   PrefServiceMockBuilder builder;
    107   builder.WithUserFilePrefs(preferences_file_, task_runner_.get());
    108   builder.WithExtensionPrefs(
    109       new ExtensionPrefStore(extension_pref_value_map_.get(), false));
    110   pref_service_.reset(builder.CreateSyncable(pref_registry_.get()));
    111 
    112   prefs_.reset(ExtensionPrefs::Create(
    113       pref_service_.get(),
    114       temp_dir_.path(),
    115       extension_pref_value_map_.get(),
    116       extensions_disabled_,
    117       // Guarantee that no two extensions get the same installation time
    118       // stamp and we can reliably assert the installation order in the tests.
    119       scoped_ptr<ExtensionPrefs::TimeProvider>(
    120           new IncrementalTimeProvider())));
    121 }
    122 
    123 scoped_refptr<Extension> TestExtensionPrefs::AddExtension(std::string name) {
    124   DictionaryValue dictionary;
    125   dictionary.SetString(extension_manifest_keys::kName, name);
    126   dictionary.SetString(extension_manifest_keys::kVersion, "0.1");
    127   return AddExtensionWithManifest(dictionary, Manifest::INTERNAL);
    128 }
    129 
    130 scoped_refptr<Extension> TestExtensionPrefs::AddApp(std::string name) {
    131   DictionaryValue dictionary;
    132   dictionary.SetString(extension_manifest_keys::kName, name);
    133   dictionary.SetString(extension_manifest_keys::kVersion, "0.1");
    134   dictionary.SetString(extension_manifest_keys::kApp, "true");
    135   dictionary.SetString(extension_manifest_keys::kLaunchWebURL,
    136                        "http://example.com");
    137   return AddExtensionWithManifest(dictionary, Manifest::INTERNAL);
    138 
    139 }
    140 
    141 scoped_refptr<Extension> TestExtensionPrefs::AddExtensionWithManifest(
    142     const DictionaryValue& manifest, Manifest::Location location) {
    143   return AddExtensionWithManifestAndFlags(manifest, location,
    144                                           Extension::NO_FLAGS);
    145 }
    146 
    147 scoped_refptr<Extension> TestExtensionPrefs::AddExtensionWithManifestAndFlags(
    148     const DictionaryValue& manifest,
    149     Manifest::Location location,
    150     int extra_flags) {
    151   std::string name;
    152   EXPECT_TRUE(manifest.GetString(extension_manifest_keys::kName, &name));
    153   base::FilePath path =  extensions_dir_.AppendASCII(name);
    154   std::string errors;
    155   scoped_refptr<Extension> extension = Extension::Create(
    156       path, location, manifest, extra_flags, &errors);
    157   EXPECT_TRUE(extension.get()) << errors;
    158   if (!extension.get())
    159     return NULL;
    160 
    161   EXPECT_TRUE(Extension::IdIsValid(extension->id()));
    162   prefs_->OnExtensionInstalled(extension.get(),
    163                                Extension::ENABLED,
    164                                Blacklist::NOT_BLACKLISTED,
    165                                syncer::StringOrdinal::CreateInitialOrdinal());
    166   return extension;
    167 }
    168 
    169 std::string TestExtensionPrefs::AddExtensionAndReturnId(std::string name) {
    170   scoped_refptr<Extension> extension(AddExtension(name));
    171   return extension->id();
    172 }
    173 
    174 PrefService* TestExtensionPrefs::CreateIncognitoPrefService() const {
    175   return pref_service_->CreateIncognitoPrefService(
    176       new ExtensionPrefStore(extension_pref_value_map_.get(), true));
    177 }
    178 
    179 void TestExtensionPrefs::set_extensions_disabled(bool extensions_disabled) {
    180   extensions_disabled_ = extensions_disabled;
    181 }
    182 
    183 }  // namespace extensions
    184