15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/declarative_webrequest/webrequest_condition_attribute.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/memory/scoped_ptr.h"
109ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/resource_request_info.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/declarative_webrequest/webrequest_condition.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/declarative_webrequest/webrequest_constants.h"
150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "net/base/request_priority.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/test/embedded_test_server/embedded_test_server.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/url_request/url_request.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request_test_util.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::DictionaryValue;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::FundamentalValue;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::ListValue;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringValue;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Value;
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing content::ResourceType;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace keys = declarative_webrequest_constants;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kUnknownConditionName[] = "unknownType";
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::FilePath TestDataPath(base::StringPiece relative_to_src) {
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath src_dir;
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &src_dir));
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return src_dir.AppendASCII(relative_to_src);
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WebRequestConditionAttributeTest, CreateConditionAttribute) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Necessary for TestURLRequest.
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoopForIO message_loop;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const WebRequestConditionAttribute> result;
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::StringValue string_value("main_frame");
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue resource_types;
493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  resource_types.Append(new base::StringValue("main_frame"));
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test wrong condition name passed.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error.clear();
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = WebRequestConditionAttribute::Create(
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUnknownConditionName, &resource_types, &error);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(error.empty());
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(result.get());
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test wrong data type passed
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error.clear();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = WebRequestConditionAttribute::Create(
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      keys::kResourceTypeKey, &string_value, &error);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(error.empty());
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(result.get());
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error.clear();
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = WebRequestConditionAttribute::Create(
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      keys::kContentTypeKey, &string_value, &error);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(error.empty());
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(result.get());
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test success
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error.clear();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = WebRequestConditionAttribute::Create(
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      keys::kResourceTypeKey, &resource_types, &error);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", error);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(result.get());
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(WebRequestConditionAttribute::CONDITION_RESOURCE_TYPE,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            result->GetType());
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(std::string(keys::kResourceTypeKey), result->GetName());
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WebRequestConditionAttributeTest, ResourceType) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Necessary for TestURLRequest.
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoopForIO message_loop;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue resource_types;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The 'sub_frame' value is chosen arbitrarily, so as the corresponding
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // content::ResourceType is not 0, the default value.
903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  resource_types.Append(new base::StringValue("sub_frame"));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const WebRequestConditionAttribute> attribute =
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebRequestConditionAttribute::Create(
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          keys::kResourceTypeKey, &resource_types, &error);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", error);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(attribute.get());
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(std::string(keys::kResourceTypeKey), attribute->GetName());
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLRequestContext context;
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<net::URLRequest> url_request_ok(context.CreateRequest(
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GURL("http://www.example.com"), net::DEFAULT_PRIORITY, NULL, NULL));
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::ResourceRequestInfo::AllocateForTesting(
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url_request_ok.get(),
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      content::RESOURCE_TYPE_SUB_FRAME,
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      NULL,
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      -1,
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      -1,
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      -1,
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      false);
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(attribute->IsFulfilled(WebRequestData(url_request_ok.get(),
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                    ON_BEFORE_REQUEST)));
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<net::URLRequest> url_request_fail(context.CreateRequest(
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GURL("http://www.example.com"), net::DEFAULT_PRIORITY, NULL, NULL));
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::ResourceRequestInfo::AllocateForTesting(
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url_request_fail.get(),
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      content::RESOURCE_TYPE_MAIN_FRAME,
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      NULL,
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      -1,
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      -1,
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      -1,
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      false);
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(attribute->IsFulfilled(WebRequestData(url_request_fail.get(),
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                     ON_BEFORE_REQUEST)));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WebRequestConditionAttributeTest, ContentType) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Necessary for TestURLRequest.
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoopForIO message_loop;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const WebRequestConditionAttribute> result;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::test_server::EmbeddedTestServer test_server;
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  test_server.ServeFilesFromDirectory(TestDataPath(
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "chrome/test/data/extensions/api_test/webrequest/declarative"));
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_server.InitializeAndWaitUntilReady());
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLRequestContext context;
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestDelegate delegate;
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<net::URLRequest> url_request(
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      context.CreateRequest(test_server.GetURL("/headers.html"),
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            net::DEFAULT_PRIORITY,
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            &delegate,
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            NULL));
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  url_request->Start();
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue content_types;
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  content_types.Append(new base::StringValue("text/plain"));
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const WebRequestConditionAttribute> attribute_include =
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebRequestConditionAttribute::Create(
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          keys::kContentTypeKey, &content_types, &error);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", error);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(attribute_include.get());
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(attribute_include->IsFulfilled(
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      WebRequestData(url_request.get(), ON_BEFORE_REQUEST,
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     url_request->response_headers())));
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(attribute_include->IsFulfilled(
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      WebRequestData(url_request.get(), ON_HEADERS_RECEIVED,
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     url_request->response_headers())));
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(std::string(keys::kContentTypeKey), attribute_include->GetName());
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const WebRequestConditionAttribute> attribute_exclude =
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebRequestConditionAttribute::Create(
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          keys::kExcludeContentTypeKey, &content_types, &error);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", error);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(attribute_exclude.get());
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(attribute_exclude->IsFulfilled(
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      WebRequestData(url_request.get(), ON_HEADERS_RECEIVED,
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     url_request->response_headers())));
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content_types.Clear();
1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  content_types.Append(new base::StringValue("something/invalid"));
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const WebRequestConditionAttribute> attribute_unincluded =
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebRequestConditionAttribute::Create(
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          keys::kContentTypeKey, &content_types, &error);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", error);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(attribute_unincluded.get());
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(attribute_unincluded->IsFulfilled(
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      WebRequestData(url_request.get(), ON_HEADERS_RECEIVED,
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     url_request->response_headers())));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const WebRequestConditionAttribute> attribute_unexcluded =
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebRequestConditionAttribute::Create(
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          keys::kExcludeContentTypeKey, &content_types, &error);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", error);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(attribute_unexcluded.get());
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(attribute_unexcluded->IsFulfilled(
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      WebRequestData(url_request.get(), ON_HEADERS_RECEIVED,
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     url_request->response_headers())));
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(std::string(keys::kExcludeContentTypeKey),
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            attribute_unexcluded->GetName());
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Testing WebRequestConditionAttributeThirdParty.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WebRequestConditionAttributeTest, ThirdParty) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Necessary for TestURLRequest.
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoopForIO message_loop;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FundamentalValue value_true(true);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This attribute matches only third party requests.
20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const WebRequestConditionAttribute> third_party_attribute =
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebRequestConditionAttribute::Create(keys::kThirdPartyKey,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &value_true,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &error);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ("", error);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(third_party_attribute.get());
21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(std::string(keys::kThirdPartyKey),
21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            third_party_attribute->GetName());
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FundamentalValue value_false(false);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This attribute matches only first party requests.
21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const WebRequestConditionAttribute> first_party_attribute =
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebRequestConditionAttribute::Create(keys::kThirdPartyKey,
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &value_false,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &error);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ("", error);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(first_party_attribute.get());
22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(std::string(keys::kThirdPartyKey),
22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            first_party_attribute->GetName());
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url_empty;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url_a("http://a.com");
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url_b("http://b.com");
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLRequestContext context;
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestDelegate delegate;
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<net::URLRequest> url_request(
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      context.CreateRequest(url_a, net::DEFAULT_PRIORITY, &delegate, NULL));
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (unsigned int i = 1; i <= kLastActiveStage; i <<= 1) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(kActiveStages & i))
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const RequestStage stage = static_cast<RequestStage>(i);
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    url_request->set_first_party_for_cookies(url_empty);
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_FALSE(third_party_attribute->IsFulfilled(
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        WebRequestData(url_request.get(), stage)));
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(first_party_attribute->IsFulfilled(
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        WebRequestData(url_request.get(), stage)));
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    url_request->set_first_party_for_cookies(url_b);
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(third_party_attribute->IsFulfilled(
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        WebRequestData(url_request.get(), stage)));
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_FALSE(first_party_attribute->IsFulfilled(
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        WebRequestData(url_request.get(), stage)));
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    url_request->set_first_party_for_cookies(url_a);
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_FALSE(third_party_attribute->IsFulfilled(
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        WebRequestData(url_request.get(), stage)));
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(first_party_attribute->IsFulfilled(
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        WebRequestData(url_request.get(), stage)));
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Testing WebRequestConditionAttributeStages. This iterates over all stages,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and tests a couple of "stage" attributes -- one created with an empty set of
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// applicable stages, one for each stage applicable for that stage, and one
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// applicable in all stages.
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WebRequestConditionAttributeTest, Stages) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Necessary for TestURLRequest.
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoopForIO message_loop;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::pair<RequestStage, const char*> StageNamePair;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const StageNamePair active_stages[] = {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StageNamePair(ON_BEFORE_REQUEST, keys::kOnBeforeRequestEnum),
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StageNamePair(ON_BEFORE_SEND_HEADERS, keys::kOnBeforeSendHeadersEnum),
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StageNamePair(ON_HEADERS_RECEIVED, keys::kOnHeadersReceivedEnum),
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StageNamePair(ON_AUTH_REQUIRED, keys::kOnAuthRequiredEnum)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that exactly all active stages are considered in this test.
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int covered_stages = 0;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(active_stages); ++i)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    covered_stages |= active_stages[i].first;
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kActiveStages, covered_stages);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create an attribute with an empty set of applicable stages.
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue empty_list;
28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const WebRequestConditionAttribute> empty_attribute =
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebRequestConditionAttribute::Create(keys::kStagesKey,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &empty_list,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &error);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", error);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(empty_attribute.get());
28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(std::string(keys::kStagesKey), empty_attribute->GetName());
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create an attribute with all possible applicable stages.
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue all_stages;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(active_stages); ++i)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    all_stages.AppendString(active_stages[i].second);
29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const WebRequestConditionAttribute> attribute_with_all =
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebRequestConditionAttribute::Create(keys::kStagesKey,
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &all_stages,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &error);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", error);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(attribute_with_all.get());
29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(std::string(keys::kStagesKey), attribute_with_all->GetName());
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create one attribute for each single stage, to be applicable in that stage.
30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<scoped_refptr<const WebRequestConditionAttribute> >
30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      one_stage_attributes;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(active_stages); ++i) {
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::ListValue single_stage_list;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    single_stage_list.AppendString(active_stages[i].second);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    one_stage_attributes.push_back(
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        WebRequestConditionAttribute::Create(keys::kStagesKey,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             &single_stage_list,
31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                             &error));
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("", error);
313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_TRUE(one_stage_attributes.back().get() != NULL);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url_empty;
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLRequestContext context;
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestDelegate delegate;
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<net::URLRequest> url_request(
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      context.CreateRequest(url_empty, net::DEFAULT_PRIORITY, &delegate, NULL));
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(active_stages); ++i) {
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(empty_attribute->IsFulfilled(
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        WebRequestData(url_request.get(), active_stages[i].first)));
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t j = 0; j < one_stage_attributes.size(); ++j) {
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(i == j,
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                one_stage_attributes[j]->IsFulfilled(
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    WebRequestData(url_request.get(), active_stages[i].first)));
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(attribute_with_all->IsFulfilled(
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        WebRequestData(url_request.get(), active_stages[i].first)));
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Builds a vector of vectors of string pointers from an array of strings.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |array| is in fact a sequence of arrays. The array |sizes| captures the sizes
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of all parts of |array|, and |size| is the length of |sizes| itself.
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example (this is pseudo-code, not C++):
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// array = { "a", "b", "c", "d", "e", "f" }
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sizes = { 2, 0, 4 }
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// size = 3
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// results in out == { {&"a", &"b"}, {}, {&"c", &"d", &"e", &"f"} }
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetArrayAsVector(const std::string array[],
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const size_t sizes[],
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const size_t size,
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      std::vector< std::vector<const std::string*> >* out) {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out->clear();
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t next = 0;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < size; ++i) {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out->push_back(std::vector<const std::string*>());
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t j = next; j < next + sizes[i]; ++j) {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      out->back().push_back(&(array[j]));
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    next += sizes[i];
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Builds a DictionaryValue from an array of the form {name1, value1, name2,
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// value2, ...}. Values for the same key are grouped in a ListValue.
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_ptr<base::DictionaryValue> GetDictionaryFromArray(
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<const std::string*>& array) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t length = array.size();
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(length % 2 == 0);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < length; i += 2) {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string* name = array[i];
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string* value = array[i+1];
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (dictionary->HasKey(*name)) {
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Value* entry = NULL;
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_ptr<base::Value> entry_owned;
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::ListValue* list = NULL;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!dictionary->GetWithoutPathExpansion(*name, &entry))
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return scoped_ptr<base::DictionaryValue>();
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switch (entry->GetType()) {
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        case base::Value::TYPE_STRING:
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          // Replace the present string with a list.
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          list = new base::ListValue;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Ignoring return value, we already verified the entry is there.
3843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          dictionary->RemoveWithoutPathExpansion(*name, &entry_owned);
3853240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          list->Append(entry_owned.release());
3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          list->Append(new base::StringValue(*value));
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          dictionary->SetWithoutPathExpansion(*name, list);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        case base::Value::TYPE_LIST:  // Just append to the list.
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          CHECK(entry->GetAsList(&list));
3913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          list->Append(new base::StringValue(*value));
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        default:
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          NOTREACHED();  // We never put other Values here.
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          return scoped_ptr<base::DictionaryValue>();
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dictionary->SetString(*name, *value);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return dictionary.Pass();
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns whether the response headers from |url_request| satisfy the match
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// criteria given in |tests|. For at least one |i| all tests from |tests[i]|
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// must pass. If |positive_test| is true, the dictionary is interpreted as the
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// containsHeaders property of a RequestMatcher, otherwise as
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// doesNotContainHeaders.
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MatchAndCheck(const std::vector< std::vector<const std::string*> >& tests,
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const std::string& key,
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   RequestStage stage,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   net::URLRequest* url_request,
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   bool* result) {
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue contains_headers;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < tests.size(); ++i) {
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<base::DictionaryValue> temp(GetDictionaryFromArray(tests[i]));
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(temp.get());
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    contains_headers.Append(temp.release());
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
42290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const WebRequestConditionAttribute> attribute =
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebRequestConditionAttribute::Create(key, &contains_headers, &error);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ("", error);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(attribute.get());
42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(key, attribute->GetName());
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *result = attribute->IsFulfilled(WebRequestData(
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url_request, stage, url_request->response_headers()));
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Here we test WebRequestConditionAttributeRequestHeaders for matching
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// correctly against request headers. This test is not as extensive as
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "ResponseHeaders" (below), because the header-matching code is shared
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// by both types of condition attributes, so it is enough to test it once.
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WebRequestConditionAttributeTest, RequestHeaders) {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Necessary for TestURLRequest.
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoopForIO message_loop;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLRequestContext context;
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestDelegate delegate;
4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<net::URLRequest> url_request(
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      context.CreateRequest(GURL("http://example.com"),  // Dummy URL.
4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            net::DEFAULT_PRIORITY,
4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            &delegate,
4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            NULL));
4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  url_request->SetExtraRequestHeaderByName(
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Custom-header", "custom/value", true /* overwrite */);
4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  url_request->Start();
45290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::vector<const std::string*> > tests;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = false;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const RequestStage stage = ON_BEFORE_SEND_HEADERS;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First set of test data -- passing conjunction.
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kPassingCondition[] = {
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameContainsKey, "CuStOm",  // Header names are case insensitive.
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameEqualsKey, "custom-header",
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueSuffixKey, "alue",
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValuePrefixKey, "custom/value"
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kPassingConditionSizes[] = { arraysize(kPassingCondition) };
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(kPassingCondition, kPassingConditionSizes, 1u, &tests);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Positive filter, passing (conjunction of tests).
4691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(
4701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      tests, keys::kRequestHeadersKey, stage, url_request.get(), &result);
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negative filter, failing (conjunction of tests).
4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kExcludeRequestHeadersKey, stage,
4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                url_request.get(), &result);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(result);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second set of test data -- failing disjunction.
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kFailCondition[] = {
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameSuffixKey, "Custom",      // Test 1.
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameEqualsKey, "ustom-valu",  // Test 2.
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValuePrefixKey, "custom ",    // Test 3.
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueContainsKey, " value"    // Test 4.
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kFailConditionSizes[] = { 2u, 2u, 2u, 2u };
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(kFailCondition, kFailConditionSizes, 4u, &tests);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Positive filter, failing (disjunction of tests).
4871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kRequestHeadersKey, stage, url_request.get(),
4881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                &result);
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(result);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negative filter, passing (disjunction of tests).
4911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kExcludeRequestHeadersKey, stage,
4921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                url_request.get(), &result);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Third set of test data, corner case -- empty disjunction.
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(NULL, NULL, 0u, &tests);
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Positive filter, failing (no test to pass).
4981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kRequestHeadersKey, stage, url_request.get(),
4991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                &result);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(result);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negative filter, passing (no test to fail).
5021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kExcludeRequestHeadersKey, stage,
5031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                url_request.get(), &result);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fourth set of test data, corner case -- empty conjunction.
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kEmptyConjunctionSizes[] = { 0u };
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(NULL, kEmptyConjunctionSizes, 1u, &tests);
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Positive filter, passing (trivial test).
5101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kRequestHeadersKey, stage, url_request.get(),
5111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                &result);
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negative filter, failing.
5141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kExcludeRequestHeadersKey, stage,
5151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                url_request.get(), &result);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(result);
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Here we test WebRequestConditionAttributeResponseHeaders for:
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1. Correct implementation of prefix/suffix/contains/equals matching.
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2. Performing logical disjunction (||) between multiple specifications.
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3. Negating the match in case of 'doesNotContainHeaders'.
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WebRequestConditionAttributeTest, ResponseHeaders) {
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Necessary for TestURLRequest.
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoopForIO message_loop;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::test_server::EmbeddedTestServer test_server;
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  test_server.ServeFilesFromDirectory(TestDataPath(
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "chrome/test/data/extensions/api_test/webrequest/declarative"));
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_server.InitializeAndWaitUntilReady());
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLRequestContext context;
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestDelegate delegate;
5341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<net::URLRequest> url_request(
5351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      context.CreateRequest(test_server.GetURL("/headers.html"),
5361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            net::DEFAULT_PRIORITY,
5371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            &delegate,
5381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            NULL));
5391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  url_request->Start();
54090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In all the tests below we assume that the server includes the headers
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Custom-Header: custom/value
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Custom-Header-B: valueA
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Custom-Header-B: valueB
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Custom-Header-C: valueC, valueD
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Custom-Header-D:
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the response, but does not include "Non-existing: void".
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector< std::vector<const std::string*> > tests;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const RequestStage stage = ON_HEADERS_RECEIVED;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1.a. -- All these tests should pass.
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kPassingCondition[] = {
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNamePrefixKey, "Custom",
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameSuffixKey, "m-header",  // Header names are case insensitive.
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueContainsKey, "alu",
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueEqualsKey, "custom/value"
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kPassingConditionSizes[] = { arraysize(kPassingCondition) };
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(kPassingCondition, kPassingConditionSizes, 1u, &tests);
5641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kResponseHeadersKey, stage, url_request.get(),
5651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                &result);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1.b. -- None of the following tests in the discjunction should pass.
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kFailCondition[] = {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNamePrefixKey, " Custom",  // Test 1.
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameContainsKey, " -",     // Test 2.
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueSuffixKey, "alu",     // Test 3.
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueEqualsKey, "custom"   // Test 4.
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kFailConditionSizes[] = { 2u, 2u, 2u, 2u };
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(kFailCondition, kFailConditionSizes, 4u, &tests);
5771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kResponseHeadersKey, stage, url_request.get(),
5781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                &result);
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(result);
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1.c. -- This should fail (mixing name and value from different headers)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kMixingCondition[] = {
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameSuffixKey, "Header-B",
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueEqualsKey, "custom/value"
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kMixingConditionSizes[] = { arraysize(kMixingCondition) };
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(kMixingCondition, kMixingConditionSizes, 1u, &tests);
5881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kResponseHeadersKey, stage, url_request.get(),
5891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                &result);
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(result);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1.d. -- Test handling multiple values for one header (both should pass).
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kMoreValues1[] = {
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameEqualsKey, "Custom-header-b",
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueEqualsKey, "valueA"
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kMoreValues1Sizes[] = { arraysize(kMoreValues1) };
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(kMoreValues1, kMoreValues1Sizes, 1u, &tests);
5991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kResponseHeadersKey, stage, url_request.get(),
6001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                &result);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kMoreValues2[] = {
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameEqualsKey, "Custom-header-b",
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueEqualsKey, "valueB"
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kMoreValues2Sizes[] = { arraysize(kMoreValues2) };
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(kMoreValues2, kMoreValues2Sizes, 1u, &tests);
6081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kResponseHeadersKey, stage, url_request.get(),
6091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                &result);
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1.e. -- This should fail as conjunction but pass as disjunction.
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kConflict[] = {
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameSuffixKey, "Header",      // True for some header.
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameContainsKey, "Header-B"   // True for a different header.
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First disjunction, no conflict.
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kNoConflictSizes[] = { 2u, 2u };
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(kConflict, kNoConflictSizes, 2u, &tests);
6201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kResponseHeadersKey, stage, url_request.get(),
6211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                &result);
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then conjunction, conflict.
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kConflictSizes[] = { arraysize(kConflict) };
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(kConflict, kConflictSizes, 1u, &tests);
6261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kResponseHeadersKey, stage, url_request.get(),
6271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                &result);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(result);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1.f. -- This should pass, checking for correct treatment of ',' in values.
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kComma[] = {
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameSuffixKey, "Header-C",
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueEqualsKey, "valueC, valueD"
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kCommaSizes[] = { arraysize(kComma) };
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(kComma, kCommaSizes, 1u, &tests);
6371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kResponseHeadersKey, stage, url_request.get(),
6381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                &result);
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1.g. -- This should pass, empty values are values as well.
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kEmpty[] = {
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameEqualsKey, "custom-header-d",
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueEqualsKey, ""
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kEmptySizes[] = { arraysize(kEmpty) };
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(kEmpty, kEmptySizes, 1u, &tests);
6481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kResponseHeadersKey, stage, url_request.get(),
6491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                &result);
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1.h. -- Values are case-sensitive, this should fail.
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kLowercase[] = {
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameEqualsKey, "Custom-header-b",
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValuePrefixKey, "valueb",  // valueb != valueB
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameEqualsKey, "Custom-header-b",
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueSuffixKey, "valueb",
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameEqualsKey, "Custom-header-b",
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueContainsKey, "valueb",
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameEqualsKey, "Custom-header-b",
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueEqualsKey, "valueb"
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kLowercaseSizes[] = { 4u, 4u, 4u, 4u };  // As disjunction.
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(kLowercase, kLowercaseSizes, 4u, &tests);
6651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kResponseHeadersKey, stage, url_request.get(),
6661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                &result);
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(result);
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1.i. -- Names are case-insensitive, this should pass.
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kUppercase[] = {
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNamePrefixKey, "CUSTOM-HEADER-B",
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameSuffixKey, "CUSTOM-HEADER-B",
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameEqualsKey, "CUSTOM-HEADER-B",
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameContainsKey, "CUSTOM-HEADER-B"
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kUppercaseSizes[] = { arraysize(kUppercase) };  // Conjunction.
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(kUppercase, kUppercaseSizes, 1u, &tests);
6781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kResponseHeadersKey, stage, url_request.get(),
6791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                &result);
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2.a. -- This should pass as disjunction, because one of the tests passes.
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kDisjunction[] = {
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNamePrefixKey, "Non-existing",  // This one fails.
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameSuffixKey, "Non-existing",  // This one fails.
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueEqualsKey, "void",         // This one fails.
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueContainsKey, "alu"         // This passes.
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kDisjunctionSizes[] = { 2u, 2u, 2u, 2u };
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(kDisjunction, kDisjunctionSizes, 4u, &tests);
6911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kResponseHeadersKey, stage, url_request.get(),
6921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                &result);
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3.a. -- This should pass.
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kNonExistent[] = {
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameEqualsKey, "Non-existing",
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueEqualsKey, "void"
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kNonExistentSizes[] = { arraysize(kNonExistent) };
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(kNonExistent, kNonExistentSizes, 1u, &tests);
7021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kExcludeResponseHeadersKey, stage,
7031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                url_request.get(), &result);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(result);
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3.b. -- This should fail.
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kExisting[] = {
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kNameEqualsKey, "custom-header-b",
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys::kValueEqualsKey, "valueB"
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kExistingSize[] = { arraysize(kExisting) };
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetArrayAsVector(kExisting, kExistingSize, 1u, &tests);
7131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MatchAndCheck(tests, keys::kExcludeResponseHeadersKey, stage,
7141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                url_request.get(), &result);
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(result);
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
720