Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc

Issue 14358004: Almost all actions in Declarative Web Request require all_urls host permissions (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: All URLs -> all hosts; also rebased Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_webrequest/webrequest_action .h" 5 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_action .h"
6 6
7 #include "base/files/file_path.h"
8 #include "base/json/json_file_value_serializer.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
7 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/path_service.h"
13 #include "base/test/values_test_util.h"
14 #include "base/time.h"
8 #include "base/values.h" 15 #include "base/values.h"
16 #include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
9 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condit ion.h" 17 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condit ion.h"
10 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_consta nts.h" 18 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_consta nts.h"
11 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" 19 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
20 #include "chrome/browser/extensions/extension_info_map.h"
21 #include "chrome/common/chrome_paths.h"
22 #include "chrome/common/extensions/extension.h"
12 #include "chrome/common/extensions/extension_constants.h" 23 #include "chrome/common/extensions/extension_constants.h"
24 #include "chrome/common/extensions/extension_test_util.h"
25 #include "content/public/test/test_browser_thread.h"
26 #include "net/http/http_response_headers.h"
13 #include "net/url_request/url_request_test_util.h" 27 #include "net/url_request/url_request_test_util.h"
28 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h" 29 #include "testing/gtest/include/gtest/gtest.h"
15 30
16 namespace { 31 using base::DictionaryValue;
17 const char kUnknownActionType[] = "unknownType"; 32 using base::ListValue;
18 } // namespace 33 using extension_test_util::LoadManifestUnchecked;
34 using testing::HasSubstr;
19 35
20 namespace extensions { 36 namespace extensions {
21 37
38 namespace {
39
40 const char kUnknownActionType[] = "unknownType";
41
42 scoped_ptr<WebRequestActionSet> CreateSetOfActions(const char* json) {
43 scoped_ptr<Value> parsed_value(base::test::ParseJson(json));
44 const ListValue* parsed_list;
45 CHECK(parsed_value->GetAsList(&parsed_list));
46
47 WebRequestActionSet::AnyVector actions;
48 for (ListValue::const_iterator it = parsed_list->begin();
49 it != parsed_list->end();
50 ++it) {
51 const DictionaryValue* dict;
52 CHECK((*it)->GetAsDictionary(&dict));
53 actions.push_back(linked_ptr<base::Value>(dict->DeepCopy()));
54 }
55
56 std::string error;
57 bool bad_message = false;
58
59 scoped_ptr<WebRequestActionSet> action_set(
60 WebRequestActionSet::Create(actions, &error, &bad_message));
61 EXPECT_EQ("", error);
62 EXPECT_FALSE(bad_message);
63 CHECK(action_set);
64 return action_set.Pass();
65 }
66
67 } // namespace
68
22 namespace keys = declarative_webrequest_constants; 69 namespace keys = declarative_webrequest_constants;
23 70
71 class WebRequestActionWithThreadsTest : public testing::Test {
72 public:
73 WebRequestActionWithThreadsTest()
74 : io_thread_(content::BrowserThread::IO, &message_loop_) {}
75
76 protected:
77 virtual void SetUp() OVERRIDE;
78
79 // Creates a URL request for URL |url_string|, and applies the actions from
80 // |action_set| as if they were triggered by the extension with
81 // |extension_id| during |stage|.
82 bool ActionWorksOnRequest(const char* url_string,
83 const std::string& extension_id,
84 const WebRequestActionSet* action_set,
85 RequestStage stage);
86
87 // Expects a JSON description of an |action| requiring <all_urls> host
88 // permission, and checks that only an extensions with full host permissions
89 // can execute that action at |stage|. Also checks that the action is not
90 // executable for http://clients1.google.com.
91 void CheckActionNeedsAllUrls(const char* action, RequestStage stage);
92
93 net::TestURLRequestContext context_;
94
95 // An extension with *.com host permissions and the DWR permission.
96 scoped_refptr<Extension> extension_;
97 // An extension with host permissions for all URLs and the DWR permission.
98 scoped_refptr<Extension> extension_all_urls_;
99 scoped_refptr<ExtensionInfoMap> extension_info_map_;
100
101 private:
102 MessageLoopForIO message_loop_;
103 content::TestBrowserThread io_thread_;
104 };
105
106 void WebRequestActionWithThreadsTest::SetUp() {
107 testing::Test::SetUp();
108
109 std::string error;
110 extension_ = LoadManifestUnchecked("permissions",
111 "web_request_com_host_permissions.json",
112 Manifest::INVALID_LOCATION,
113 Extension::NO_FLAGS,
114 "ext_id_1",
115 &error);
116 ASSERT_TRUE(extension_) << error;
117 extension_all_urls_ =
118 LoadManifestUnchecked("permissions",
119 "web_request_all_host_permissions.json",
120 Manifest::INVALID_LOCATION,
121 Extension::NO_FLAGS,
122 "ext_id_2",
123 &error);
124 ASSERT_TRUE(extension_all_urls_) << error;
125 extension_info_map_ = new ExtensionInfoMap;
126 ASSERT_TRUE(extension_info_map_);
127 extension_info_map_->AddExtension(
128 extension_.get(), base::Time::Now(), false /*incognito_enabled*/);
129 extension_info_map_->AddExtension(extension_all_urls_.get(),
130 base::Time::Now(),
131 false /*incognito_enabled*/);
132 }
133
134 bool WebRequestActionWithThreadsTest::ActionWorksOnRequest(
135 const char* url_string,
136 const std::string& extension_id,
137 const WebRequestActionSet* action_set,
138 RequestStage stage) {
139 net::TestURLRequest regular_request(GURL(url_string), NULL, &context_, NULL);
140 std::list<LinkedPtrEventResponseDelta> deltas;
141 scoped_refptr<net::HttpResponseHeaders> headers(
142 new net::HttpResponseHeaders(""));
143 WebRequestData request_data(&regular_request, stage, headers);
144 std::set<std::string> ignored_tags;
145 WebRequestAction::ApplyInfo apply_info = {
146 extension_info_map_, request_data, false /*crosses_incognito*/, &deltas,
147 &ignored_tags
148 };
149 action_set->Apply(extension_id, base::Time(), &apply_info);
150 return (1u == deltas.size() || 0u < ignored_tags.size());
151 }
152
153 void WebRequestActionWithThreadsTest::CheckActionNeedsAllUrls(
154 const char* action,
155 RequestStage stage) {
156 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(action));
157
158 // Although |extension_| has matching *.com host permission, |action|
159 // is intentionally forbidden -- in Declarative WR, host permission
160 // for less than all URLs are ignored (except in SendMessageToExtension).
161 EXPECT_FALSE(ActionWorksOnRequest(
162 "http://test.com", extension_->id(), action_set.get(), stage));
163 // With the "<all_urls>" host permission they are allowed.
164 EXPECT_TRUE(ActionWorksOnRequest(
165 "http://test.com", extension_all_urls_->id(), action_set.get(), stage));
166
167 // The protected URLs should not be touched at all.
168 EXPECT_FALSE(ActionWorksOnRequest(
169 "http://clients1.google.com", extension_->id(), action_set.get(), stage));
170 EXPECT_FALSE(ActionWorksOnRequest("http://clients1.google.com",
171 extension_all_urls_->id(),
172 action_set.get(),
173 stage));
174 }
175
24 TEST(WebRequestActionTest, CreateAction) { 176 TEST(WebRequestActionTest, CreateAction) {
25 std::string error; 177 std::string error;
26 bool bad_message = false; 178 bool bad_message = false;
27 scoped_ptr<WebRequestAction> result; 179 scoped_ptr<WebRequestAction> result;
28 180
29 // Test wrong data type passed. 181 // Test wrong data type passed.
30 error.clear(); 182 error.clear();
31 base::ListValue empty_list; 183 base::ListValue empty_list;
32 result = WebRequestAction::Create(empty_list, &error, &bad_message); 184 result = WebRequestAction::Create(empty_list, &error, &bad_message);
33 EXPECT_TRUE(bad_message); 185 EXPECT_TRUE(bad_message);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 EXPECT_EQ("foo$1bar", CallPerlToRe2Style("foo\\$1bar")); 260 EXPECT_EQ("foo$1bar", CallPerlToRe2Style("foo\\$1bar"));
109 // foo\\$1bar -> foo\\\1bar 261 // foo\\$1bar -> foo\\\1bar
110 EXPECT_EQ("foo\\\\\\1bar", CallPerlToRe2Style("foo\\\\$1bar")); 262 EXPECT_EQ("foo\\\\\\1bar", CallPerlToRe2Style("foo\\\\$1bar"));
111 // foo\bar -> foobar 263 // foo\bar -> foobar
112 EXPECT_EQ("foobar", CallPerlToRe2Style("foo\\bar")); 264 EXPECT_EQ("foobar", CallPerlToRe2Style("foo\\bar"));
113 // foo$bar -> foo$bar 265 // foo$bar -> foo$bar
114 EXPECT_EQ("foo$bar", CallPerlToRe2Style("foo$bar")); 266 EXPECT_EQ("foo$bar", CallPerlToRe2Style("foo$bar"));
115 #undef CallPerlToRe2Style 267 #undef CallPerlToRe2Style
116 } 268 }
117 269
118 TEST(WebRequestActionTest, TestPermissions) { 270 TEST_F(WebRequestActionWithThreadsTest, PermissionsToRedirect) {
119 // Necessary for TestURLRequest. 271 const char kAction[] =
120 MessageLoop message_loop(MessageLoop::TYPE_IO); 272 "[{"
121 net::TestURLRequestContext context; 273 " \"instanceType\": \"declarativeWebRequest.RedirectRequest\","
122 274 " \"redirectUrl\": \"http://www.foobar.com\""
123 std::string error; 275 "}]";
124 bool bad_message = false; 276 CheckActionNeedsAllUrls(kAction, ON_BEFORE_REQUEST);
125 scoped_ptr<WebRequestActionSet> action_set; 277 }
126 278
127 // Setup redirect to http://www.foobar.com. 279 TEST_F(WebRequestActionWithThreadsTest, PermissionsToRedirectByRegEx) {
128 base::DictionaryValue redirect; 280 const char kAction[] =
129 redirect.SetString(keys::kInstanceTypeKey, keys::kRedirectRequestType); 281 "[{"
130 redirect.SetString(keys::kRedirectUrlKey, "http://www.foobar.com"); 282 " \"instanceType\": \"declarativeWebRequest.RedirectByRegEx\","
131 283 " \"from\": \".*\","
132 WebRequestActionSet::AnyVector actions; 284 " \"to\": \"http://www.foobar.com\""
133 actions.push_back(linked_ptr<base::Value>(redirect.DeepCopy())); 285 "}]";
134 286 CheckActionNeedsAllUrls(kAction, ON_BEFORE_REQUEST);
135 action_set = WebRequestActionSet::Create(actions, &error, &bad_message); 287 }
136 EXPECT_EQ("", error); 288
137 EXPECT_FALSE(bad_message); 289 TEST_F(WebRequestActionWithThreadsTest, PermissionsToSetRequestHeader) {
138 290 const char kAction[] =
139 // Check that redirect works on regular URLs but not on protected URLs. 291 "[{"
140 net::TestURLRequest regular_request( 292 " \"instanceType\": \"declarativeWebRequest.SetRequestHeader\","
141 GURL("http://test.com"), NULL, &context, NULL); 293 " \"name\": \"testname\","
142 std::list<LinkedPtrEventResponseDelta> deltas; 294 " \"value\": \"testvalue\""
143 WebRequestData request_data(&regular_request, ON_BEFORE_REQUEST); 295 "}]";
144 WebRequestAction::ApplyInfo apply_info = { 296 CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
145 NULL, request_data, false, &deltas 297 }
146 }; 298
147 action_set->Apply("ext1", base::Time(), &apply_info); 299 TEST_F(WebRequestActionWithThreadsTest, PermissionsToRemoveRequestHeader) {
148 EXPECT_EQ(1u, deltas.size()); 300 const char kAction[] =
149 301 "[{"
150 net::TestURLRequest protected_request(GURL("http://clients1.google.com"), 302 " \"instanceType\": \"declarativeWebRequest.RemoveRequestHeader\","
151 NULL, &context, NULL); 303 " \"name\": \"testname\""
152 deltas.clear(); 304 "}]";
153 request_data = WebRequestData(&protected_request, ON_BEFORE_REQUEST); 305 CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
154 // Note that we just updated the request_data reference in apply_info. 306 }
155 action_set->Apply("ext1", base::Time(), &apply_info); 307
156 EXPECT_EQ(0u, deltas.size()); 308 TEST_F(WebRequestActionWithThreadsTest, PermissionsToAddResponseHeader) {
309 const char kAction[] =
310 "[{"
311 " \"instanceType\": \"declarativeWebRequest.AddResponseHeader\","
312 " \"name\": \"testname\","
313 " \"value\": \"testvalue\""
314 "}]";
315 CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
316 }
317
318 TEST_F(WebRequestActionWithThreadsTest, PermissionsToRemoveResponseHeader) {
319 const char kAction[] =
320 "[{"
321 " \"instanceType\": \"declarativeWebRequest.RemoveResponseHeader\","
322 " \"name\": \"testname\""
323 "}]";
324 CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
325 }
326
327 TEST_F(WebRequestActionWithThreadsTest, PermissionsToSendMessageToExtension) {
328 const char kAction[] =
329 "[{"
330 " \"instanceType\": \"declarativeWebRequest.SendMessageToExtension\","
331 " \"message\": \"testtext\""
332 "}]";
333 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));
334
335 // For sending messages, specific host permissions actually matter.
336 EXPECT_TRUE(ActionWorksOnRequest("http://test.com",
337 extension_->id(),
338 action_set.get(),
339 ON_BEFORE_REQUEST));
340 // With the "<all_urls>" host permission they are allowed.
341 EXPECT_TRUE(ActionWorksOnRequest("http://test.com",
342 extension_all_urls_->id(),
343 action_set.get(),
344 ON_BEFORE_REQUEST));
345
346 // The protected URLs should not be touched at all.
347 EXPECT_FALSE(ActionWorksOnRequest("http://clients1.google.com",
348 extension_->id(),
349 action_set.get(),
350 ON_BEFORE_REQUEST));
351 EXPECT_FALSE(ActionWorksOnRequest("http://clients1.google.com",
352 extension_all_urls_->id(),
353 action_set.get(),
354 ON_BEFORE_REQUEST));
355 }
356
357 TEST_F(WebRequestActionWithThreadsTest, PermissionsToAddRequestCookie) {
358 const char kAction[] =
359 "[{"
360 " \"instanceType\": \"declarativeWebRequest.AddRequestCookie\","
361 " \"cookie\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
362 "}]";
363 CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
364 }
365
366 TEST_F(WebRequestActionWithThreadsTest, PermissionsToAddResponseCookie) {
367 const char kAction[] =
368 "[{"
369 " \"instanceType\": \"declarativeWebRequest.AddResponseCookie\","
370 " \"cookie\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
371 "}]";
372 CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
373 }
374
375 TEST_F(WebRequestActionWithThreadsTest, PermissionsToEditRequestCookie) {
376 const char kAction[] =
377 "[{"
378 " \"instanceType\": \"declarativeWebRequest.EditRequestCookie\","
379 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" },"
380 " \"modification\": { \"name\": \"name2\", \"value\": \"value2\" }"
381 "}]";
382 CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
383 }
384
385 TEST_F(WebRequestActionWithThreadsTest, PermissionsToEditResponseCookie) {
386 const char kAction[] =
387 "[{"
388 " \"instanceType\": \"declarativeWebRequest.EditResponseCookie\","
389 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" },"
390 " \"modification\": { \"name\": \"name2\", \"value\": \"value2\" }"
391 "}]";
392 CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
393 }
394
395 TEST_F(WebRequestActionWithThreadsTest, PermissionsToRemoveRequestCookie) {
396 const char kAction[] =
397 "[{"
398 " \"instanceType\": \"declarativeWebRequest.RemoveRequestCookie\","
399 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
400 "}]";
401 CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
402 }
403
404 TEST_F(WebRequestActionWithThreadsTest, PermissionsToRemoveResponseCookie) {
405 const char kAction[] =
406 "[{"
407 " \"instanceType\": \"declarativeWebRequest.RemoveResponseCookie\","
408 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
409 "}]";
410 CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
411 }
412
413 TEST_F(WebRequestActionWithThreadsTest, PermissionsToCancel) {
414 const char kAction[] =
415 "[{"
416 " \"instanceType\": \"declarativeWebRequest.CancelRequest\""
417 "}]";
418 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));
419
420 // Cancelling requests works without full host permissions.
421 EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
422 extension_->id(),
423 action_set.get(),
424 ON_BEFORE_REQUEST));
425 }
426
427 TEST_F(WebRequestActionWithThreadsTest,
428 PermissionsToRedirectToTransparentImage) {
429 const char kAction[] =
430 "[{"
431 " \"instanceType\": \"declarativeWebRequest.RedirectToTransparentImage\""
432 "}]";
433 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));
434
435 // Redirecting to transparent images works without full host permissions.
436 EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
437 extension_->id(),
438 action_set.get(),
439 ON_BEFORE_REQUEST));
440 }
441
442 TEST_F(WebRequestActionWithThreadsTest, PermissionsToRedirectToEmptyDocument) {
443 const char kAction[] =
444 "[{"
445 " \"instanceType\": \"declarativeWebRequest.RedirectToEmptyDocument\""
446 "}]";
447 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));
448
449 // Redirecting to the empty document works without full host permissions.
450 EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
451 extension_->id(),
452 action_set.get(),
453 ON_BEFORE_REQUEST));
454 }
455
456 TEST_F(WebRequestActionWithThreadsTest, PermissionsToIgnore) {
457 const char kAction[] =
458 "[{"
459 " \"instanceType\": \"declarativeWebRequest.IgnoreRules\","
460 " \"lowerPriorityThan\": 123,"
461 " \"hasTag\": \"some_tag\""
462 "}]";
463 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));
464
465 // Ignoring rules works without full host permissions.
466 EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
467 extension_->id(),
468 action_set.get(),
469 ON_BEFORE_REQUEST));
470 }
471
472 TEST(WebRequestActionTest, GetName) {
473 const char kActions[] =
474 "[{"
475 " \"instanceType\": \"declarativeWebRequest.RedirectRequest\","
476 " \"redirectUrl\": \"http://www.foobar.com\""
477 "},"
478 "{"
479 " \"instanceType\": \"declarativeWebRequest.RedirectByRegEx\","
480 " \"from\": \".*\","
481 " \"to\": \"http://www.foobar.com\""
482 "},"
483 "{"
484 " \"instanceType\": \"declarativeWebRequest.SetRequestHeader\","
485 " \"name\": \"testname\","
486 " \"value\": \"testvalue\""
487 "},"
488 "{"
489 " \"instanceType\": \"declarativeWebRequest.RemoveRequestHeader\","
490 " \"name\": \"testname\""
491 "},"
492 "{"
493 " \"instanceType\": \"declarativeWebRequest.AddResponseHeader\","
494 " \"name\": \"testname\","
495 " \"value\": \"testvalue\""
496 "},"
497 "{"
498 " \"instanceType\": \"declarativeWebRequest.RemoveResponseHeader\","
499 " \"name\": \"testname\""
500 "},"
501 "{"
502 " \"instanceType\": \"declarativeWebRequest.SendMessageToExtension\","
503 " \"message\": \"testtext\""
504 "},"
505 "{"
506 " \"instanceType\": \"declarativeWebRequest.AddRequestCookie\","
507 " \"cookie\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
508 "},"
509 "{"
510 " \"instanceType\": \"declarativeWebRequest.AddResponseCookie\","
511 " \"cookie\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
512 "},"
513 "{"
514 " \"instanceType\": \"declarativeWebRequest.EditRequestCookie\","
515 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" },"
516 " \"modification\": { \"name\": \"name2\", \"value\": \"value2\" }"
517 "},"
518 "{"
519 " \"instanceType\": \"declarativeWebRequest.EditResponseCookie\","
520 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" },"
521 " \"modification\": { \"name\": \"name2\", \"value\": \"value2\" }"
522 "},"
523 "{"
524 " \"instanceType\": \"declarativeWebRequest.RemoveRequestCookie\","
525 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
526 "},"
527 "{"
528 " \"instanceType\": \"declarativeWebRequest.RemoveResponseCookie\","
529 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
530 "},"
531 "{"
532 " \"instanceType\": \"declarativeWebRequest.CancelRequest\""
533 "},"
534 "{"
535 " \"instanceType\": \"declarativeWebRequest.RedirectToTransparentImage\""
536 "},"
537 "{"
538 " \"instanceType\": \"declarativeWebRequest.RedirectToEmptyDocument\""
539 "},"
540 "{"
541 " \"instanceType\": \"declarativeWebRequest.IgnoreRules\","
542 " \"lowerPriorityThan\": 123,"
543 " \"hasTag\": \"some_tag\""
544 "}]";
545 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kActions));
546 for (WebRequestActionSet::Actions::const_iterator it =
547 action_set->actions().begin();
548 it != action_set->actions().end();
549 ++it) {
550 EXPECT_THAT((*it)->GetName(), HasSubstr("declarativeWebRequest."));
551 }
157 } 552 }
158 553
159 } // namespace extensions 554 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698