| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/api/declarative_content/content_action.h" | 5 #include "chrome/browser/extensions/api/declarative_content/content_action.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 #include "third_party/skia/include/core/SkBitmap.h" | 29 #include "third_party/skia/include/core/SkBitmap.h" |
| 30 #include "ui/gfx/image/image.h" | 30 #include "ui/gfx/image/image.h" |
| 31 #include "ui/gfx/ipc/skia/gfx_skia_param_traits.h" | 31 #include "ui/gfx/ipc/skia/gfx_skia_param_traits.h" |
| 32 | 32 |
| 33 namespace extensions { | 33 namespace extensions { |
| 34 namespace { | 34 namespace { |
| 35 | 35 |
| 36 using base::test::ParseJson; | 36 using base::test::ParseJson; |
| 37 using testing::HasSubstr; | 37 using testing::HasSubstr; |
| 38 | 38 |
| 39 | 39 std::unique_ptr<base::DictionaryValue> SimpleManifest() { |
| 40 scoped_ptr<base::DictionaryValue> SimpleManifest() { | |
| 41 return DictionaryBuilder() | 40 return DictionaryBuilder() |
| 42 .Set("name", "extension") | 41 .Set("name", "extension") |
| 43 .Set("manifest_version", 2) | 42 .Set("manifest_version", 2) |
| 44 .Set("version", "1.0") | 43 .Set("version", "1.0") |
| 45 .Build(); | 44 .Build(); |
| 46 } | 45 } |
| 47 | 46 |
| 48 class RequestContentScriptTest : public ExtensionServiceTestBase { | 47 class RequestContentScriptTest : public ExtensionServiceTestBase { |
| 49 public: | 48 public: |
| 50 RequestContentScriptTest() | 49 RequestContentScriptTest() |
| (...skipping 13 matching lines...) Expand all Loading... |
| 64 Profile* profile() { return profile_.get(); } | 63 Profile* profile() { return profile_.get(); } |
| 65 Extension* extension() { return extension_.get(); } | 64 Extension* extension() { return extension_.get(); } |
| 66 | 65 |
| 67 private: | 66 private: |
| 68 scoped_refptr<Extension> extension_; | 67 scoped_refptr<Extension> extension_; |
| 69 }; | 68 }; |
| 70 | 69 |
| 71 TEST(DeclarativeContentActionTest, InvalidCreation) { | 70 TEST(DeclarativeContentActionTest, InvalidCreation) { |
| 72 TestExtensionEnvironment env; | 71 TestExtensionEnvironment env; |
| 73 std::string error; | 72 std::string error; |
| 74 scoped_ptr<const ContentAction> result; | 73 std::unique_ptr<const ContentAction> result; |
| 75 | 74 |
| 76 // Test wrong data type passed. | 75 // Test wrong data type passed. |
| 77 error.clear(); | 76 error.clear(); |
| 78 result = ContentAction::Create( | 77 result = ContentAction::Create( |
| 79 NULL, NULL, *ParseJson("[]"), &error); | 78 NULL, NULL, *ParseJson("[]"), &error); |
| 80 EXPECT_EQ("", error); | 79 EXPECT_EQ("", error); |
| 81 EXPECT_FALSE(result.get()); | 80 EXPECT_FALSE(result.get()); |
| 82 | 81 |
| 83 // Test missing instanceType element. | 82 // Test missing instanceType element. |
| 84 error.clear(); | 83 error.clear(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 99 } | 98 } |
| 100 | 99 |
| 101 TEST(DeclarativeContentActionTest, ShowPageActionWithoutPageAction) { | 100 TEST(DeclarativeContentActionTest, ShowPageActionWithoutPageAction) { |
| 102 // Tests legacy behavior. | 101 // Tests legacy behavior. |
| 103 FeatureSwitch::ScopedOverride action_redesign_override( | 102 FeatureSwitch::ScopedOverride action_redesign_override( |
| 104 FeatureSwitch::extension_action_redesign(), false); | 103 FeatureSwitch::extension_action_redesign(), false); |
| 105 TestExtensionEnvironment env; | 104 TestExtensionEnvironment env; |
| 106 | 105 |
| 107 const Extension* extension = env.MakeExtension(base::DictionaryValue()); | 106 const Extension* extension = env.MakeExtension(base::DictionaryValue()); |
| 108 std::string error; | 107 std::string error; |
| 109 scoped_ptr<const ContentAction> result = ContentAction::Create( | 108 std::unique_ptr<const ContentAction> result = ContentAction::Create( |
| 110 NULL, | 109 NULL, extension, |
| 111 extension, | 110 *ParseJson("{\n" |
| 112 *ParseJson( | 111 " \"instanceType\": \"declarativeContent.ShowPageAction\",\n" |
| 113 "{\n" | 112 "}"), |
| 114 " \"instanceType\": \"declarativeContent.ShowPageAction\",\n" | |
| 115 "}"), | |
| 116 &error); | 113 &error); |
| 117 EXPECT_THAT(error, testing::HasSubstr("without a page action")); | 114 EXPECT_THAT(error, testing::HasSubstr("without a page action")); |
| 118 ASSERT_FALSE(result.get()); | 115 ASSERT_FALSE(result.get()); |
| 119 } | 116 } |
| 120 | 117 |
| 121 TEST(DeclarativeContentActionTest, ShowPageAction) { | 118 TEST(DeclarativeContentActionTest, ShowPageAction) { |
| 122 TestExtensionEnvironment env; | 119 TestExtensionEnvironment env; |
| 123 | 120 |
| 124 const Extension* extension = env.MakeExtension( | 121 const Extension* extension = env.MakeExtension( |
| 125 *ParseJson("{\"page_action\": { \"default_title\": \"Extension\" } }")); | 122 *ParseJson("{\"page_action\": { \"default_title\": \"Extension\" } }")); |
| 126 std::string error; | 123 std::string error; |
| 127 scoped_ptr<const ContentAction> result = ContentAction::Create( | 124 std::unique_ptr<const ContentAction> result = ContentAction::Create( |
| 128 NULL, | 125 NULL, extension, |
| 129 extension, | 126 *ParseJson("{\n" |
| 130 *ParseJson( | 127 " \"instanceType\": \"declarativeContent.ShowPageAction\",\n" |
| 131 "{\n" | 128 "}"), |
| 132 " \"instanceType\": \"declarativeContent.ShowPageAction\",\n" | |
| 133 "}"), | |
| 134 &error); | 129 &error); |
| 135 EXPECT_EQ("", error); | 130 EXPECT_EQ("", error); |
| 136 ASSERT_TRUE(result.get()); | 131 ASSERT_TRUE(result.get()); |
| 137 | 132 |
| 138 ExtensionAction* page_action = | 133 ExtensionAction* page_action = |
| 139 ExtensionActionManager::Get(env.profile())->GetPageAction(*extension); | 134 ExtensionActionManager::Get(env.profile())->GetPageAction(*extension); |
| 140 scoped_ptr<content::WebContents> contents = env.MakeTab(); | 135 std::unique_ptr<content::WebContents> contents = env.MakeTab(); |
| 141 const int tab_id = ExtensionTabUtil::GetTabId(contents.get()); | 136 const int tab_id = ExtensionTabUtil::GetTabId(contents.get()); |
| 142 EXPECT_FALSE(page_action->GetIsVisible(tab_id)); | 137 EXPECT_FALSE(page_action->GetIsVisible(tab_id)); |
| 143 ContentAction::ApplyInfo apply_info = { | 138 ContentAction::ApplyInfo apply_info = { |
| 144 extension, env.profile(), contents.get(), 100 | 139 extension, env.profile(), contents.get(), 100 |
| 145 }; | 140 }; |
| 146 result->Apply(apply_info); | 141 result->Apply(apply_info); |
| 147 EXPECT_TRUE(page_action->GetIsVisible(tab_id)); | 142 EXPECT_TRUE(page_action->GetIsVisible(tab_id)); |
| 148 result->Apply(apply_info); | 143 result->Apply(apply_info); |
| 149 EXPECT_TRUE(page_action->GetIsVisible(tab_id)); | 144 EXPECT_TRUE(page_action->GetIsVisible(tab_id)); |
| 150 result->Revert(apply_info); | 145 result->Revert(apply_info); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 163 uint32_t* pixels = bitmap.getAddr32(0, 0); | 158 uint32_t* pixels = bitmap.getAddr32(0, 0); |
| 164 for (int i = 0; i < 19 * 19; ++i) | 159 for (int i = 0; i < 19 * 19; ++i) |
| 165 pixels[i] = i; | 160 pixels[i] = i; |
| 166 IPC::Message bitmap_pickle; | 161 IPC::Message bitmap_pickle; |
| 167 IPC::WriteParam(&bitmap_pickle, bitmap); | 162 IPC::WriteParam(&bitmap_pickle, bitmap); |
| 168 std::string binary_data = std::string( | 163 std::string binary_data = std::string( |
| 169 static_cast<const char*>(bitmap_pickle.data()), bitmap_pickle.size()); | 164 static_cast<const char*>(bitmap_pickle.data()), bitmap_pickle.size()); |
| 170 std::string data64; | 165 std::string data64; |
| 171 base::Base64Encode(binary_data, &data64); | 166 base::Base64Encode(binary_data, &data64); |
| 172 | 167 |
| 173 scoped_ptr<base::DictionaryValue> dict = | 168 std::unique_ptr<base::DictionaryValue> dict = |
| 174 DictionaryBuilder() | 169 DictionaryBuilder() |
| 175 .Set("instanceType", "declarativeContent.SetIcon") | 170 .Set("instanceType", "declarativeContent.SetIcon") |
| 176 .Set("imageData", DictionaryBuilder().Set("19", data64).Build()) | 171 .Set("imageData", DictionaryBuilder().Set("19", data64).Build()) |
| 177 .Build(); | 172 .Build(); |
| 178 | 173 |
| 179 const Extension* extension = env.MakeExtension( | 174 const Extension* extension = env.MakeExtension( |
| 180 *ParseJson("{\"page_action\": { \"default_title\": \"Extension\" } }")); | 175 *ParseJson("{\"page_action\": { \"default_title\": \"Extension\" } }")); |
| 181 std::string error; | 176 std::string error; |
| 182 scoped_ptr<const ContentAction> result = ContentAction::Create( | 177 std::unique_ptr<const ContentAction> result = |
| 183 NULL, | 178 ContentAction::Create(NULL, extension, *dict, &error); |
| 184 extension, | |
| 185 *dict, | |
| 186 &error); | |
| 187 EXPECT_EQ("", error); | 179 EXPECT_EQ("", error); |
| 188 ASSERT_TRUE(result.get()); | 180 ASSERT_TRUE(result.get()); |
| 189 | 181 |
| 190 ExtensionAction* page_action = | 182 ExtensionAction* page_action = |
| 191 ExtensionActionManager::Get(env.profile())->GetPageAction(*extension); | 183 ExtensionActionManager::Get(env.profile())->GetPageAction(*extension); |
| 192 scoped_ptr<content::WebContents> contents = env.MakeTab(); | 184 std::unique_ptr<content::WebContents> contents = env.MakeTab(); |
| 193 const int tab_id = ExtensionTabUtil::GetTabId(contents.get()); | 185 const int tab_id = ExtensionTabUtil::GetTabId(contents.get()); |
| 194 EXPECT_FALSE(page_action->GetIsVisible(tab_id)); | 186 EXPECT_FALSE(page_action->GetIsVisible(tab_id)); |
| 195 ContentAction::ApplyInfo apply_info = { | 187 ContentAction::ApplyInfo apply_info = { |
| 196 extension, env.profile(), contents.get(), 100 | 188 extension, env.profile(), contents.get(), 100 |
| 197 }; | 189 }; |
| 198 | 190 |
| 199 // The declarative icon shouldn't exist unless the content action is applied. | 191 // The declarative icon shouldn't exist unless the content action is applied. |
| 200 EXPECT_TRUE(page_action->GetDeclarativeIcon(tab_id).IsEmpty()); | 192 EXPECT_TRUE(page_action->GetDeclarativeIcon(tab_id).IsEmpty()); |
| 201 result->Apply(apply_info); | 193 result->Apply(apply_info); |
| 202 EXPECT_FALSE(page_action->GetDeclarativeIcon(tab_id).IsEmpty()); | 194 EXPECT_FALSE(page_action->GetDeclarativeIcon(tab_id).IsEmpty()); |
| 203 result->Revert(apply_info); | 195 result->Revert(apply_info); |
| 204 EXPECT_TRUE(page_action->GetDeclarativeIcon(tab_id).IsEmpty()); | 196 EXPECT_TRUE(page_action->GetDeclarativeIcon(tab_id).IsEmpty()); |
| 205 } | 197 } |
| 206 | 198 |
| 207 TEST_F(RequestContentScriptTest, MissingScripts) { | 199 TEST_F(RequestContentScriptTest, MissingScripts) { |
| 208 Init(); | 200 Init(); |
| 209 std::string error; | 201 std::string error; |
| 210 scoped_ptr<const ContentAction> result = ContentAction::Create( | 202 std::unique_ptr<const ContentAction> result = ContentAction::Create( |
| 211 profile(), | 203 profile(), extension(), |
| 212 extension(), | |
| 213 *ParseJson( | 204 *ParseJson( |
| 214 "{\n" | 205 "{\n" |
| 215 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" | 206 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" |
| 216 " \"allFrames\": true,\n" | 207 " \"allFrames\": true,\n" |
| 217 " \"matchAboutBlank\": true\n" | 208 " \"matchAboutBlank\": true\n" |
| 218 "}"), | 209 "}"), |
| 219 &error); | 210 &error); |
| 220 EXPECT_THAT(error, testing::HasSubstr("Missing parameter is required")); | 211 EXPECT_THAT(error, testing::HasSubstr("Missing parameter is required")); |
| 221 ASSERT_FALSE(result.get()); | 212 ASSERT_FALSE(result.get()); |
| 222 } | 213 } |
| 223 | 214 |
| 224 TEST_F(RequestContentScriptTest, CSS) { | 215 TEST_F(RequestContentScriptTest, CSS) { |
| 225 Init(); | 216 Init(); |
| 226 std::string error; | 217 std::string error; |
| 227 scoped_ptr<const ContentAction> result = ContentAction::Create( | 218 std::unique_ptr<const ContentAction> result = ContentAction::Create( |
| 228 profile(), | 219 profile(), extension(), |
| 229 extension(), | |
| 230 *ParseJson( | 220 *ParseJson( |
| 231 "{\n" | 221 "{\n" |
| 232 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" | 222 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" |
| 233 " \"css\": [\"style.css\"]\n" | 223 " \"css\": [\"style.css\"]\n" |
| 234 "}"), | 224 "}"), |
| 235 &error); | 225 &error); |
| 236 EXPECT_EQ("", error); | 226 EXPECT_EQ("", error); |
| 237 ASSERT_TRUE(result.get()); | 227 ASSERT_TRUE(result.get()); |
| 238 } | 228 } |
| 239 | 229 |
| 240 TEST_F(RequestContentScriptTest, JS) { | 230 TEST_F(RequestContentScriptTest, JS) { |
| 241 Init(); | 231 Init(); |
| 242 std::string error; | 232 std::string error; |
| 243 scoped_ptr<const ContentAction> result = ContentAction::Create( | 233 std::unique_ptr<const ContentAction> result = ContentAction::Create( |
| 244 profile(), | 234 profile(), extension(), |
| 245 extension(), | |
| 246 *ParseJson( | 235 *ParseJson( |
| 247 "{\n" | 236 "{\n" |
| 248 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" | 237 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" |
| 249 " \"js\": [\"script.js\"]\n" | 238 " \"js\": [\"script.js\"]\n" |
| 250 "}"), | 239 "}"), |
| 251 &error); | 240 &error); |
| 252 EXPECT_EQ("", error); | 241 EXPECT_EQ("", error); |
| 253 ASSERT_TRUE(result.get()); | 242 ASSERT_TRUE(result.get()); |
| 254 } | 243 } |
| 255 | 244 |
| 256 TEST_F(RequestContentScriptTest, CSSBadType) { | 245 TEST_F(RequestContentScriptTest, CSSBadType) { |
| 257 Init(); | 246 Init(); |
| 258 std::string error; | 247 std::string error; |
| 259 scoped_ptr<const ContentAction> result = ContentAction::Create( | 248 std::unique_ptr<const ContentAction> result = ContentAction::Create( |
| 260 profile(), | 249 profile(), extension(), |
| 261 extension(), | |
| 262 *ParseJson( | 250 *ParseJson( |
| 263 "{\n" | 251 "{\n" |
| 264 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" | 252 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" |
| 265 " \"css\": \"style.css\"\n" | 253 " \"css\": \"style.css\"\n" |
| 266 "}"), | 254 "}"), |
| 267 &error); | 255 &error); |
| 268 ASSERT_FALSE(result.get()); | 256 ASSERT_FALSE(result.get()); |
| 269 } | 257 } |
| 270 | 258 |
| 271 TEST_F(RequestContentScriptTest, JSBadType) { | 259 TEST_F(RequestContentScriptTest, JSBadType) { |
| 272 Init(); | 260 Init(); |
| 273 std::string error; | 261 std::string error; |
| 274 scoped_ptr<const ContentAction> result = ContentAction::Create( | 262 std::unique_ptr<const ContentAction> result = ContentAction::Create( |
| 275 profile(), | 263 profile(), extension(), |
| 276 extension(), | |
| 277 *ParseJson( | 264 *ParseJson( |
| 278 "{\n" | 265 "{\n" |
| 279 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" | 266 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" |
| 280 " \"js\": \"script.js\"\n" | 267 " \"js\": \"script.js\"\n" |
| 281 "}"), | 268 "}"), |
| 282 &error); | 269 &error); |
| 283 ASSERT_FALSE(result.get()); | 270 ASSERT_FALSE(result.get()); |
| 284 } | 271 } |
| 285 | 272 |
| 286 TEST_F(RequestContentScriptTest, AllFrames) { | 273 TEST_F(RequestContentScriptTest, AllFrames) { |
| 287 Init(); | 274 Init(); |
| 288 std::string error; | 275 std::string error; |
| 289 scoped_ptr<const ContentAction> result = ContentAction::Create( | 276 std::unique_ptr<const ContentAction> result = ContentAction::Create( |
| 290 profile(), | 277 profile(), extension(), |
| 291 extension(), | |
| 292 *ParseJson( | 278 *ParseJson( |
| 293 "{\n" | 279 "{\n" |
| 294 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" | 280 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" |
| 295 " \"js\": [\"script.js\"],\n" | 281 " \"js\": [\"script.js\"],\n" |
| 296 " \"allFrames\": true\n" | 282 " \"allFrames\": true\n" |
| 297 "}"), | 283 "}"), |
| 298 &error); | 284 &error); |
| 299 EXPECT_EQ("", error); | 285 EXPECT_EQ("", error); |
| 300 ASSERT_TRUE(result.get()); | 286 ASSERT_TRUE(result.get()); |
| 301 } | 287 } |
| 302 | 288 |
| 303 TEST_F(RequestContentScriptTest, MatchAboutBlank) { | 289 TEST_F(RequestContentScriptTest, MatchAboutBlank) { |
| 304 Init(); | 290 Init(); |
| 305 std::string error; | 291 std::string error; |
| 306 scoped_ptr<const ContentAction> result = ContentAction::Create( | 292 std::unique_ptr<const ContentAction> result = ContentAction::Create( |
| 307 profile(), | 293 profile(), extension(), |
| 308 extension(), | |
| 309 *ParseJson( | 294 *ParseJson( |
| 310 "{\n" | 295 "{\n" |
| 311 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" | 296 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" |
| 312 " \"js\": [\"script.js\"],\n" | 297 " \"js\": [\"script.js\"],\n" |
| 313 " \"matchAboutBlank\": true\n" | 298 " \"matchAboutBlank\": true\n" |
| 314 "}"), | 299 "}"), |
| 315 &error); | 300 &error); |
| 316 EXPECT_EQ("", error); | 301 EXPECT_EQ("", error); |
| 317 ASSERT_TRUE(result.get()); | 302 ASSERT_TRUE(result.get()); |
| 318 } | 303 } |
| 319 | 304 |
| 320 TEST_F(RequestContentScriptTest, AllFramesBadType) { | 305 TEST_F(RequestContentScriptTest, AllFramesBadType) { |
| 321 Init(); | 306 Init(); |
| 322 std::string error; | 307 std::string error; |
| 323 scoped_ptr<const ContentAction> result = ContentAction::Create( | 308 std::unique_ptr<const ContentAction> result = ContentAction::Create( |
| 324 profile(), | 309 profile(), extension(), |
| 325 extension(), | |
| 326 *ParseJson( | 310 *ParseJson( |
| 327 "{\n" | 311 "{\n" |
| 328 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" | 312 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" |
| 329 " \"js\": [\"script.js\"],\n" | 313 " \"js\": [\"script.js\"],\n" |
| 330 " \"allFrames\": null\n" | 314 " \"allFrames\": null\n" |
| 331 "}"), | 315 "}"), |
| 332 &error); | 316 &error); |
| 333 ASSERT_FALSE(result.get()); | 317 ASSERT_FALSE(result.get()); |
| 334 } | 318 } |
| 335 | 319 |
| 336 TEST_F(RequestContentScriptTest, MatchAboutBlankBadType) { | 320 TEST_F(RequestContentScriptTest, MatchAboutBlankBadType) { |
| 337 Init(); | 321 Init(); |
| 338 std::string error; | 322 std::string error; |
| 339 scoped_ptr<const ContentAction> result = ContentAction::Create( | 323 std::unique_ptr<const ContentAction> result = ContentAction::Create( |
| 340 profile(), | 324 profile(), extension(), |
| 341 extension(), | |
| 342 *ParseJson( | 325 *ParseJson( |
| 343 "{\n" | 326 "{\n" |
| 344 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" | 327 " \"instanceType\": \"declarativeContent.RequestContentScript\",\n" |
| 345 " \"js\": [\"script.js\"],\n" | 328 " \"js\": [\"script.js\"],\n" |
| 346 " \"matchAboutBlank\": null\n" | 329 " \"matchAboutBlank\": null\n" |
| 347 "}"), | 330 "}"), |
| 348 &error); | 331 &error); |
| 349 ASSERT_FALSE(result.get()); | 332 ASSERT_FALSE(result.get()); |
| 350 } | 333 } |
| 351 | 334 |
| 352 } // namespace | 335 } // namespace |
| 353 } // namespace extensions | 336 } // namespace extensions |
| OLD | NEW |