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 <string>
6 #include <vector>
7
8 #include "base/file_util.h"
9 #include "base/files/file_path.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/path_service.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/extensions/convert_user_script.h"
15 #include "chrome/common/chrome_paths.h"
16 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
17 #include "extensions/common/constants.h"
18 #include "extensions/common/extension.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace extensions {
22
23 namespace {
24
AddPattern(URLPatternSet * extent,const std::string & pattern)25 static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
26 int schemes = URLPattern::SCHEME_ALL;
27 extent->AddPattern(URLPattern(schemes, pattern));
28 }
29
30 }
31
32 class ExtensionFromUserScript : public testing::Test {
33 };
34
TEST_F(ExtensionFromUserScript,Basic)35 TEST_F(ExtensionFromUserScript, Basic) {
36 base::ScopedTempDir extensions_dir;
37 ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
38
39 base::FilePath test_file;
40 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
41 test_file = test_file.AppendASCII("extensions")
42 .AppendASCII("user_script_basic.user.js");
43
44 base::string16 error;
45 scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
46 test_file, GURL("http://www.google.com/foo"),
47 extensions_dir.path(), &error));
48
49 ASSERT_TRUE(extension.get());
50 EXPECT_EQ(base::string16(), error);
51
52 // Use a temp dir so that the extensions dir will clean itself up.
53 base::ScopedTempDir ext_dir;
54 EXPECT_TRUE(ext_dir.Set(extension->path()));
55
56 // Validate generated extension metadata.
57 EXPECT_EQ("My user script", extension->name());
58 EXPECT_EQ("2.2.2", extension->VersionString());
59 EXPECT_EQ("Does totally awesome stuff.", extension->description());
60 EXPECT_EQ("IhCFCg9PMQTAcJdc9ytUP99WME+4yh6aMnM1uupkovo=",
61 extension->public_key());
62 EXPECT_EQ(Manifest::TYPE_USER_SCRIPT, extension->GetType());
63
64 ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension.get()).size());
65 const UserScript& script =
66 ContentScriptsInfo::GetContentScripts(extension.get())[0];
67 EXPECT_EQ(UserScript::DOCUMENT_IDLE, script.run_location());
68 ASSERT_EQ(2u, script.globs().size());
69 EXPECT_EQ("http://www.google.com/*", script.globs().at(0));
70 EXPECT_EQ("http://www.yahoo.com/*", script.globs().at(1));
71 ASSERT_EQ(1u, script.exclude_globs().size());
72 EXPECT_EQ("*foo*", script.exclude_globs().at(0));
73 ASSERT_EQ(1u, script.url_patterns().patterns().size());
74 EXPECT_EQ("http://www.google.com/*",
75 script.url_patterns().begin()->GetAsString());
76 ASSERT_EQ(1u, script.exclude_url_patterns().patterns().size());
77 EXPECT_EQ("http://www.google.com/foo*",
78 script.exclude_url_patterns().begin()->GetAsString());
79 EXPECT_TRUE(script.emulate_greasemonkey());
80
81 // Make sure the files actually exist on disk.
82 EXPECT_TRUE(base::PathExists(
83 extension->path().Append(script.js_scripts()[0].relative_path())));
84 EXPECT_TRUE(base::PathExists(
85 extension->path().Append(kManifestFilename)));
86 }
87
TEST_F(ExtensionFromUserScript,NoMetadata)88 TEST_F(ExtensionFromUserScript, NoMetadata) {
89 base::ScopedTempDir extensions_dir;
90 ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
91
92 base::FilePath test_file;
93 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
94 test_file = test_file.AppendASCII("extensions")
95 .AppendASCII("user_script_no_metadata.user.js");
96
97 base::string16 error;
98 scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
99 test_file, GURL("http://www.google.com/foo/bar.user.js?monkey"),
100 extensions_dir.path(), &error));
101
102 ASSERT_TRUE(extension.get());
103 EXPECT_EQ(base::string16(), error);
104
105 // Use a temp dir so that the extensions dir will clean itself up.
106 base::ScopedTempDir ext_dir;
107 EXPECT_TRUE(ext_dir.Set(extension->path()));
108
109 // Validate generated extension metadata.
110 EXPECT_EQ("bar.user.js", extension->name());
111 EXPECT_EQ("1.0", extension->VersionString());
112 EXPECT_EQ("", extension->description());
113 EXPECT_EQ("k1WxKx54hX6tfl5gQaXD/m4d9QUMwRdXWM4RW+QkWcY=",
114 extension->public_key());
115 EXPECT_EQ(Manifest::TYPE_USER_SCRIPT, extension->GetType());
116
117 ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension.get()).size());
118 const UserScript& script =
119 ContentScriptsInfo::GetContentScripts(extension.get())[0];
120 ASSERT_EQ(1u, script.globs().size());
121 EXPECT_EQ("*", script.globs()[0]);
122 EXPECT_EQ(0u, script.exclude_globs().size());
123 EXPECT_TRUE(script.emulate_greasemonkey());
124
125 URLPatternSet expected;
126 AddPattern(&expected, "http://*/*");
127 AddPattern(&expected, "https://*/*");
128 EXPECT_EQ(expected, script.url_patterns());
129
130 // Make sure the files actually exist on disk.
131 EXPECT_TRUE(base::PathExists(
132 extension->path().Append(script.js_scripts()[0].relative_path())));
133 EXPECT_TRUE(base::PathExists(
134 extension->path().Append(kManifestFilename)));
135 }
136
TEST_F(ExtensionFromUserScript,NotUTF8)137 TEST_F(ExtensionFromUserScript, NotUTF8) {
138 base::ScopedTempDir extensions_dir;
139 ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
140
141 base::FilePath test_file;
142 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
143 test_file = test_file.AppendASCII("extensions")
144 .AppendASCII("user_script_not_utf8.user.js");
145
146 base::string16 error;
147 scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
148 test_file, GURL("http://www.google.com/foo/bar.user.js?monkey"),
149 extensions_dir.path(), &error));
150
151 ASSERT_FALSE(extension.get());
152 EXPECT_EQ(base::ASCIIToUTF16("User script must be UTF8 encoded."), error);
153 }
154
TEST_F(ExtensionFromUserScript,RunAtDocumentStart)155 TEST_F(ExtensionFromUserScript, RunAtDocumentStart) {
156 base::ScopedTempDir extensions_dir;
157 ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
158
159 base::FilePath test_file;
160 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
161 test_file = test_file.AppendASCII("extensions")
162 .AppendASCII("user_script_run_at_start.user.js");
163
164 base::string16 error;
165 scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
166 test_file, GURL("http://www.google.com/foo"),
167 extensions_dir.path(), &error));
168
169 ASSERT_TRUE(extension.get());
170 EXPECT_EQ(base::string16(), error);
171
172 // Use a temp dir so that the extensions dir will clean itself up.
173 base::ScopedTempDir ext_dir;
174 EXPECT_TRUE(ext_dir.Set(extension->path()));
175
176 // Validate generated extension metadata.
177 EXPECT_EQ("Document Start Test", extension->name());
178 EXPECT_EQ("This script tests document-start", extension->description());
179 EXPECT_EQ("RjmyI7+Gp/YHcW1qnu4xDxkJcL4cV4kTzdCA4BajCbk=",
180 extension->public_key());
181 EXPECT_EQ(Manifest::TYPE_USER_SCRIPT, extension->GetType());
182
183 // Validate run location.
184 ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension.get()).size());
185 const UserScript& script =
186 ContentScriptsInfo::GetContentScripts(extension.get())[0];
187 EXPECT_EQ(UserScript::DOCUMENT_START, script.run_location());
188 }
189
TEST_F(ExtensionFromUserScript,RunAtDocumentEnd)190 TEST_F(ExtensionFromUserScript, RunAtDocumentEnd) {
191 base::ScopedTempDir extensions_dir;
192 ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
193
194 base::FilePath test_file;
195 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
196 test_file = test_file.AppendASCII("extensions")
197 .AppendASCII("user_script_run_at_end.user.js");
198
199 base::string16 error;
200 scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
201 test_file, GURL("http://www.google.com/foo"),
202 extensions_dir.path(), &error));
203
204 ASSERT_TRUE(extension.get());
205 EXPECT_EQ(base::string16(), error);
206
207 // Use a temp dir so that the extensions dir will clean itself up.
208 base::ScopedTempDir ext_dir;
209 EXPECT_TRUE(ext_dir.Set(extension->path()));
210
211 // Validate generated extension metadata.
212 EXPECT_EQ("Document End Test", extension->name());
213 EXPECT_EQ("This script tests document-end", extension->description());
214 EXPECT_EQ("cpr5i8Mi24FzECV8UJe6tanwlU8SWesZosJ915YISvQ=",
215 extension->public_key());
216 EXPECT_EQ(Manifest::TYPE_USER_SCRIPT, extension->GetType());
217
218 // Validate run location.
219 ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension.get()).size());
220 const UserScript& script =
221 ContentScriptsInfo::GetContentScripts(extension.get())[0];
222 EXPECT_EQ(UserScript::DOCUMENT_END, script.run_location());
223 }
224
TEST_F(ExtensionFromUserScript,RunAtDocumentIdle)225 TEST_F(ExtensionFromUserScript, RunAtDocumentIdle) {
226 base::ScopedTempDir extensions_dir;
227 ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());
228
229 base::FilePath test_file;
230 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
231 test_file = test_file.AppendASCII("extensions")
232 .AppendASCII("user_script_run_at_idle.user.js");
233 ASSERT_TRUE(base::PathExists(test_file)) << test_file.value();
234
235 base::string16 error;
236 scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
237 test_file, GURL("http://www.google.com/foo"),
238 extensions_dir.path(), &error));
239
240 ASSERT_TRUE(extension.get());
241 EXPECT_EQ(base::string16(), error);
242
243 // Use a temp dir so that the extensions dir will clean itself up.
244 base::ScopedTempDir ext_dir;
245 EXPECT_TRUE(ext_dir.Set(extension->path()));
246
247 // Validate generated extension metadata.
248 EXPECT_EQ("Document Idle Test", extension->name());
249 EXPECT_EQ("This script tests document-idle", extension->description());
250 EXPECT_EQ("kHnHKec3O/RKKo5/Iu1hKqe4wQERthL0639isNtsfiY=",
251 extension->public_key());
252 EXPECT_EQ(Manifest::TYPE_USER_SCRIPT, extension->GetType());
253
254 // Validate run location.
255 ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension.get()).size());
256 const UserScript& script =
257 ContentScriptsInfo::GetContentScripts(extension.get())[0];
258 EXPECT_EQ(UserScript::DOCUMENT_IDLE, script.run_location());
259 }
260
261 } // namespace extensions
262