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