Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / declarative_content / content_action_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/api/declarative_content/content_action.h"
6
7 #include "base/base64.h"
8 #include "base/run_loop.h"
9 #include "base/test/values_test_util.h"
10 #include "chrome/browser/extensions/extension_action.h"
11 #include "chrome/browser/extensions/extension_action_manager.h"
12 #include "chrome/browser/extensions/extension_service_test_base.h"
13 #include "chrome/browser/extensions/extension_tab_util.h"
14 #include "chrome/browser/extensions/test_extension_environment.h"
15 #include "chrome/browser/extensions/test_extension_system.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "content/public/browser/web_contents.h"
19 #include "extensions/browser/extension_system.h"
20 #include "extensions/common/extension.h"
21 #include "extensions/common/extension_builder.h"
22 #include "extensions/common/value_builder.h"
23 #include "ipc/ipc_message_utils.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "ui/gfx/image/image_skia.h"
27 #include "ui/gfx/ipc/gfx_param_traits.h"
28
29 namespace extensions {
30 namespace {
31
32 using base::test::ParseJson;
33 using testing::HasSubstr;
34
35
36 scoped_ptr<base::DictionaryValue> SimpleManifest() {
37   return DictionaryBuilder()
38       .Set("name", "extension")
39       .Set("manifest_version", 2)
40       .Set("version", "1.0")
41       .Build();
42 }
43
44 class RequestContentScriptTest : public ExtensionServiceTestBase {
45  public:
46   RequestContentScriptTest()
47       : extension_(ExtensionBuilder().SetManifest(SimpleManifest()).Build()) {};
48
49   // TODO(rdevlin.cronin): This should be SetUp(), but an issues with invoking
50   // InitializeEmptyExtensionService() within SetUp() means that we have to
51   // call this manually within every test. This can be cleaned up once said
52   // issue is fixed.
53   virtual void Init() {
54     InitializeEmptyExtensionService();
55     static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile()))->
56         SetReady();
57     base::RunLoop().RunUntilIdle();
58   }
59
60   Profile* profile() { return profile_.get(); }
61   Extension* extension() { return extension_.get(); }
62
63  private:
64   scoped_refptr<Extension> extension_;
65 };
66
67 TEST(DeclarativeContentActionTest, InvalidCreation) {
68   TestExtensionEnvironment env;
69   std::string error;
70   bool bad_message = false;
71   scoped_refptr<const ContentAction> result;
72
73   // Test wrong data type passed.
74   error.clear();
75   result = ContentAction::Create(
76       NULL, NULL, *ParseJson("[]"), &error, &bad_message);
77   EXPECT_TRUE(bad_message);
78   EXPECT_EQ("", error);
79   EXPECT_FALSE(result.get());
80
81   // Test missing instanceType element.
82   error.clear();
83   result = ContentAction::Create(
84       NULL, NULL, *ParseJson("{}"), &error, &bad_message);
85   EXPECT_TRUE(bad_message);
86   EXPECT_EQ("", error);
87   EXPECT_FALSE(result.get());
88
89   // Test wrong instanceType element.
90   error.clear();
91   result = ContentAction::Create(NULL, NULL, *ParseJson(
92       "{\n"
93       "  \"instanceType\": \"declarativeContent.UnknownType\",\n"
94       "}"),
95                                  &error, &bad_message);
96   EXPECT_THAT(error, HasSubstr("invalid instanceType"));
97   EXPECT_FALSE(result.get());
98 }
99
100 TEST(DeclarativeContentActionTest, ShowPageActionWithoutPageAction) {
101   TestExtensionEnvironment env;
102
103   const Extension* extension = env.MakeExtension(base::DictionaryValue());
104   std::string error;
105   bool bad_message = false;
106   scoped_refptr<const ContentAction> result = ContentAction::Create(
107       NULL,
108       extension,
109       *ParseJson(
110            "{\n"
111            "  \"instanceType\": \"declarativeContent.ShowPageAction\",\n"
112            "}"),
113       &error,
114       &bad_message);
115   EXPECT_THAT(error, testing::HasSubstr("without a page action"));
116   EXPECT_FALSE(bad_message);
117   ASSERT_FALSE(result.get());
118 }
119
120 TEST(DeclarativeContentActionTest, ShowPageAction) {
121   TestExtensionEnvironment env;
122
123   const Extension* extension = env.MakeExtension(
124       *ParseJson("{\"page_action\": { \"default_title\": \"Extension\" } }"));
125   std::string error;
126   bool bad_message = false;
127   scoped_refptr<const ContentAction> result = ContentAction::Create(
128       NULL,
129       extension,
130       *ParseJson(
131            "{\n"
132            "  \"instanceType\": \"declarativeContent.ShowPageAction\",\n"
133            "}"),
134       &error,
135       &bad_message);
136   EXPECT_EQ("", error);
137   EXPECT_FALSE(bad_message);
138   ASSERT_TRUE(result.get());
139   EXPECT_EQ(ContentAction::ACTION_SHOW_PAGE_ACTION, result->GetType());
140
141   ExtensionAction* page_action =
142       ExtensionActionManager::Get(env.profile())->GetPageAction(*extension);
143   scoped_ptr<content::WebContents> contents = env.MakeTab();
144   const int tab_id = ExtensionTabUtil::GetTabId(contents.get());
145   EXPECT_FALSE(page_action->GetIsVisible(tab_id));
146   ContentAction::ApplyInfo apply_info = {
147     env.profile(), contents.get()
148   };
149   result->Apply(extension->id(), base::Time(), &apply_info);
150   EXPECT_TRUE(page_action->GetIsVisible(tab_id));
151   result->Apply(extension->id(), base::Time(), &apply_info);
152   EXPECT_TRUE(page_action->GetIsVisible(tab_id));
153   result->Revert(extension->id(), base::Time(), &apply_info);
154   EXPECT_TRUE(page_action->GetIsVisible(tab_id));
155   result->Revert(extension->id(), base::Time(), &apply_info);
156   EXPECT_FALSE(page_action->GetIsVisible(tab_id));
157 }
158
159 TEST(DeclarativeContentActionTest, SetIcon) {
160   TestExtensionEnvironment env;
161
162   // Simulate the process of passing ImageData to SetIcon::Create.
163   SkBitmap bitmap;
164   EXPECT_TRUE(bitmap.tryAllocN32Pixels(19, 19));
165   bitmap.eraseARGB(0,0,0,0);
166   uint32_t* pixels = bitmap.getAddr32(0, 0);
167   for (int i = 0; i < 19 * 19; ++i)
168     pixels[i] = i;
169   IPC::Message bitmap_pickle;
170   IPC::WriteParam(&bitmap_pickle, bitmap);
171   std::string binary_data = std::string(
172       static_cast<const char*>(bitmap_pickle.data()), bitmap_pickle.size());
173   std::string data64;
174   base::Base64Encode(binary_data, &data64);
175
176   scoped_ptr<base::DictionaryValue> dict =
177       DictionaryBuilder().Set("instanceType", "declarativeContent.SetIcon")
178                          .Set("imageData",
179                               DictionaryBuilder().Set("19", data64)).Build();
180
181   const Extension* extension = env.MakeExtension(
182       *ParseJson("{\"page_action\": { \"default_title\": \"Extension\" } }"));
183   std::string error;
184   bool bad_message = false;
185   scoped_refptr<const ContentAction> result = ContentAction::Create(
186       NULL,
187       extension,
188       *dict,
189       &error,
190       &bad_message);
191   EXPECT_EQ("", error);
192   EXPECT_FALSE(bad_message);
193   ASSERT_TRUE(result.get());
194   EXPECT_EQ(ContentAction::ACTION_SET_ICON, result->GetType());
195
196   ExtensionAction* page_action =
197       ExtensionActionManager::Get(env.profile())->GetPageAction(*extension);
198   scoped_ptr<content::WebContents> contents = env.MakeTab();
199   const int tab_id = ExtensionTabUtil::GetTabId(contents.get());
200   EXPECT_FALSE(page_action->GetIsVisible(tab_id));
201   ContentAction::ApplyInfo apply_info = {
202     env.profile(), contents.get()
203   };
204
205   // The declarative icon shouldn't exist unless the content action is applied.
206   EXPECT_TRUE(page_action->GetDeclarativeIcon(tab_id).bitmap()->empty());
207   result->Apply(extension->id(), base::Time(), &apply_info);
208   EXPECT_FALSE(page_action->GetDeclarativeIcon(tab_id).bitmap()->empty());
209   result->Revert(extension->id(), base::Time(), &apply_info);
210   EXPECT_TRUE(page_action->GetDeclarativeIcon(tab_id).bitmap()->empty());
211 }
212
213 TEST_F(RequestContentScriptTest, MissingScripts) {
214   Init();
215   std::string error;
216   bool bad_message = false;
217   scoped_refptr<const ContentAction> result = ContentAction::Create(
218       profile(),
219       extension(),
220       *ParseJson(
221           "{\n"
222           "  \"instanceType\": \"declarativeContent.RequestContentScript\",\n"
223           "  \"allFrames\": true,\n"
224           "  \"matchAboutBlank\": true\n"
225           "}"),
226       &error,
227       &bad_message);
228   EXPECT_THAT(error, testing::HasSubstr("Missing parameter is required"));
229   EXPECT_FALSE(bad_message);
230   ASSERT_FALSE(result.get());
231 }
232
233 TEST_F(RequestContentScriptTest, CSS) {
234   Init();
235   std::string error;
236   bool bad_message = false;
237   scoped_refptr<const ContentAction> result = ContentAction::Create(
238       profile(),
239       extension(),
240       *ParseJson(
241           "{\n"
242           "  \"instanceType\": \"declarativeContent.RequestContentScript\",\n"
243           "  \"css\": [\"style.css\"]\n"
244           "}"),
245       &error,
246       &bad_message);
247   EXPECT_EQ("", error);
248   EXPECT_FALSE(bad_message);
249   ASSERT_TRUE(result.get());
250   EXPECT_EQ(ContentAction::ACTION_REQUEST_CONTENT_SCRIPT, result->GetType());
251 }
252
253 TEST_F(RequestContentScriptTest, JS) {
254   Init();
255   std::string error;
256   bool bad_message = false;
257   scoped_refptr<const ContentAction> result = ContentAction::Create(
258       profile(),
259       extension(),
260       *ParseJson(
261           "{\n"
262           "  \"instanceType\": \"declarativeContent.RequestContentScript\",\n"
263           "  \"js\": [\"script.js\"]\n"
264           "}"),
265       &error,
266       &bad_message);
267   EXPECT_EQ("", error);
268   EXPECT_FALSE(bad_message);
269   ASSERT_TRUE(result.get());
270   EXPECT_EQ(ContentAction::ACTION_REQUEST_CONTENT_SCRIPT, result->GetType());
271 }
272
273 TEST_F(RequestContentScriptTest, CSSBadType) {
274   Init();
275   std::string error;
276   bool bad_message = false;
277   scoped_refptr<const ContentAction> result = ContentAction::Create(
278       profile(),
279       extension(),
280       *ParseJson(
281           "{\n"
282           "  \"instanceType\": \"declarativeContent.RequestContentScript\",\n"
283           "  \"css\": \"style.css\"\n"
284           "}"),
285       &error,
286       &bad_message);
287   EXPECT_TRUE(bad_message);
288   ASSERT_FALSE(result.get());
289 }
290
291 TEST_F(RequestContentScriptTest, JSBadType) {
292   Init();
293   std::string error;
294   bool bad_message = false;
295   scoped_refptr<const ContentAction> result = ContentAction::Create(
296       profile(),
297       extension(),
298       *ParseJson(
299           "{\n"
300           "  \"instanceType\": \"declarativeContent.RequestContentScript\",\n"
301           "  \"js\": \"script.js\"\n"
302           "}"),
303       &error,
304       &bad_message);
305   EXPECT_TRUE(bad_message);
306   ASSERT_FALSE(result.get());
307 }
308
309 TEST_F(RequestContentScriptTest, AllFrames) {
310   Init();
311   std::string error;
312   bool bad_message = false;
313   scoped_refptr<const ContentAction> result = ContentAction::Create(
314       profile(),
315       extension(),
316       *ParseJson(
317           "{\n"
318           "  \"instanceType\": \"declarativeContent.RequestContentScript\",\n"
319           "  \"js\": [\"script.js\"],\n"
320           "  \"allFrames\": true\n"
321           "}"),
322       &error,
323       &bad_message);
324   EXPECT_EQ("", error);
325   EXPECT_FALSE(bad_message);
326   ASSERT_TRUE(result.get());
327   EXPECT_EQ(ContentAction::ACTION_REQUEST_CONTENT_SCRIPT, result->GetType());
328 }
329
330 TEST_F(RequestContentScriptTest, MatchAboutBlank) {
331   Init();
332   std::string error;
333   bool bad_message = false;
334   scoped_refptr<const ContentAction> result = ContentAction::Create(
335       profile(),
336       extension(),
337       *ParseJson(
338           "{\n"
339           "  \"instanceType\": \"declarativeContent.RequestContentScript\",\n"
340           "  \"js\": [\"script.js\"],\n"
341           "  \"matchAboutBlank\": true\n"
342           "}"),
343       &error,
344       &bad_message);
345   EXPECT_EQ("", error);
346   EXPECT_FALSE(bad_message);
347   ASSERT_TRUE(result.get());
348   EXPECT_EQ(ContentAction::ACTION_REQUEST_CONTENT_SCRIPT, result->GetType());
349 }
350
351 TEST_F(RequestContentScriptTest, AllFramesBadType) {
352   Init();
353   std::string error;
354   bool bad_message = false;
355   scoped_refptr<const ContentAction> result = ContentAction::Create(
356       profile(),
357       extension(),
358       *ParseJson(
359           "{\n"
360           "  \"instanceType\": \"declarativeContent.RequestContentScript\",\n"
361           "  \"js\": [\"script.js\"],\n"
362           "  \"allFrames\": null\n"
363           "}"),
364       &error,
365       &bad_message);
366   EXPECT_TRUE(bad_message);
367   ASSERT_FALSE(result.get());
368 }
369
370 TEST_F(RequestContentScriptTest, MatchAboutBlankBadType) {
371   Init();
372   std::string error;
373   bool bad_message = false;
374   scoped_refptr<const ContentAction> result = ContentAction::Create(
375       profile(),
376       extension(),
377       *ParseJson(
378           "{\n"
379           "  \"instanceType\": \"declarativeContent.RequestContentScript\",\n"
380           "  \"js\": [\"script.js\"],\n"
381           "  \"matchAboutBlank\": null\n"
382           "}"),
383       &error,
384       &bad_message);
385   EXPECT_TRUE(bad_message);
386   ASSERT_FALSE(result.get());
387 }
388
389 }  // namespace
390 }  // namespace extensions