Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / declarative_webrequest / webrequest_condition_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h"
6
7 #include <set>
8
9 #include "base/message_loop/message_loop.h"
10 #include "base/test/values_test_util.h"
11 #include "base/values.h"
12 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h"
13 #include "components/url_matcher/url_matcher_constants.h"
14 #include "content/public/browser/resource_request_info.h"
15 #include "net/base/request_priority.h"
16 #include "net/url_request/url_request_test_util.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 using content::ResourceType;
20 using url_matcher::URLMatcher;
21 using url_matcher::URLMatcherConditionSet;
22
23 namespace extensions {
24
25 TEST(WebRequestConditionTest, CreateCondition) {
26   // Necessary for TestURLRequest.
27   base::MessageLoopForIO message_loop;
28   URLMatcher matcher;
29
30   std::string error;
31   scoped_ptr<WebRequestCondition> result;
32
33   // Test wrong condition name passed.
34   error.clear();
35   result = WebRequestCondition::Create(
36       NULL,
37       matcher.condition_factory(),
38       *base::test::ParseJson(
39            "{ \"invalid\": \"foobar\", \n"
40            "  \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n"
41            "}"),
42       &error);
43   EXPECT_FALSE(error.empty());
44   EXPECT_FALSE(result.get());
45
46   // Test wrong datatype in host_suffix.
47   error.clear();
48   result = WebRequestCondition::Create(
49       NULL,
50       matcher.condition_factory(),
51       *base::test::ParseJson(
52            "{ \n"
53            "  \"url\": [], \n"
54            "  \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n"
55            "}"),
56       &error);
57   EXPECT_FALSE(error.empty());
58   EXPECT_FALSE(result.get());
59
60   // Test success (can we support multiple criteria?)
61   error.clear();
62   result = WebRequestCondition::Create(
63       NULL,
64       matcher.condition_factory(),
65       *base::test::ParseJson(
66            "{ \n"
67            "  \"resourceType\": [\"main_frame\"], \n"
68            "  \"url\": { \"hostSuffix\": \"example.com\" }, \n"
69            "  \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n"
70            "}"),
71       &error);
72   EXPECT_EQ("", error);
73   ASSERT_TRUE(result.get());
74
75   URLMatcherConditionSet::Vector url_matcher_condition_set;
76   result->GetURLMatcherConditionSets(&url_matcher_condition_set);
77   matcher.AddConditionSets(url_matcher_condition_set);
78
79   net::TestURLRequestContext context;
80   const GURL http_url("http://www.example.com");
81   net::TestURLRequest match_request(
82       http_url, net::DEFAULT_PRIORITY, NULL, &context);
83   WebRequestData data(&match_request, ON_BEFORE_REQUEST);
84   WebRequestDataWithMatchIds request_data(&data);
85   request_data.url_match_ids = matcher.MatchURL(http_url);
86   EXPECT_EQ(1u, request_data.url_match_ids.size());
87   content::ResourceRequestInfo::AllocateForTesting(
88       &match_request,
89       content::RESOURCE_TYPE_MAIN_FRAME,
90       NULL,
91       -1,
92       -1,
93       -1,
94       false);
95   EXPECT_TRUE(result->IsFulfilled(request_data));
96
97   const GURL https_url("https://www.example.com");
98   net::TestURLRequest wrong_resource_type(
99       https_url, net::DEFAULT_PRIORITY, NULL, &context);
100   data.request = &wrong_resource_type;
101   request_data.url_match_ids = matcher.MatchURL(http_url);
102   // Make sure IsFulfilled does not fail because of URL matching.
103   EXPECT_EQ(1u, request_data.url_match_ids.size());
104   content::ResourceRequestInfo::AllocateForTesting(
105       &wrong_resource_type,
106       content::RESOURCE_TYPE_SUB_FRAME,
107       NULL,
108       -1,
109       -1,
110       -1,
111       false);
112   EXPECT_FALSE(result->IsFulfilled(request_data));
113 }
114
115 TEST(WebRequestConditionTest, CreateConditionFirstPartyForCookies) {
116   // Necessary for TestURLRequest.
117   base::MessageLoopForIO message_loop;
118   URLMatcher matcher;
119
120   std::string error;
121   scoped_ptr<WebRequestCondition> result;
122
123   result = WebRequestCondition::Create(
124       NULL,
125       matcher.condition_factory(),
126       *base::test::ParseJson(
127            "{ \n"
128            "  \"firstPartyForCookiesUrl\": { \"hostPrefix\": \"fpfc\"}, \n"
129            "  \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n"
130            "}"),
131       &error);
132   EXPECT_EQ("", error);
133   ASSERT_TRUE(result.get());
134
135   URLMatcherConditionSet::Vector url_matcher_condition_set;
136   result->GetURLMatcherConditionSets(&url_matcher_condition_set);
137   matcher.AddConditionSets(url_matcher_condition_set);
138
139   net::TestURLRequestContext context;
140   const GURL http_url("http://www.example.com");
141   const GURL first_party_url("http://fpfc.example.com");
142   net::TestURLRequest match_request(
143       http_url, net::DEFAULT_PRIORITY, NULL, &context);
144   WebRequestData data(&match_request, ON_BEFORE_REQUEST);
145   WebRequestDataWithMatchIds request_data(&data);
146   request_data.url_match_ids = matcher.MatchURL(http_url);
147   EXPECT_EQ(0u, request_data.url_match_ids.size());
148   request_data.first_party_url_match_ids = matcher.MatchURL(first_party_url);
149   EXPECT_EQ(1u, request_data.first_party_url_match_ids.size());
150   content::ResourceRequestInfo::AllocateForTesting(
151       &match_request,
152       content::RESOURCE_TYPE_MAIN_FRAME,
153       NULL,
154       -1,
155       -1,
156       -1,
157       false);
158   EXPECT_TRUE(result->IsFulfilled(request_data));
159 }
160
161 // Conditions without UrlFilter attributes need to be independent of URL
162 // matching results. We test here that:
163 //   1. A non-empty condition without UrlFilter attributes is fulfilled iff its
164 //      attributes are fulfilled.
165 //   2. An empty condition (in particular, without UrlFilter attributes) is
166 //      always fulfilled.
167 TEST(WebRequestConditionTest, NoUrlAttributes) {
168   // Necessary for TestURLRequest.
169   base::MessageLoopForIO message_loop;
170   URLMatcher matcher;
171   std::string error;
172
173   // The empty condition.
174   error.clear();
175   scoped_ptr<WebRequestCondition> condition_empty = WebRequestCondition::Create(
176       NULL,
177       matcher.condition_factory(),
178       *base::test::ParseJson(
179            "{ \n"
180            "  \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n"
181            "}"),
182       &error);
183   EXPECT_EQ("", error);
184   ASSERT_TRUE(condition_empty.get());
185
186   // A condition without a UrlFilter attribute, which is always true.
187   error.clear();
188   scoped_ptr<WebRequestCondition> condition_no_url_true =
189       WebRequestCondition::Create(
190           NULL,
191           matcher.condition_factory(),
192           *base::test::ParseJson(
193                "{ \n"
194                "  \"instanceType\": \"declarativeWebRequest.RequestMatcher\", "
195                "\n"
196                // There is no "1st party for cookies" URL in the requests below,
197                // therefore all requests are considered first party for cookies.
198                "  \"thirdPartyForCookies\": false, \n"
199                "}"),
200           &error);
201   EXPECT_EQ("", error);
202   ASSERT_TRUE(condition_no_url_true.get());
203
204   // A condition without a UrlFilter attribute, which is always false.
205   error.clear();
206   scoped_ptr<WebRequestCondition> condition_no_url_false =
207       WebRequestCondition::Create(
208           NULL,
209           matcher.condition_factory(),
210           *base::test::ParseJson(
211                "{ \n"
212                "  \"instanceType\": \"declarativeWebRequest.RequestMatcher\", "
213                "\n"
214                "  \"thirdPartyForCookies\": true, \n"
215                "}"),
216           &error);
217   EXPECT_EQ("", error);
218   ASSERT_TRUE(condition_no_url_false.get());
219
220   net::TestURLRequestContext context;
221   net::TestURLRequest https_request(
222       GURL("https://www.example.com"), net::DEFAULT_PRIORITY, NULL, &context);
223
224   // 1. A non-empty condition without UrlFilter attributes is fulfilled iff its
225   //    attributes are fulfilled.
226   WebRequestData data(&https_request, ON_BEFORE_REQUEST);
227   EXPECT_FALSE(
228       condition_no_url_false->IsFulfilled(WebRequestDataWithMatchIds(&data)));
229
230   data = WebRequestData(&https_request, ON_BEFORE_REQUEST);
231   EXPECT_TRUE(
232       condition_no_url_true->IsFulfilled(WebRequestDataWithMatchIds(&data)));
233
234   // 2. An empty condition (in particular, without UrlFilter attributes) is
235   //    always fulfilled.
236   data = WebRequestData(&https_request, ON_BEFORE_REQUEST);
237   EXPECT_TRUE(condition_empty->IsFulfilled(WebRequestDataWithMatchIds(&data)));
238 }
239
240 TEST(WebRequestConditionTest, CreateConditionSet) {
241   // Necessary for TestURLRequest.
242   base::MessageLoopForIO message_loop;
243   URLMatcher matcher;
244
245   WebRequestConditionSet::AnyVector conditions;
246   conditions.push_back(linked_ptr<base::Value>(base::test::ParseJson(
247       "{ \n"
248       "  \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n"
249       "  \"url\": { \n"
250       "    \"hostSuffix\": \"example.com\", \n"
251       "    \"schemes\": [\"http\"], \n"
252       "  }, \n"
253       "}").release()));
254   conditions.push_back(linked_ptr<base::Value>(base::test::ParseJson(
255       "{ \n"
256       "  \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n"
257       "  \"url\": { \n"
258       "    \"hostSuffix\": \"example.com\", \n"
259       "    \"hostPrefix\": \"www\", \n"
260       "    \"schemes\": [\"https\"], \n"
261       "  }, \n"
262       "}").release()));
263
264   // Test insertion
265   std::string error;
266   scoped_ptr<WebRequestConditionSet> result = WebRequestConditionSet::Create(
267       NULL, matcher.condition_factory(), conditions, &error);
268   EXPECT_EQ("", error);
269   ASSERT_TRUE(result.get());
270   EXPECT_EQ(2u, result->conditions().size());
271
272   // Tell the URLMatcher about our shiny new patterns.
273   URLMatcherConditionSet::Vector url_matcher_condition_set;
274   result->GetURLMatcherConditionSets(&url_matcher_condition_set);
275   matcher.AddConditionSets(url_matcher_condition_set);
276
277   // Test that the result is correct and matches http://www.example.com and
278   // https://www.example.com
279   GURL http_url("http://www.example.com");
280   net::TestURLRequestContext context;
281   net::TestURLRequest http_request(
282       http_url, net::DEFAULT_PRIORITY, NULL, &context);
283   WebRequestData data(&http_request, ON_BEFORE_REQUEST);
284   WebRequestDataWithMatchIds request_data(&data);
285   request_data.url_match_ids = matcher.MatchURL(http_url);
286   EXPECT_EQ(1u, request_data.url_match_ids.size());
287   EXPECT_TRUE(result->IsFulfilled(*(request_data.url_match_ids.begin()),
288                                   request_data));
289
290   GURL https_url("https://www.example.com");
291   request_data.url_match_ids = matcher.MatchURL(https_url);
292   EXPECT_EQ(1u, request_data.url_match_ids.size());
293   net::TestURLRequest https_request(
294       https_url, net::DEFAULT_PRIORITY, NULL, &context);
295   data.request = &https_request;
296   EXPECT_TRUE(result->IsFulfilled(*(request_data.url_match_ids.begin()),
297                                   request_data));
298
299   // Check that both, hostPrefix and hostSuffix are evaluated.
300   GURL https_foo_url("https://foo.example.com");
301   request_data.url_match_ids = matcher.MatchURL(https_foo_url);
302   EXPECT_EQ(0u, request_data.url_match_ids.size());
303   net::TestURLRequest https_foo_request(
304       https_foo_url, net::DEFAULT_PRIORITY, NULL, &context);
305   data.request = &https_foo_request;
306   EXPECT_FALSE(result->IsFulfilled(-1, request_data));
307 }
308
309 TEST(WebRequestConditionTest, TestPortFilter) {
310   // Necessary for TestURLRequest.
311   base::MessageLoopForIO message_loop;
312   URLMatcher matcher;
313
314   WebRequestConditionSet::AnyVector conditions;
315   conditions.push_back(linked_ptr<base::Value>(base::test::ParseJson(
316       "{ \n"
317       "  \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n"
318       "  \"url\": { \n"
319       "    \"ports\": [80, [1000, 1010]], \n"  // Allow 80;1000-1010.
320       "    \"hostSuffix\": \"example.com\", \n"
321       "  }, \n"
322       "}").release()));
323
324   // Test insertion
325   std::string error;
326   scoped_ptr<WebRequestConditionSet> result = WebRequestConditionSet::Create(
327       NULL, matcher.condition_factory(), conditions, &error);
328   EXPECT_EQ("", error);
329   ASSERT_TRUE(result.get());
330   EXPECT_EQ(1u, result->conditions().size());
331
332   // Tell the URLMatcher about our shiny new patterns.
333   URLMatcherConditionSet::Vector url_matcher_condition_set;
334   result->GetURLMatcherConditionSets(&url_matcher_condition_set);
335   matcher.AddConditionSets(url_matcher_condition_set);
336
337   std::set<URLMatcherConditionSet::ID> url_match_ids;
338
339   // Test various URLs.
340   GURL http_url("http://www.example.com");
341   net::TestURLRequestContext context;
342   net::TestURLRequest http_request(
343       http_url, net::DEFAULT_PRIORITY, NULL, &context);
344   url_match_ids = matcher.MatchURL(http_url);
345   ASSERT_EQ(1u, url_match_ids.size());
346
347   GURL http_url_80("http://www.example.com:80");
348   net::TestURLRequest http_request_80(
349       http_url_80, net::DEFAULT_PRIORITY, NULL, &context);
350   url_match_ids = matcher.MatchURL(http_url_80);
351   ASSERT_EQ(1u, url_match_ids.size());
352
353   GURL http_url_1000("http://www.example.com:1000");
354   net::TestURLRequest http_request_1000(
355       http_url_1000, net::DEFAULT_PRIORITY, NULL, &context);
356   url_match_ids = matcher.MatchURL(http_url_1000);
357   ASSERT_EQ(1u, url_match_ids.size());
358
359   GURL http_url_2000("http://www.example.com:2000");
360   net::TestURLRequest http_request_2000(
361       http_url_2000, net::DEFAULT_PRIORITY, NULL, &context);
362   url_match_ids = matcher.MatchURL(http_url_2000);
363   ASSERT_EQ(0u, url_match_ids.size());
364 }
365
366 // Create a condition with two attributes: one on the request header and one on
367 // the response header. The Create() method should fail and complain that it is
368 // impossible that both conditions are fulfilled at the same time.
369 TEST(WebRequestConditionTest, ConditionsWithConflictingStages) {
370   // Necessary for TestURLRequest.
371   base::MessageLoopForIO message_loop;
372   URLMatcher matcher;
373
374   std::string error;
375   scoped_ptr<WebRequestCondition> result;
376
377   // Test error on incompatible application stages for involved attributes.
378   error.clear();
379   result = WebRequestCondition::Create(
380       NULL,
381       matcher.condition_factory(),
382       *base::test::ParseJson(
383            "{ \n"
384            "  \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n"
385            // Pass a JS array with one empty object to each of the header
386            // filters.
387            "  \"requestHeaders\": [{}], \n"
388            "  \"responseHeaders\": [{}], \n"
389            "}"),
390       &error);
391   EXPECT_FALSE(error.empty());
392   EXPECT_FALSE(result.get());
393 }
394
395 }  // namespace extensions