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/component_loader.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string>
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/test_extension_service.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/background_info.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_set.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/base/testing_pref_service_syncable.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/user_prefs/pref_registry_syncable.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/constants.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockExtensionService : public TestExtensionService {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ready_;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t unloaded_count_;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionSet extension_set_;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockExtensionService() : ready_(false), unloaded_count_(0) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddComponentExtension(const Extension* extension) OVERRIDE {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(extension_set_.Contains(extension->id()));
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ExtensionService must become the owner of the extension object.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_set_.Insert(extension);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void UnloadExtension(
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& extension_id,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension_misc::UnloadedExtensionReason reason) OVERRIDE {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(extension_set_.Contains(extension_id));
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Remove the extension with the matching id.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_set_.Remove(extension_id);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unloaded_count_++;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool is_ready() OVERRIDE {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ready_;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual const ExtensionSet* extensions() const OVERRIDE {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &extension_set_;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_ready(bool ready) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ready_ = ready;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t unloaded_count() const {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return unloaded_count_;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void clear_extensions() {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_set_.Clear();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ComponentLoaderTest : public testing::Test {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ComponentLoaderTest()
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Note: we pass the same pref service here, to stand in for both
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // user prefs and local state.
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : component_loader_(&extension_service_, &prefs_, &local_state_) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_path_ =
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetBasePath().AppendASCII("good")
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     .AppendASCII("Extensions")
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     .AppendASCII("1.0.0.0");
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Read in the extension manifest.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(file_util::ReadFileToString(
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        extension_path_.Append(kManifestFilename),
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &manifest_contents_));
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Register the local state prefs.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    local_state_.registry()->RegisterBooleanPref(
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        prefs::kSpokenFeedbackEnabled, false);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockExtensionService extension_service_;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestingPrefServiceSyncable prefs_;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestingPrefServiceSimple local_state_;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ComponentLoader component_loader_;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The root directory of the text extension.
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath extension_path_;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The contents of the text extension's manifest file.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string manifest_contents_;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath GetBasePath() {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath test_data_dir;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return test_data_dir.AppendASCII("extensions");
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ComponentLoaderTest, ParseManifest) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> manifest;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test invalid JSON.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manifest.reset(
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      component_loader_.ParseManifest("{ 'test': 3 } invalid"));
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(manifest.get());
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test manifests that are valid JSON, but don't have an object literal
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // at the root. ParseManifest() should always return NULL.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  manifest.reset(component_loader_.ParseManifest(std::string()));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(manifest.get());
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manifest.reset(component_loader_.ParseManifest("[{ \"foo\": 3 }]"));
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(manifest.get());
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manifest.reset(component_loader_.ParseManifest("\"Test\""));
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(manifest.get());
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manifest.reset(component_loader_.ParseManifest("42"));
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(manifest.get());
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manifest.reset(component_loader_.ParseManifest("true"));
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(manifest.get());
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manifest.reset(component_loader_.ParseManifest("false"));
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(manifest.get());
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manifest.reset(component_loader_.ParseManifest("null"));
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(manifest.get());
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test parsing valid JSON.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int value = 0;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manifest.reset(component_loader_.ParseManifest(
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "{ \"test\": { \"one\": 1 }, \"two\": 2 }"));
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(manifest.get());
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(manifest->GetInteger("test.one", &value));
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, value);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(manifest->GetInteger("two", &value));
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, value);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string string_value;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manifest.reset(component_loader_.ParseManifest(manifest_contents_));
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(manifest->GetString("background.page", &string_value));
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("backgroundpage.html", string_value);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that the extension isn't loaded if the extension service isn't ready.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ComponentLoaderTest, AddWhenNotReady) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_service_.set_ready(false);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string extension_id =
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      component_loader_.Add(manifest_contents_, extension_path_);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE("", extension_id);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, extension_service_.extensions()->size());
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that it *is* loaded when the extension service *is* ready.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ComponentLoaderTest, AddWhenReady) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_service_.set_ready(true);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string extension_id =
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      component_loader_.Add(manifest_contents_, extension_path_);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE("", extension_id);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, extension_service_.extensions()->size());
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(extension_service_.extensions()->GetByID(extension_id));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ComponentLoaderTest, Remove) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_service_.set_ready(false);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Removing an extension that was never added should be ok.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  component_loader_.Remove(extension_path_);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, extension_service_.extensions()->size());
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try adding and removing before LoadAll() is called.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  component_loader_.Add(manifest_contents_, extension_path_);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  component_loader_.Remove(extension_path_);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  component_loader_.LoadAll();
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, extension_service_.extensions()->size());
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load an extension, and check that it's unloaded when Remove() is called.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_service_.set_ready(true);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string extension_id =
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      component_loader_.Add(manifest_contents_, extension_path_);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, extension_service_.extensions()->size());
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  component_loader_.Remove(extension_path_);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, extension_service_.extensions()->size());
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And after calling LoadAll(), it shouldn't get loaded.
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  component_loader_.LoadAll();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, extension_service_.extensions()->size());
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ComponentLoaderTest, LoadAll) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_service_.set_ready(false);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No extensions should be loaded if none were added.
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  component_loader_.LoadAll();
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, extension_service_.extensions()->size());
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use LoadAll() to load the default extensions.
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  component_loader_.AddDefaultComponentExtensions(false);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  component_loader_.LoadAll();
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int default_count = extension_service_.extensions()->size();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear the list of loaded extensions, and reload with one more.
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_service_.clear_extensions();
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  component_loader_.Add(manifest_contents_, extension_path_);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  component_loader_.LoadAll();
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ComponentLoaderTest, RemoveAll) {
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extension_service_.set_ready(true);
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0u, extension_service_.extensions()->size());
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add all the default extensions. Since the extension service is ready, they
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // will be loaded immediately.
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  component_loader_.AddDefaultComponentExtensions(false);
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned int default_count = extension_service_.extensions()->size();
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // And add one more just to make sure there is anything in there in case
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // there are no defaults for this platform.
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  component_loader_.Add(manifest_contents_, extension_path_);
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remove all default extensions.
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  component_loader_.RemoveAll();
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0u, extension_service_.extensions()->size());
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ComponentLoaderTest, AddOrReplace) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, component_loader_.registered_extensions_count());
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  component_loader_.AddDefaultComponentExtensions(false);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t const default_count = component_loader_.registered_extensions_count();
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath known_extension = GetBasePath()
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .AppendASCII("override_component_extension");
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath unknow_extension = extension_path_;
26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::FilePath invalid_extension = GetBasePath().AppendASCII("bad");
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Replace a default component extension.
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  component_loader_.AddOrReplace(known_extension);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(default_count,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            component_loader_.registered_extensions_count());
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a new component extension.
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  component_loader_.AddOrReplace(unknow_extension);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(default_count + 1,
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            component_loader_.registered_extensions_count());
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_service_.set_ready(true);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  component_loader_.LoadAll();
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, extension_service_.unloaded_count());
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // replace loaded component extension.
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  component_loader_.AddOrReplace(known_extension);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, extension_service_.unloaded_count());
28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Add an invalid component extension.
28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string extension_id = component_loader_.AddOrReplace(invalid_extension);
28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(extension_id.empty());
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
289