Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / component_loader_unittest.cc
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/component_loader.h"
6
7 #include <string>
8
9 #include "base/files/file_util.h"
10 #include "base/path_service.h"
11 #include "base/prefs/pref_registry_simple.h"
12 #include "chrome/browser/extensions/test_extension_service.h"
13 #include "chrome/common/chrome_paths.h"
14 #include "chrome/common/pref_names.h"
15 #include "chrome/test/base/testing_pref_service_syncable.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "components/pref_registry/pref_registry_syncable.h"
18 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "extensions/common/constants.h"
20 #include "extensions/common/extension.h"
21 #include "extensions/common/extension_set.h"
22 #include "extensions/common/manifest_handlers/background_info.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24
25 namespace extensions {
26
27 namespace {
28
29 class MockExtensionService : public TestExtensionService {
30  private:
31   bool ready_;
32   size_t unloaded_count_;
33   ExtensionSet extension_set_;
34
35  public:
36   MockExtensionService() : ready_(false), unloaded_count_(0) {
37   }
38
39   virtual void AddComponentExtension(const Extension* extension) OVERRIDE {
40     EXPECT_FALSE(extension_set_.Contains(extension->id()));
41     // ExtensionService must become the owner of the extension object.
42     extension_set_.Insert(extension);
43   }
44
45   virtual void UnloadExtension(
46       const std::string& extension_id,
47       UnloadedExtensionInfo::Reason reason) OVERRIDE {
48     ASSERT_TRUE(extension_set_.Contains(extension_id));
49     // Remove the extension with the matching id.
50     extension_set_.Remove(extension_id);
51     unloaded_count_++;
52   }
53
54   virtual void RemoveComponentExtension(const std::string & extension_id)
55       OVERRIDE {
56     UnloadExtension(extension_id, UnloadedExtensionInfo::REASON_DISABLE);
57   }
58
59   virtual bool is_ready() OVERRIDE {
60     return ready_;
61   }
62
63   virtual const ExtensionSet* extensions() const OVERRIDE {
64     return &extension_set_;
65   }
66
67   void set_ready(bool ready) {
68     ready_ = ready;
69   }
70
71   size_t unloaded_count() const {
72     return unloaded_count_;
73   }
74
75   void clear_extensions() {
76     extension_set_.Clear();
77   }
78 };
79
80 }  // namespace
81
82 class ComponentLoaderTest : public testing::Test {
83  public:
84   ComponentLoaderTest()
85       // Note: we pass the same pref service here, to stand in for both
86       // user prefs and local state.
87       : component_loader_(&extension_service_,
88                           &prefs_,
89                           &local_state_,
90                           &profile_) {
91   }
92
93   virtual void SetUp() OVERRIDE {
94     extension_path_ =
95         GetBasePath().AppendASCII("good")
96                      .AppendASCII("Extensions")
97                      .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
98                      .AppendASCII("1.0.0.0");
99
100     // Read in the extension manifest.
101     ASSERT_TRUE(base::ReadFileToString(
102         extension_path_.Append(kManifestFilename),
103         &manifest_contents_));
104
105     // Register the local state prefs.
106 #if defined(OS_CHROMEOS)
107     local_state_.registry()->RegisterBooleanPref(
108         prefs::kAccessibilitySpokenFeedbackEnabled, false);
109 #endif
110   }
111
112  protected:
113   MockExtensionService extension_service_;
114   TestingPrefServiceSyncable prefs_;
115   TestingPrefServiceSimple local_state_;
116   TestingProfile profile_;
117   ComponentLoader component_loader_;
118
119   // The root directory of the text extension.
120   base::FilePath extension_path_;
121
122   // The contents of the text extension's manifest file.
123   std::string manifest_contents_;
124
125   content::TestBrowserThreadBundle thread_bundle_;
126
127   base::FilePath GetBasePath() {
128     base::FilePath test_data_dir;
129     PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
130     return test_data_dir.AppendASCII("extensions");
131   }
132 };
133
134 TEST_F(ComponentLoaderTest, ParseManifest) {
135   scoped_ptr<base::DictionaryValue> manifest;
136
137   // Test invalid JSON.
138   manifest.reset(
139       component_loader_.ParseManifest("{ 'test': 3 } invalid"));
140   EXPECT_FALSE(manifest.get());
141
142   // Test manifests that are valid JSON, but don't have an object literal
143   // at the root. ParseManifest() should always return NULL.
144
145   manifest.reset(component_loader_.ParseManifest(std::string()));
146   EXPECT_FALSE(manifest.get());
147
148   manifest.reset(component_loader_.ParseManifest("[{ \"foo\": 3 }]"));
149   EXPECT_FALSE(manifest.get());
150
151   manifest.reset(component_loader_.ParseManifest("\"Test\""));
152   EXPECT_FALSE(manifest.get());
153
154   manifest.reset(component_loader_.ParseManifest("42"));
155   EXPECT_FALSE(manifest.get());
156
157   manifest.reset(component_loader_.ParseManifest("true"));
158   EXPECT_FALSE(manifest.get());
159
160   manifest.reset(component_loader_.ParseManifest("false"));
161   EXPECT_FALSE(manifest.get());
162
163   manifest.reset(component_loader_.ParseManifest("null"));
164   EXPECT_FALSE(manifest.get());
165
166   // Test parsing valid JSON.
167
168   int value = 0;
169   manifest.reset(component_loader_.ParseManifest(
170       "{ \"test\": { \"one\": 1 }, \"two\": 2 }"));
171   ASSERT_TRUE(manifest.get());
172   EXPECT_TRUE(manifest->GetInteger("test.one", &value));
173   EXPECT_EQ(1, value);
174   ASSERT_TRUE(manifest->GetInteger("two", &value));
175   EXPECT_EQ(2, value);
176
177   std::string string_value;
178   manifest.reset(component_loader_.ParseManifest(manifest_contents_));
179   ASSERT_TRUE(manifest->GetString("background.page", &string_value));
180   EXPECT_EQ("backgroundpage.html", string_value);
181 }
182
183 // Test that the extension isn't loaded if the extension service isn't ready.
184 TEST_F(ComponentLoaderTest, AddWhenNotReady) {
185   extension_service_.set_ready(false);
186   std::string extension_id =
187       component_loader_.Add(manifest_contents_, extension_path_);
188   EXPECT_NE("", extension_id);
189   EXPECT_EQ(0u, extension_service_.extensions()->size());
190 }
191
192 // Test that it *is* loaded when the extension service *is* ready.
193 TEST_F(ComponentLoaderTest, AddWhenReady) {
194   extension_service_.set_ready(true);
195   std::string extension_id =
196       component_loader_.Add(manifest_contents_, extension_path_);
197   EXPECT_NE("", extension_id);
198   EXPECT_EQ(1u, extension_service_.extensions()->size());
199   EXPECT_TRUE(extension_service_.extensions()->GetByID(extension_id));
200 }
201
202 TEST_F(ComponentLoaderTest, Remove) {
203   extension_service_.set_ready(false);
204
205   // Removing an extension that was never added should be ok.
206   component_loader_.Remove(extension_path_);
207   EXPECT_EQ(0u, extension_service_.extensions()->size());
208
209   // Try adding and removing before LoadAll() is called.
210   component_loader_.Add(manifest_contents_, extension_path_);
211   component_loader_.Remove(extension_path_);
212   component_loader_.LoadAll();
213   EXPECT_EQ(0u, extension_service_.extensions()->size());
214
215   // Load an extension, and check that it's unloaded when Remove() is called.
216   extension_service_.set_ready(true);
217   std::string extension_id =
218       component_loader_.Add(manifest_contents_, extension_path_);
219   EXPECT_EQ(1u, extension_service_.extensions()->size());
220   component_loader_.Remove(extension_path_);
221   EXPECT_EQ(0u, extension_service_.extensions()->size());
222
223   // And after calling LoadAll(), it shouldn't get loaded.
224   component_loader_.LoadAll();
225   EXPECT_EQ(0u, extension_service_.extensions()->size());
226 }
227
228 TEST_F(ComponentLoaderTest, LoadAll) {
229   extension_service_.set_ready(false);
230
231   // No extensions should be loaded if none were added.
232   component_loader_.LoadAll();
233   EXPECT_EQ(0u, extension_service_.extensions()->size());
234
235   // Use LoadAll() to load the default extensions.
236   component_loader_.AddDefaultComponentExtensions(false);
237   component_loader_.LoadAll();
238   unsigned int default_count = extension_service_.extensions()->size();
239
240   // Clear the list of loaded extensions, and reload with one more.
241   extension_service_.clear_extensions();
242   component_loader_.Add(manifest_contents_, extension_path_);
243   component_loader_.LoadAll();
244
245   EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
246 }
247
248 TEST_F(ComponentLoaderTest, AddOrReplace) {
249   EXPECT_EQ(0u, component_loader_.registered_extensions_count());
250   component_loader_.AddDefaultComponentExtensions(false);
251   size_t const default_count = component_loader_.registered_extensions_count();
252   base::FilePath known_extension = GetBasePath()
253       .AppendASCII("override_component_extension");
254   base::FilePath unknow_extension = extension_path_;
255   base::FilePath invalid_extension = GetBasePath().AppendASCII("bad");
256
257   // Replace a default component extension.
258   component_loader_.AddOrReplace(known_extension);
259   EXPECT_EQ(default_count,
260             component_loader_.registered_extensions_count());
261
262   // Add a new component extension.
263   component_loader_.AddOrReplace(unknow_extension);
264   EXPECT_EQ(default_count + 1,
265             component_loader_.registered_extensions_count());
266
267   extension_service_.set_ready(true);
268   component_loader_.LoadAll();
269
270   EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
271   EXPECT_EQ(0u, extension_service_.unloaded_count());
272
273   // replace loaded component extension.
274   component_loader_.AddOrReplace(known_extension);
275   EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
276   EXPECT_EQ(1u, extension_service_.unloaded_count());
277
278   // Add an invalid component extension.
279   std::string extension_id = component_loader_.AddOrReplace(invalid_extension);
280   EXPECT_TRUE(extension_id.empty());
281 }
282
283 }  // namespace extensions