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