Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / declarative_webrequest / webrequest_action_unittest.cc
blob9053ec1e751c89dc4a5d83e0d71350cf5e97ec20
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.
5 #include "extensions/browser/api/declarative_webrequest/webrequest_action.h"
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"
11 #include "base/message_loop/message_loop.h"
12 #include "base/test/values_test_util.h"
13 #include "base/time/time.h"
14 #include "base/values.h"
15 #include "chrome/common/chrome_paths.h"
16 #include "chrome/common/extensions/extension_constants.h"
17 #include "chrome/common/extensions/extension_test_util.h"
18 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "extensions/browser/api/declarative_webrequest/request_stage.h"
20 #include "extensions/browser/api/declarative_webrequest/webrequest_condition.h"
21 #include "extensions/browser/api/declarative_webrequest/webrequest_constants.h"
22 #include "extensions/browser/api/web_request/web_request_api_helpers.h"
23 #include "extensions/browser/info_map.h"
24 #include "extensions/common/extension.h"
25 #include "net/base/request_priority.h"
26 #include "net/http/http_response_headers.h"
27 #include "net/url_request/url_request.h"
28 #include "net/url_request/url_request_test_util.h"
29 #include "testing/gmock/include/gmock/gmock.h"
30 #include "testing/gtest/include/gtest/gtest.h"
32 using base::DictionaryValue;
33 using base::ListValue;
34 using extension_test_util::LoadManifestUnchecked;
35 using testing::HasSubstr;
37 namespace extensions {
39 namespace {
41 const char kUnknownActionType[] = "unknownType";
43 scoped_ptr<WebRequestActionSet> CreateSetOfActions(const char* json) {
44 scoped_ptr<base::Value> parsed_value(base::test::ParseJson(json));
45 const base::ListValue* parsed_list;
46 CHECK(parsed_value->GetAsList(&parsed_list));
48 WebRequestActionSet::Values actions;
49 for (base::ListValue::const_iterator it = parsed_list->begin();
50 it != parsed_list->end();
51 ++it) {
52 const base::DictionaryValue* dict;
53 CHECK((*it)->GetAsDictionary(&dict));
54 actions.push_back(linked_ptr<base::Value>(dict->DeepCopy()));
57 std::string error;
58 bool bad_message = false;
60 scoped_ptr<WebRequestActionSet> action_set(
61 WebRequestActionSet::Create(NULL, NULL, actions, &error, &bad_message));
62 EXPECT_EQ("", error);
63 EXPECT_FALSE(bad_message);
64 CHECK(action_set);
65 return action_set.Pass();
68 } // namespace
70 namespace keys = declarative_webrequest_constants;
72 class WebRequestActionWithThreadsTest : public testing::Test {
73 public:
74 WebRequestActionWithThreadsTest()
75 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
77 protected:
78 void SetUp() override;
80 // Creates a URL request for URL |url_string|, and applies the actions from
81 // |action_set| as if they were triggered by the extension with
82 // |extension_id| during |stage|.
83 bool ActionWorksOnRequest(const char* url_string,
84 const std::string& extension_id,
85 const WebRequestActionSet* action_set,
86 RequestStage stage);
88 // Expects a JSON description of an |action| requiring <all_urls> host
89 // permission, and checks that only an extensions with full host permissions
90 // can execute that action at |stage|. Also checks that the action is not
91 // executable for http://clients1.google.com.
92 void CheckActionNeedsAllUrls(const char* action, RequestStage stage);
94 private:
95 content::TestBrowserThreadBundle thread_bundle_;
97 protected:
98 net::TestURLRequestContext context_;
100 // An extension with *.com host permissions and the DWR permission.
101 scoped_refptr<Extension> extension_;
102 // An extension with host permissions for all URLs and the DWR permission.
103 scoped_refptr<Extension> extension_all_urls_;
104 scoped_refptr<InfoMap> extension_info_map_;
107 void WebRequestActionWithThreadsTest::SetUp() {
108 testing::Test::SetUp();
110 std::string error;
111 extension_ = LoadManifestUnchecked("permissions",
112 "web_request_com_host_permissions.json",
113 Manifest::INVALID_LOCATION,
114 Extension::NO_FLAGS,
115 "ext_id_1",
116 &error);
117 ASSERT_TRUE(extension_.get()) << error;
118 extension_all_urls_ =
119 LoadManifestUnchecked("permissions",
120 "web_request_all_host_permissions.json",
121 Manifest::INVALID_LOCATION,
122 Extension::NO_FLAGS,
123 "ext_id_2",
124 &error);
125 ASSERT_TRUE(extension_all_urls_.get()) << error;
126 extension_info_map_ = new InfoMap;
127 ASSERT_TRUE(extension_info_map_.get());
128 extension_info_map_->AddExtension(
129 extension_.get(),
130 base::Time::Now(),
131 false /*incognito_enabled*/,
132 false /*notifications_disabled*/);
133 extension_info_map_->AddExtension(extension_all_urls_.get(),
134 base::Time::Now(),
135 false /*incognito_enabled*/,
136 false /*notifications_disabled*/);
139 bool WebRequestActionWithThreadsTest::ActionWorksOnRequest(
140 const char* url_string,
141 const std::string& extension_id,
142 const WebRequestActionSet* action_set,
143 RequestStage stage) {
144 scoped_ptr<net::URLRequest> regular_request(context_.CreateRequest(
145 GURL(url_string), net::DEFAULT_PRIORITY, NULL));
146 std::list<LinkedPtrEventResponseDelta> deltas;
147 scoped_refptr<net::HttpResponseHeaders> headers(
148 new net::HttpResponseHeaders(""));
149 WebRequestData request_data(regular_request.get(), stage, headers.get());
150 std::set<std::string> ignored_tags;
151 WebRequestAction::ApplyInfo apply_info = { extension_info_map_.get(),
152 request_data,
153 false /*crosses_incognito*/,
154 &deltas, &ignored_tags };
155 action_set->Apply(extension_id, base::Time(), &apply_info);
156 return (1u == deltas.size() || 0u < ignored_tags.size());
159 void WebRequestActionWithThreadsTest::CheckActionNeedsAllUrls(
160 const char* action,
161 RequestStage stage) {
162 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(action));
164 // Although |extension_| has matching *.com host permission, |action|
165 // is intentionally forbidden -- in Declarative WR, host permission
166 // for less than all URLs are ignored (except in SendMessageToExtension).
167 EXPECT_FALSE(ActionWorksOnRequest(
168 "http://test.com", extension_->id(), action_set.get(), stage));
169 // With the "<all_urls>" host permission they are allowed.
170 EXPECT_TRUE(ActionWorksOnRequest(
171 "http://test.com", extension_all_urls_->id(), action_set.get(), stage));
173 // The protected URLs should not be touched at all.
174 EXPECT_FALSE(ActionWorksOnRequest(
175 "http://clients1.google.com", extension_->id(), action_set.get(), stage));
176 EXPECT_FALSE(ActionWorksOnRequest("http://clients1.google.com",
177 extension_all_urls_->id(),
178 action_set.get(),
179 stage));
182 TEST(WebRequestActionTest, CreateAction) {
183 std::string error;
184 bool bad_message = false;
185 scoped_refptr<const WebRequestAction> result;
187 // Test wrong data type passed.
188 error.clear();
189 base::ListValue empty_list;
190 result = WebRequestAction::Create(
191 NULL, NULL, empty_list, &error, &bad_message);
192 EXPECT_TRUE(bad_message);
193 EXPECT_FALSE(result.get());
195 // Test missing instanceType element.
196 base::DictionaryValue input;
197 error.clear();
198 result = WebRequestAction::Create(NULL, NULL, input, &error, &bad_message);
199 EXPECT_TRUE(bad_message);
200 EXPECT_FALSE(result.get());
202 // Test wrong instanceType element.
203 input.SetString(keys::kInstanceTypeKey, kUnknownActionType);
204 error.clear();
205 result = WebRequestAction::Create(NULL, NULL, input, &error, &bad_message);
206 EXPECT_NE("", error);
207 EXPECT_FALSE(result.get());
209 // Test success
210 input.SetString(keys::kInstanceTypeKey, keys::kCancelRequestType);
211 error.clear();
212 result = WebRequestAction::Create(NULL, NULL, input, &error, &bad_message);
213 EXPECT_EQ("", error);
214 EXPECT_FALSE(bad_message);
215 ASSERT_TRUE(result.get());
216 EXPECT_EQ(WebRequestAction::ACTION_CANCEL_REQUEST, result->type());
219 TEST(WebRequestActionTest, CreateActionSet) {
220 std::string error;
221 bool bad_message = false;
222 scoped_ptr<WebRequestActionSet> result;
224 WebRequestActionSet::Values input;
226 // Test empty input.
227 error.clear();
228 result = WebRequestActionSet::Create(NULL, NULL, input, &error, &bad_message);
229 EXPECT_TRUE(error.empty()) << error;
230 EXPECT_FALSE(bad_message);
231 ASSERT_TRUE(result.get());
232 EXPECT_TRUE(result->actions().empty());
233 EXPECT_EQ(std::numeric_limits<int>::min(), result->GetMinimumPriority());
235 base::DictionaryValue correct_action;
236 correct_action.SetString(keys::kInstanceTypeKey, keys::kIgnoreRulesType);
237 correct_action.SetInteger(keys::kLowerPriorityThanKey, 10);
238 base::DictionaryValue incorrect_action;
239 incorrect_action.SetString(keys::kInstanceTypeKey, kUnknownActionType);
241 // Test success.
242 input.push_back(linked_ptr<base::Value>(correct_action.DeepCopy()));
243 error.clear();
244 result = WebRequestActionSet::Create(NULL, NULL, input, &error, &bad_message);
245 EXPECT_TRUE(error.empty()) << error;
246 EXPECT_FALSE(bad_message);
247 ASSERT_TRUE(result.get());
248 ASSERT_EQ(1u, result->actions().size());
249 EXPECT_EQ(WebRequestAction::ACTION_IGNORE_RULES,
250 result->actions()[0]->type());
251 EXPECT_EQ(10, result->GetMinimumPriority());
253 // Test failure.
254 input.push_back(linked_ptr<base::Value>(incorrect_action.DeepCopy()));
255 error.clear();
256 result = WebRequestActionSet::Create(NULL, NULL, input, &error, &bad_message);
257 EXPECT_NE("", error);
258 EXPECT_FALSE(result.get());
261 // Test capture group syntax conversions of WebRequestRedirectByRegExAction
262 TEST(WebRequestActionTest, PerlToRe2Style) {
263 #define CallPerlToRe2Style WebRequestRedirectByRegExAction::PerlToRe2Style
264 // foo$1bar -> foo\1bar
265 EXPECT_EQ("foo\\1bar", CallPerlToRe2Style("foo$1bar"));
266 // foo\$1bar -> foo$1bar
267 EXPECT_EQ("foo$1bar", CallPerlToRe2Style("foo\\$1bar"));
268 // foo\\$1bar -> foo\\\1bar
269 EXPECT_EQ("foo\\\\\\1bar", CallPerlToRe2Style("foo\\\\$1bar"));
270 // foo\bar -> foobar
271 EXPECT_EQ("foobar", CallPerlToRe2Style("foo\\bar"));
272 // foo$bar -> foo$bar
273 EXPECT_EQ("foo$bar", CallPerlToRe2Style("foo$bar"));
274 #undef CallPerlToRe2Style
277 TEST_F(WebRequestActionWithThreadsTest, PermissionsToRedirect) {
278 const char kAction[] =
279 "[{"
280 " \"instanceType\": \"declarativeWebRequest.RedirectRequest\","
281 " \"redirectUrl\": \"http://www.foobar.com\""
282 "}]";
283 CheckActionNeedsAllUrls(kAction, ON_BEFORE_REQUEST);
284 CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
287 TEST_F(WebRequestActionWithThreadsTest, PermissionsToRedirectByRegEx) {
288 const char kAction[] =
289 "[{"
290 " \"instanceType\": \"declarativeWebRequest.RedirectByRegEx\","
291 " \"from\": \".*\","
292 " \"to\": \"http://www.foobar.com\""
293 "}]";
294 CheckActionNeedsAllUrls(kAction, ON_BEFORE_REQUEST);
297 TEST_F(WebRequestActionWithThreadsTest, PermissionsToSetRequestHeader) {
298 const char kAction[] =
299 "[{"
300 " \"instanceType\": \"declarativeWebRequest.SetRequestHeader\","
301 " \"name\": \"testname\","
302 " \"value\": \"testvalue\""
303 "}]";
304 CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
307 TEST_F(WebRequestActionWithThreadsTest, PermissionsToRemoveRequestHeader) {
308 const char kAction[] =
309 "[{"
310 " \"instanceType\": \"declarativeWebRequest.RemoveRequestHeader\","
311 " \"name\": \"testname\""
312 "}]";
313 CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
316 TEST_F(WebRequestActionWithThreadsTest, PermissionsToAddResponseHeader) {
317 const char kAction[] =
318 "[{"
319 " \"instanceType\": \"declarativeWebRequest.AddResponseHeader\","
320 " \"name\": \"testname\","
321 " \"value\": \"testvalue\""
322 "}]";
323 CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
326 TEST_F(WebRequestActionWithThreadsTest, PermissionsToRemoveResponseHeader) {
327 const char kAction[] =
328 "[{"
329 " \"instanceType\": \"declarativeWebRequest.RemoveResponseHeader\","
330 " \"name\": \"testname\""
331 "}]";
332 CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
335 TEST_F(WebRequestActionWithThreadsTest, PermissionsToSendMessageToExtension) {
336 const char kAction[] =
337 "[{"
338 " \"instanceType\": \"declarativeWebRequest.SendMessageToExtension\","
339 " \"message\": \"testtext\""
340 "}]";
341 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));
343 // For sending messages, specific host permissions actually matter.
344 EXPECT_TRUE(ActionWorksOnRequest("http://test.com",
345 extension_->id(),
346 action_set.get(),
347 ON_BEFORE_REQUEST));
348 // With the "<all_urls>" host permission they are allowed.
349 EXPECT_TRUE(ActionWorksOnRequest("http://test.com",
350 extension_all_urls_->id(),
351 action_set.get(),
352 ON_BEFORE_REQUEST));
354 // The protected URLs should not be touched at all.
355 EXPECT_FALSE(ActionWorksOnRequest("http://clients1.google.com",
356 extension_->id(),
357 action_set.get(),
358 ON_BEFORE_REQUEST));
359 EXPECT_FALSE(ActionWorksOnRequest("http://clients1.google.com",
360 extension_all_urls_->id(),
361 action_set.get(),
362 ON_BEFORE_REQUEST));
365 TEST_F(WebRequestActionWithThreadsTest, PermissionsToAddRequestCookie) {
366 const char kAction[] =
367 "[{"
368 " \"instanceType\": \"declarativeWebRequest.AddRequestCookie\","
369 " \"cookie\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
370 "}]";
371 CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
374 TEST_F(WebRequestActionWithThreadsTest, PermissionsToAddResponseCookie) {
375 const char kAction[] =
376 "[{"
377 " \"instanceType\": \"declarativeWebRequest.AddResponseCookie\","
378 " \"cookie\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
379 "}]";
380 CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
383 TEST_F(WebRequestActionWithThreadsTest, PermissionsToEditRequestCookie) {
384 const char kAction[] =
385 "[{"
386 " \"instanceType\": \"declarativeWebRequest.EditRequestCookie\","
387 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" },"
388 " \"modification\": { \"name\": \"name2\", \"value\": \"value2\" }"
389 "}]";
390 CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
393 TEST_F(WebRequestActionWithThreadsTest, PermissionsToEditResponseCookie) {
394 const char kAction[] =
395 "[{"
396 " \"instanceType\": \"declarativeWebRequest.EditResponseCookie\","
397 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" },"
398 " \"modification\": { \"name\": \"name2\", \"value\": \"value2\" }"
399 "}]";
400 CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
403 TEST_F(WebRequestActionWithThreadsTest, PermissionsToRemoveRequestCookie) {
404 const char kAction[] =
405 "[{"
406 " \"instanceType\": \"declarativeWebRequest.RemoveRequestCookie\","
407 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
408 "}]";
409 CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
412 TEST_F(WebRequestActionWithThreadsTest, PermissionsToRemoveResponseCookie) {
413 const char kAction[] =
414 "[{"
415 " \"instanceType\": \"declarativeWebRequest.RemoveResponseCookie\","
416 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
417 "}]";
418 CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
421 TEST_F(WebRequestActionWithThreadsTest, PermissionsToCancel) {
422 const char kAction[] =
423 "[{"
424 " \"instanceType\": \"declarativeWebRequest.CancelRequest\""
425 "}]";
426 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));
428 // Cancelling requests works without full host permissions.
429 EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
430 extension_->id(),
431 action_set.get(),
432 ON_BEFORE_REQUEST));
435 TEST_F(WebRequestActionWithThreadsTest,
436 PermissionsToRedirectToTransparentImage) {
437 const char kAction[] =
438 "[{"
439 " \"instanceType\": \"declarativeWebRequest.RedirectToTransparentImage\""
440 "}]";
441 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));
443 // Redirecting to transparent images works without full host permissions.
444 EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
445 extension_->id(),
446 action_set.get(),
447 ON_BEFORE_REQUEST));
448 EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
449 extension_->id(),
450 action_set.get(),
451 ON_HEADERS_RECEIVED));
454 TEST_F(WebRequestActionWithThreadsTest, PermissionsToRedirectToEmptyDocument) {
455 const char kAction[] =
456 "[{"
457 " \"instanceType\": \"declarativeWebRequest.RedirectToEmptyDocument\""
458 "}]";
459 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));
461 // Redirecting to the empty document works without full host permissions.
462 EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
463 extension_->id(),
464 action_set.get(),
465 ON_BEFORE_REQUEST));
466 EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
467 extension_->id(),
468 action_set.get(),
469 ON_HEADERS_RECEIVED));
472 TEST_F(WebRequestActionWithThreadsTest, PermissionsToIgnore) {
473 const char kAction[] =
474 "[{"
475 " \"instanceType\": \"declarativeWebRequest.IgnoreRules\","
476 " \"lowerPriorityThan\": 123,"
477 " \"hasTag\": \"some_tag\""
478 "}]";
479 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));
481 // Ignoring rules works without full host permissions.
482 EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
483 extension_->id(),
484 action_set.get(),
485 ON_BEFORE_REQUEST));
488 TEST(WebRequestActionTest, GetName) {
489 const char kActions[] =
490 "[{"
491 " \"instanceType\": \"declarativeWebRequest.RedirectRequest\","
492 " \"redirectUrl\": \"http://www.foobar.com\""
493 "},"
495 " \"instanceType\": \"declarativeWebRequest.RedirectByRegEx\","
496 " \"from\": \".*\","
497 " \"to\": \"http://www.foobar.com\""
498 "},"
500 " \"instanceType\": \"declarativeWebRequest.SetRequestHeader\","
501 " \"name\": \"testname\","
502 " \"value\": \"testvalue\""
503 "},"
505 " \"instanceType\": \"declarativeWebRequest.RemoveRequestHeader\","
506 " \"name\": \"testname\""
507 "},"
509 " \"instanceType\": \"declarativeWebRequest.AddResponseHeader\","
510 " \"name\": \"testname\","
511 " \"value\": \"testvalue\""
512 "},"
514 " \"instanceType\": \"declarativeWebRequest.RemoveResponseHeader\","
515 " \"name\": \"testname\""
516 "},"
518 " \"instanceType\": \"declarativeWebRequest.SendMessageToExtension\","
519 " \"message\": \"testtext\""
520 "},"
522 " \"instanceType\": \"declarativeWebRequest.AddRequestCookie\","
523 " \"cookie\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
524 "},"
526 " \"instanceType\": \"declarativeWebRequest.AddResponseCookie\","
527 " \"cookie\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
528 "},"
530 " \"instanceType\": \"declarativeWebRequest.EditRequestCookie\","
531 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" },"
532 " \"modification\": { \"name\": \"name2\", \"value\": \"value2\" }"
533 "},"
535 " \"instanceType\": \"declarativeWebRequest.EditResponseCookie\","
536 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" },"
537 " \"modification\": { \"name\": \"name2\", \"value\": \"value2\" }"
538 "},"
540 " \"instanceType\": \"declarativeWebRequest.RemoveRequestCookie\","
541 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
542 "},"
544 " \"instanceType\": \"declarativeWebRequest.RemoveResponseCookie\","
545 " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
546 "},"
548 " \"instanceType\": \"declarativeWebRequest.CancelRequest\""
549 "},"
551 " \"instanceType\": \"declarativeWebRequest.RedirectToTransparentImage\""
552 "},"
554 " \"instanceType\": \"declarativeWebRequest.RedirectToEmptyDocument\""
555 "},"
557 " \"instanceType\": \"declarativeWebRequest.IgnoreRules\","
558 " \"lowerPriorityThan\": 123,"
559 " \"hasTag\": \"some_tag\""
560 "}]";
561 const char* const kExpectedNames[] = {
562 "declarativeWebRequest.RedirectRequest",
563 "declarativeWebRequest.RedirectByRegEx",
564 "declarativeWebRequest.SetRequestHeader",
565 "declarativeWebRequest.RemoveRequestHeader",
566 "declarativeWebRequest.AddResponseHeader",
567 "declarativeWebRequest.RemoveResponseHeader",
568 "declarativeWebRequest.SendMessageToExtension",
569 "declarativeWebRequest.AddRequestCookie",
570 "declarativeWebRequest.AddResponseCookie",
571 "declarativeWebRequest.EditRequestCookie",
572 "declarativeWebRequest.EditResponseCookie",
573 "declarativeWebRequest.RemoveRequestCookie",
574 "declarativeWebRequest.RemoveResponseCookie",
575 "declarativeWebRequest.CancelRequest",
576 "declarativeWebRequest.RedirectToTransparentImage",
577 "declarativeWebRequest.RedirectToEmptyDocument",
578 "declarativeWebRequest.IgnoreRules",
580 scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kActions));
581 ASSERT_EQ(arraysize(kExpectedNames), action_set->actions().size());
582 size_t index = 0;
583 for (WebRequestActionSet::Actions::const_iterator it =
584 action_set->actions().begin();
585 it != action_set->actions().end();
586 ++it) {
587 EXPECT_EQ(kExpectedNames[index], (*it)->GetName());
588 ++index;
592 } // namespace extensions