| Index: chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc
|
| diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc
|
| index 77a0a469d63c092eadf2bf4db5965e1af82acb21..6abc9217db14ec91054593ea72ddb141d77a34aa 100644
|
| --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc
|
| +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc
|
| @@ -4,23 +4,175 @@
|
|
|
| #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h"
|
|
|
| +#include "base/files/file_path.h"
|
| +#include "base/json/json_file_value_serializer.h"
|
| +#include "base/memory/ref_counted.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| #include "base/message_loop.h"
|
| +#include "base/path_service.h"
|
| +#include "base/test/values_test_util.h"
|
| +#include "base/time.h"
|
| #include "base/values.h"
|
| +#include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
|
| #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h"
|
| #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h"
|
| #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
|
| +#include "chrome/browser/extensions/extension_info_map.h"
|
| +#include "chrome/common/chrome_paths.h"
|
| +#include "chrome/common/extensions/extension.h"
|
| #include "chrome/common/extensions/extension_constants.h"
|
| +#include "chrome/common/extensions/extension_test_util.h"
|
| +#include "content/public/test/test_browser_thread.h"
|
| +#include "net/http/http_response_headers.h"
|
| #include "net/url_request/url_request_test_util.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| +using base::DictionaryValue;
|
| +using base::ListValue;
|
| +using extension_test_util::LoadManifestUnchecked;
|
| +using testing::HasSubstr;
|
| +
|
| +namespace extensions {
|
| +
|
| namespace {
|
| +
|
| const char kUnknownActionType[] = "unknownType";
|
| -} // namespace
|
|
|
| -namespace extensions {
|
| +scoped_ptr<WebRequestActionSet> CreateSetOfActions(const char* json) {
|
| + scoped_ptr<Value> parsed_value(base::test::ParseJson(json));
|
| + const ListValue* parsed_list;
|
| + CHECK(parsed_value->GetAsList(&parsed_list));
|
| +
|
| + WebRequestActionSet::AnyVector actions;
|
| + for (ListValue::const_iterator it = parsed_list->begin();
|
| + it != parsed_list->end();
|
| + ++it) {
|
| + const DictionaryValue* dict;
|
| + CHECK((*it)->GetAsDictionary(&dict));
|
| + actions.push_back(linked_ptr<base::Value>(dict->DeepCopy()));
|
| + }
|
| +
|
| + std::string error;
|
| + bool bad_message = false;
|
| +
|
| + scoped_ptr<WebRequestActionSet> action_set(
|
| + WebRequestActionSet::Create(actions, &error, &bad_message));
|
| + EXPECT_EQ("", error);
|
| + EXPECT_FALSE(bad_message);
|
| + CHECK(action_set);
|
| + return action_set.Pass();
|
| +}
|
| +
|
| +} // namespace
|
|
|
| namespace keys = declarative_webrequest_constants;
|
|
|
| +class WebRequestActionWithThreadsTest : public testing::Test {
|
| + public:
|
| + WebRequestActionWithThreadsTest()
|
| + : io_thread_(content::BrowserThread::IO, &message_loop_) {}
|
| +
|
| + protected:
|
| + virtual void SetUp() OVERRIDE;
|
| +
|
| + // Creates a URL request for URL |url_string|, and applies the actions from
|
| + // |action_set| as if they were triggered by the extension with
|
| + // |extension_id| during |stage|.
|
| + bool ActionWorksOnRequest(const char* url_string,
|
| + const std::string& extension_id,
|
| + const WebRequestActionSet* action_set,
|
| + RequestStage stage);
|
| +
|
| + // Expects a JSON description of an |action| requiring <all_urls> host
|
| + // permission, and checks that only an extensions with full host permissions
|
| + // can execute that action at |stage|. Also checks that the action is not
|
| + // executable for http://clients1.google.com.
|
| + void CheckActionNeedsAllUrls(const char* action, RequestStage stage);
|
| +
|
| + net::TestURLRequestContext context_;
|
| +
|
| + // An extension with *.com host permissions and the DWR permission.
|
| + scoped_refptr<Extension> extension_;
|
| + // An extension with host permissions for all URLs and the DWR permission.
|
| + scoped_refptr<Extension> extension_all_urls_;
|
| + scoped_refptr<ExtensionInfoMap> extension_info_map_;
|
| +
|
| + private:
|
| + MessageLoopForIO message_loop_;
|
| + content::TestBrowserThread io_thread_;
|
| +};
|
| +
|
| +void WebRequestActionWithThreadsTest::SetUp() {
|
| + testing::Test::SetUp();
|
| +
|
| + std::string error;
|
| + extension_ = LoadManifestUnchecked("permissions",
|
| + "web_request_com_host_permissions.json",
|
| + Manifest::INVALID_LOCATION,
|
| + Extension::NO_FLAGS,
|
| + "ext_id_1",
|
| + &error);
|
| + ASSERT_TRUE(extension_) << error;
|
| + extension_all_urls_ =
|
| + LoadManifestUnchecked("permissions",
|
| + "web_request_all_host_permissions.json",
|
| + Manifest::INVALID_LOCATION,
|
| + Extension::NO_FLAGS,
|
| + "ext_id_2",
|
| + &error);
|
| + ASSERT_TRUE(extension_all_urls_) << error;
|
| + extension_info_map_ = new ExtensionInfoMap;
|
| + ASSERT_TRUE(extension_info_map_);
|
| + extension_info_map_->AddExtension(
|
| + extension_.get(), base::Time::Now(), false /*incognito_enabled*/);
|
| + extension_info_map_->AddExtension(extension_all_urls_.get(),
|
| + base::Time::Now(),
|
| + false /*incognito_enabled*/);
|
| +}
|
| +
|
| +bool WebRequestActionWithThreadsTest::ActionWorksOnRequest(
|
| + const char* url_string,
|
| + const std::string& extension_id,
|
| + const WebRequestActionSet* action_set,
|
| + RequestStage stage) {
|
| + net::TestURLRequest regular_request(GURL(url_string), NULL, &context_, NULL);
|
| + std::list<LinkedPtrEventResponseDelta> deltas;
|
| + scoped_refptr<net::HttpResponseHeaders> headers(
|
| + new net::HttpResponseHeaders(""));
|
| + WebRequestData request_data(®ular_request, stage, headers);
|
| + std::set<std::string> ignored_tags;
|
| + WebRequestAction::ApplyInfo apply_info = {
|
| + extension_info_map_, request_data, false /*crosses_incognito*/, &deltas,
|
| + &ignored_tags
|
| + };
|
| + action_set->Apply(extension_id, base::Time(), &apply_info);
|
| + return (1u == deltas.size() || 0u < ignored_tags.size());
|
| +}
|
| +
|
| +void WebRequestActionWithThreadsTest::CheckActionNeedsAllUrls(
|
| + const char* action,
|
| + RequestStage stage) {
|
| + scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(action));
|
| +
|
| + // Although |extension_| has matching *.com host permission, |action|
|
| + // is intentionally forbidden -- in Declarative WR, host permission
|
| + // for less than all URLs are ignored (except in SendMessageToExtension).
|
| + EXPECT_FALSE(ActionWorksOnRequest(
|
| + "http://test.com", extension_->id(), action_set.get(), stage));
|
| + // With the "<all_urls>" host permission they are allowed.
|
| + EXPECT_TRUE(ActionWorksOnRequest(
|
| + "http://test.com", extension_all_urls_->id(), action_set.get(), stage));
|
| +
|
| + // The protected URLs should not be touched at all.
|
| + EXPECT_FALSE(ActionWorksOnRequest(
|
| + "http://clients1.google.com", extension_->id(), action_set.get(), stage));
|
| + EXPECT_FALSE(ActionWorksOnRequest("http://clients1.google.com",
|
| + extension_all_urls_->id(),
|
| + action_set.get(),
|
| + stage));
|
| +}
|
| +
|
| TEST(WebRequestActionTest, CreateAction) {
|
| std::string error;
|
| bool bad_message = false;
|
| @@ -115,45 +267,288 @@ TEST(WebRequestActionTest, PerlToRe2Style) {
|
| #undef CallPerlToRe2Style
|
| }
|
|
|
| -TEST(WebRequestActionTest, TestPermissions) {
|
| - // Necessary for TestURLRequest.
|
| - MessageLoop message_loop(MessageLoop::TYPE_IO);
|
| - net::TestURLRequestContext context;
|
| +TEST_F(WebRequestActionWithThreadsTest, PermissionsToRedirect) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.RedirectRequest\","
|
| + " \"redirectUrl\": \"http://www.foobar.com\""
|
| + "}]";
|
| + CheckActionNeedsAllUrls(kAction, ON_BEFORE_REQUEST);
|
| +}
|
|
|
| - std::string error;
|
| - bool bad_message = false;
|
| - scoped_ptr<WebRequestActionSet> action_set;
|
| +TEST_F(WebRequestActionWithThreadsTest, PermissionsToRedirectByRegEx) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.RedirectByRegEx\","
|
| + " \"from\": \".*\","
|
| + " \"to\": \"http://www.foobar.com\""
|
| + "}]";
|
| + CheckActionNeedsAllUrls(kAction, ON_BEFORE_REQUEST);
|
| +}
|
|
|
| - // Setup redirect to http://www.foobar.com.
|
| - base::DictionaryValue redirect;
|
| - redirect.SetString(keys::kInstanceTypeKey, keys::kRedirectRequestType);
|
| - redirect.SetString(keys::kRedirectUrlKey, "http://www.foobar.com");
|
| +TEST_F(WebRequestActionWithThreadsTest, PermissionsToSetRequestHeader) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.SetRequestHeader\","
|
| + " \"name\": \"testname\","
|
| + " \"value\": \"testvalue\""
|
| + "}]";
|
| + CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
|
| +}
|
|
|
| - WebRequestActionSet::AnyVector actions;
|
| - actions.push_back(linked_ptr<base::Value>(redirect.DeepCopy()));
|
| +TEST_F(WebRequestActionWithThreadsTest, PermissionsToRemoveRequestHeader) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.RemoveRequestHeader\","
|
| + " \"name\": \"testname\""
|
| + "}]";
|
| + CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
|
| +}
|
|
|
| - action_set = WebRequestActionSet::Create(actions, &error, &bad_message);
|
| - EXPECT_EQ("", error);
|
| - EXPECT_FALSE(bad_message);
|
| +TEST_F(WebRequestActionWithThreadsTest, PermissionsToAddResponseHeader) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.AddResponseHeader\","
|
| + " \"name\": \"testname\","
|
| + " \"value\": \"testvalue\""
|
| + "}]";
|
| + CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
|
| +}
|
|
|
| - // Check that redirect works on regular URLs but not on protected URLs.
|
| - net::TestURLRequest regular_request(
|
| - GURL("http://test.com"), NULL, &context, NULL);
|
| - std::list<LinkedPtrEventResponseDelta> deltas;
|
| - WebRequestData request_data(®ular_request, ON_BEFORE_REQUEST);
|
| - WebRequestAction::ApplyInfo apply_info = {
|
| - NULL, request_data, false, &deltas
|
| - };
|
| - action_set->Apply("ext1", base::Time(), &apply_info);
|
| - EXPECT_EQ(1u, deltas.size());
|
| -
|
| - net::TestURLRequest protected_request(GURL("http://clients1.google.com"),
|
| - NULL, &context, NULL);
|
| - deltas.clear();
|
| - request_data = WebRequestData(&protected_request, ON_BEFORE_REQUEST);
|
| - // Note that we just updated the request_data reference in apply_info.
|
| - action_set->Apply("ext1", base::Time(), &apply_info);
|
| - EXPECT_EQ(0u, deltas.size());
|
| +TEST_F(WebRequestActionWithThreadsTest, PermissionsToRemoveResponseHeader) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.RemoveResponseHeader\","
|
| + " \"name\": \"testname\""
|
| + "}]";
|
| + CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
|
| +}
|
| +
|
| +TEST_F(WebRequestActionWithThreadsTest, PermissionsToSendMessageToExtension) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.SendMessageToExtension\","
|
| + " \"message\": \"testtext\""
|
| + "}]";
|
| + scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));
|
| +
|
| + // For sending messages, specific host permissions actually matter.
|
| + EXPECT_TRUE(ActionWorksOnRequest("http://test.com",
|
| + extension_->id(),
|
| + action_set.get(),
|
| + ON_BEFORE_REQUEST));
|
| + // With the "<all_urls>" host permission they are allowed.
|
| + EXPECT_TRUE(ActionWorksOnRequest("http://test.com",
|
| + extension_all_urls_->id(),
|
| + action_set.get(),
|
| + ON_BEFORE_REQUEST));
|
| +
|
| + // The protected URLs should not be touched at all.
|
| + EXPECT_FALSE(ActionWorksOnRequest("http://clients1.google.com",
|
| + extension_->id(),
|
| + action_set.get(),
|
| + ON_BEFORE_REQUEST));
|
| + EXPECT_FALSE(ActionWorksOnRequest("http://clients1.google.com",
|
| + extension_all_urls_->id(),
|
| + action_set.get(),
|
| + ON_BEFORE_REQUEST));
|
| +}
|
| +
|
| +TEST_F(WebRequestActionWithThreadsTest, PermissionsToAddRequestCookie) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.AddRequestCookie\","
|
| + " \"cookie\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
|
| + "}]";
|
| + CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
|
| +}
|
| +
|
| +TEST_F(WebRequestActionWithThreadsTest, PermissionsToAddResponseCookie) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.AddResponseCookie\","
|
| + " \"cookie\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
|
| + "}]";
|
| + CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
|
| +}
|
| +
|
| +TEST_F(WebRequestActionWithThreadsTest, PermissionsToEditRequestCookie) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.EditRequestCookie\","
|
| + " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" },"
|
| + " \"modification\": { \"name\": \"name2\", \"value\": \"value2\" }"
|
| + "}]";
|
| + CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
|
| +}
|
| +
|
| +TEST_F(WebRequestActionWithThreadsTest, PermissionsToEditResponseCookie) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.EditResponseCookie\","
|
| + " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" },"
|
| + " \"modification\": { \"name\": \"name2\", \"value\": \"value2\" }"
|
| + "}]";
|
| + CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
|
| +}
|
| +
|
| +TEST_F(WebRequestActionWithThreadsTest, PermissionsToRemoveRequestCookie) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.RemoveRequestCookie\","
|
| + " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
|
| + "}]";
|
| + CheckActionNeedsAllUrls(kAction, ON_BEFORE_SEND_HEADERS);
|
| +}
|
| +
|
| +TEST_F(WebRequestActionWithThreadsTest, PermissionsToRemoveResponseCookie) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.RemoveResponseCookie\","
|
| + " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
|
| + "}]";
|
| + CheckActionNeedsAllUrls(kAction, ON_HEADERS_RECEIVED);
|
| +}
|
| +
|
| +TEST_F(WebRequestActionWithThreadsTest, PermissionsToCancel) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.CancelRequest\""
|
| + "}]";
|
| + scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));
|
| +
|
| + // Cancelling requests works without full host permissions.
|
| + EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
|
| + extension_->id(),
|
| + action_set.get(),
|
| + ON_BEFORE_REQUEST));
|
| +}
|
| +
|
| +TEST_F(WebRequestActionWithThreadsTest,
|
| + PermissionsToRedirectToTransparentImage) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.RedirectToTransparentImage\""
|
| + "}]";
|
| + scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));
|
| +
|
| + // Redirecting to transparent images works without full host permissions.
|
| + EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
|
| + extension_->id(),
|
| + action_set.get(),
|
| + ON_BEFORE_REQUEST));
|
| +}
|
| +
|
| +TEST_F(WebRequestActionWithThreadsTest, PermissionsToRedirectToEmptyDocument) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.RedirectToEmptyDocument\""
|
| + "}]";
|
| + scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));
|
| +
|
| + // Redirecting to the empty document works without full host permissions.
|
| + EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
|
| + extension_->id(),
|
| + action_set.get(),
|
| + ON_BEFORE_REQUEST));
|
| +}
|
| +
|
| +TEST_F(WebRequestActionWithThreadsTest, PermissionsToIgnore) {
|
| + const char kAction[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.IgnoreRules\","
|
| + " \"lowerPriorityThan\": 123,"
|
| + " \"hasTag\": \"some_tag\""
|
| + "}]";
|
| + scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kAction));
|
| +
|
| + // Ignoring rules works without full host permissions.
|
| + EXPECT_TRUE(ActionWorksOnRequest("http://test.org",
|
| + extension_->id(),
|
| + action_set.get(),
|
| + ON_BEFORE_REQUEST));
|
| +}
|
| +
|
| +TEST(WebRequestActionTest, GetName) {
|
| + const char kActions[] =
|
| + "[{"
|
| + " \"instanceType\": \"declarativeWebRequest.RedirectRequest\","
|
| + " \"redirectUrl\": \"http://www.foobar.com\""
|
| + "},"
|
| + "{"
|
| + " \"instanceType\": \"declarativeWebRequest.RedirectByRegEx\","
|
| + " \"from\": \".*\","
|
| + " \"to\": \"http://www.foobar.com\""
|
| + "},"
|
| + "{"
|
| + " \"instanceType\": \"declarativeWebRequest.SetRequestHeader\","
|
| + " \"name\": \"testname\","
|
| + " \"value\": \"testvalue\""
|
| + "},"
|
| + "{"
|
| + " \"instanceType\": \"declarativeWebRequest.RemoveRequestHeader\","
|
| + " \"name\": \"testname\""
|
| + "},"
|
| + "{"
|
| + " \"instanceType\": \"declarativeWebRequest.AddResponseHeader\","
|
| + " \"name\": \"testname\","
|
| + " \"value\": \"testvalue\""
|
| + "},"
|
| + "{"
|
| + " \"instanceType\": \"declarativeWebRequest.RemoveResponseHeader\","
|
| + " \"name\": \"testname\""
|
| + "},"
|
| + "{"
|
| + " \"instanceType\": \"declarativeWebRequest.SendMessageToExtension\","
|
| + " \"message\": \"testtext\""
|
| + "},"
|
| + "{"
|
| + " \"instanceType\": \"declarativeWebRequest.AddRequestCookie\","
|
| + " \"cookie\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
|
| + "},"
|
| + "{"
|
| + " \"instanceType\": \"declarativeWebRequest.AddResponseCookie\","
|
| + " \"cookie\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
|
| + "},"
|
| + "{"
|
| + " \"instanceType\": \"declarativeWebRequest.EditRequestCookie\","
|
| + " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" },"
|
| + " \"modification\": { \"name\": \"name2\", \"value\": \"value2\" }"
|
| + "},"
|
| + "{"
|
| + " \"instanceType\": \"declarativeWebRequest.EditResponseCookie\","
|
| + " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" },"
|
| + " \"modification\": { \"name\": \"name2\", \"value\": \"value2\" }"
|
| + "},"
|
| + "{"
|
| + " \"instanceType\": \"declarativeWebRequest.RemoveRequestCookie\","
|
| + " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
|
| + "},"
|
| + "{"
|
| + " \"instanceType\": \"declarativeWebRequest.RemoveResponseCookie\","
|
| + " \"filter\": { \"name\": \"cookiename\", \"value\": \"cookievalue\" }"
|
| + "},"
|
| + "{"
|
| + " \"instanceType\": \"declarativeWebRequest.CancelRequest\""
|
| + "},"
|
| + "{"
|
| + " \"instanceType\": \"declarativeWebRequest.RedirectToTransparentImage\""
|
| + "},"
|
| + "{"
|
| + " \"instanceType\": \"declarativeWebRequest.RedirectToEmptyDocument\""
|
| + "},"
|
| + "{"
|
| + " \"instanceType\": \"declarativeWebRequest.IgnoreRules\","
|
| + " \"lowerPriorityThan\": 123,"
|
| + " \"hasTag\": \"some_tag\""
|
| + "}]";
|
| + scoped_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kActions));
|
| + for (WebRequestActionSet::Actions::const_iterator it =
|
| + action_set->actions().begin();
|
| + it != action_set->actions().end();
|
| + ++it) {
|
| + EXPECT_THAT((*it)->GetName(), HasSubstr("declarativeWebRequest."));
|
| + }
|
| }
|
|
|
| } // namespace extensions
|
|
|