1// Copyright 2013 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 "base/basictypes.h"
6#include "base/files/file_path.h"
7#include "base/pickle.h"
8#include "extensions/common/user_script.h"
9#include "testing/gtest/include/gtest/gtest.h"
10#include "url/gurl.h"
11
12namespace extensions {
13
14static const int kAllSchemes =
15    URLPattern::SCHEME_HTTP |
16    URLPattern::SCHEME_HTTPS |
17    URLPattern::SCHEME_FILE |
18    URLPattern::SCHEME_FTP |
19    URLPattern::SCHEME_CHROMEUI;
20
21TEST(ExtensionUserScriptTest, Glob_HostString) {
22  UserScript script;
23  script.add_glob("*mail.google.com*");
24  script.add_glob("*mail.yahoo.com*");
25  script.add_glob("*mail.msn.com*");
26  EXPECT_TRUE(script.MatchesURL(GURL("http://mail.google.com")));
27  EXPECT_TRUE(script.MatchesURL(GURL("http://mail.google.com/foo")));
28  EXPECT_TRUE(script.MatchesURL(GURL("https://mail.google.com/foo")));
29  EXPECT_TRUE(script.MatchesURL(GURL("ftp://mail.google.com/foo")));
30  EXPECT_TRUE(script.MatchesURL(GURL("http://woo.mail.google.com/foo")));
31  EXPECT_TRUE(script.MatchesURL(GURL("http://mail.yahoo.com/bar")));
32  EXPECT_TRUE(script.MatchesURL(GURL("http://mail.msn.com/baz")));
33  EXPECT_FALSE(script.MatchesURL(GURL("http://www.hotmail.com")));
34
35  script.add_exclude_glob("*foo*");
36  EXPECT_TRUE(script.MatchesURL(GURL("http://mail.google.com")));
37  EXPECT_FALSE(script.MatchesURL(GURL("http://mail.google.com/foo")));
38}
39
40TEST(ExtensionUserScriptTest, Glob_TrailingSlash) {
41  UserScript script;
42  script.add_glob("*mail.google.com/");
43  // GURL normalizes the URL to have a trailing "/"
44  EXPECT_TRUE(script.MatchesURL(GURL("http://mail.google.com")));
45  EXPECT_TRUE(script.MatchesURL(GURL("http://mail.google.com/")));
46  EXPECT_FALSE(script.MatchesURL(GURL("http://mail.google.com/foo")));
47}
48
49TEST(ExtensionUserScriptTest, Glob_TrailingSlashStar) {
50  UserScript script;
51  script.add_glob("http://mail.google.com/*");
52  // GURL normalizes the URL to have a trailing "/"
53  EXPECT_TRUE(script.MatchesURL(GURL("http://mail.google.com")));
54  EXPECT_TRUE(script.MatchesURL(GURL("http://mail.google.com/foo")));
55  EXPECT_FALSE(script.MatchesURL(GURL("https://mail.google.com/foo")));
56}
57
58TEST(ExtensionUserScriptTest, Glob_Star) {
59  UserScript script;
60  script.add_glob("*");
61  EXPECT_TRUE(script.MatchesURL(GURL("http://foo.com/bar")));
62  EXPECT_TRUE(script.MatchesURL(GURL("http://hot.com/dog")));
63  EXPECT_TRUE(script.MatchesURL(GURL("https://hot.com/dog")));
64  EXPECT_TRUE(script.MatchesURL(GURL("file:///foo/bar")));
65  EXPECT_TRUE(script.MatchesURL(GURL("file://localhost/foo/bar")));
66}
67
68TEST(ExtensionUserScriptTest, Glob_StringAnywhere) {
69  UserScript script;
70  script.add_glob("*foo*");
71  EXPECT_TRUE(script.MatchesURL(GURL("http://foo.com/bar")));
72  EXPECT_TRUE(script.MatchesURL(GURL("http://baz.org/foo/bar")));
73  EXPECT_FALSE(script.MatchesURL(GURL("http://baz.org")));
74}
75
76TEST(ExtensionUserScriptTest, UrlPattern) {
77  URLPattern pattern(kAllSchemes);
78  ASSERT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("http://*/foo*"));
79
80  UserScript script;
81  script.add_url_pattern(pattern);
82  EXPECT_TRUE(script.MatchesURL(GURL("http://monkey.com/foobar")));
83  EXPECT_FALSE(script.MatchesURL(GURL("http://monkey.com/hotdog")));
84
85  // NOTE: URLPattern is tested more extensively in url_pattern_unittest.cc.
86}
87
88TEST(ExtensionUserScriptTest, ExcludeUrlPattern) {
89  UserScript script;
90
91  URLPattern pattern(kAllSchemes);
92  ASSERT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("http://*.nytimes.com/*"));
93  script.add_url_pattern(pattern);
94
95  URLPattern exclude(kAllSchemes);
96  ASSERT_EQ(URLPattern::PARSE_SUCCESS, exclude.Parse("*://*/*business*"));
97  script.add_exclude_url_pattern(exclude);
98
99  EXPECT_TRUE(script.MatchesURL(GURL("http://www.nytimes.com/health")));
100  EXPECT_FALSE(script.MatchesURL(GURL("http://www.nytimes.com/business")));
101  EXPECT_TRUE(script.MatchesURL(GURL("http://business.nytimes.com")));
102}
103
104TEST(ExtensionUserScriptTest, UrlPatternAndIncludeGlobs) {
105  UserScript script;
106
107  URLPattern pattern(kAllSchemes);
108  ASSERT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("http://*.nytimes.com/*"));
109  script.add_url_pattern(pattern);
110
111  script.add_glob("*nytimes.com/???s/*");
112
113  EXPECT_TRUE(script.MatchesURL(GURL("http://www.nytimes.com/arts/1.html")));
114  EXPECT_TRUE(script.MatchesURL(GURL("http://www.nytimes.com/jobs/1.html")));
115  EXPECT_FALSE(script.MatchesURL(GURL("http://www.nytimes.com/sports/1.html")));
116}
117
118TEST(ExtensionUserScriptTest, UrlPatternAndExcludeGlobs) {
119  UserScript script;
120
121  URLPattern pattern(kAllSchemes);
122  ASSERT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("http://*.nytimes.com/*"));
123  script.add_url_pattern(pattern);
124
125  script.add_exclude_glob("*science*");
126
127  EXPECT_TRUE(script.MatchesURL(GURL("http://www.nytimes.com")));
128  EXPECT_FALSE(script.MatchesURL(GURL("http://science.nytimes.com")));
129  EXPECT_FALSE(script.MatchesURL(GURL("http://www.nytimes.com/science")));
130}
131
132TEST(ExtensionUserScriptTest, UrlPatternGlobInteraction) {
133  // If there are both, match intersection(union(globs), union(urlpatterns)).
134  UserScript script;
135
136  URLPattern pattern(kAllSchemes);
137  ASSERT_EQ(URLPattern::PARSE_SUCCESS,
138            pattern.Parse("http://www.google.com/*"));
139  script.add_url_pattern(pattern);
140
141  script.add_glob("*bar*");
142
143  // No match, because it doesn't match the glob.
144  EXPECT_FALSE(script.MatchesURL(GURL("http://www.google.com/foo")));
145
146  script.add_exclude_glob("*baz*");
147
148  // No match, because it matches the exclude glob.
149  EXPECT_FALSE(script.MatchesURL(GURL("http://www.google.com/baz")));
150
151  // Match, because it matches the glob, doesn't match the exclude glob.
152  EXPECT_TRUE(script.MatchesURL(GURL("http://www.google.com/bar")));
153
154  // Try with just a single exclude glob.
155  script.clear_globs();
156  EXPECT_TRUE(script.MatchesURL(GURL("http://www.google.com/foo")));
157
158  // Try with no globs or exclude globs.
159  script.clear_exclude_globs();
160  EXPECT_TRUE(script.MatchesURL(GURL("http://www.google.com/foo")));
161}
162
163TEST(ExtensionUserScriptTest, Pickle) {
164  URLPattern pattern1(kAllSchemes);
165  URLPattern pattern2(kAllSchemes);
166  URLPattern exclude1(kAllSchemes);
167  URLPattern exclude2(kAllSchemes);
168  ASSERT_EQ(URLPattern::PARSE_SUCCESS, pattern1.Parse("http://*/foo*"));
169  ASSERT_EQ(URLPattern::PARSE_SUCCESS, pattern2.Parse("http://bar/baz*"));
170  ASSERT_EQ(URLPattern::PARSE_SUCCESS, exclude1.Parse("*://*/*bar"));
171  ASSERT_EQ(URLPattern::PARSE_SUCCESS, exclude2.Parse("https://*/*"));
172
173  UserScript script1;
174  script1.js_scripts().push_back(UserScript::File(
175      base::FilePath(FILE_PATH_LITERAL("c:\\foo\\")),
176      base::FilePath(FILE_PATH_LITERAL("foo.user.js")),
177      GURL("chrome-extension://abc/foo.user.js")));
178  script1.css_scripts().push_back(UserScript::File(
179      base::FilePath(FILE_PATH_LITERAL("c:\\foo\\")),
180      base::FilePath(FILE_PATH_LITERAL("foo.user.css")),
181      GURL("chrome-extension://abc/foo.user.css")));
182  script1.css_scripts().push_back(UserScript::File(
183      base::FilePath(FILE_PATH_LITERAL("c:\\foo\\")),
184      base::FilePath(FILE_PATH_LITERAL("foo2.user.css")),
185      GURL("chrome-extension://abc/foo2.user.css")));
186  script1.set_run_location(UserScript::DOCUMENT_START);
187
188  script1.add_url_pattern(pattern1);
189  script1.add_url_pattern(pattern2);
190  script1.add_exclude_url_pattern(exclude1);
191  script1.add_exclude_url_pattern(exclude2);
192
193  const int64 kId = 12;
194  script1.set_id(kId);
195  const std::string kExtensionId = "foo";
196  script1.set_extension_id(kExtensionId);
197
198  Pickle pickle;
199  script1.Pickle(&pickle);
200
201  PickleIterator iter(pickle);
202  UserScript script2;
203  script2.Unpickle(pickle, &iter);
204
205  EXPECT_EQ(1U, script2.js_scripts().size());
206  EXPECT_EQ(script1.js_scripts()[0].url(), script2.js_scripts()[0].url());
207
208  EXPECT_EQ(2U, script2.css_scripts().size());
209  for (size_t i = 0; i < script2.js_scripts().size(); ++i) {
210    EXPECT_EQ(script1.css_scripts()[i].url(), script2.css_scripts()[i].url());
211  }
212
213  ASSERT_EQ(script1.globs().size(), script2.globs().size());
214  for (size_t i = 0; i < script1.globs().size(); ++i) {
215    EXPECT_EQ(script1.globs()[i], script2.globs()[i]);
216  }
217
218  ASSERT_EQ(script1.url_patterns(), script2.url_patterns());
219  ASSERT_EQ(script1.exclude_url_patterns(), script2.exclude_url_patterns());
220
221  EXPECT_EQ(kExtensionId, script2.extension_id());
222  EXPECT_EQ(kId, script2.id());
223}
224
225TEST(ExtensionUserScriptTest, Defaults) {
226  UserScript script;
227  ASSERT_EQ(UserScript::DOCUMENT_IDLE, script.run_location());
228}
229
230}  // namespace extensions
231