Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1129)

Unified Diff: chrome/browser/extensions/extension_user_script_loader_unittest.cc

Issue 903743002: Revert of Revert of Introduce HostID and de-couple Extensions from "script injection System" [browser side] (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/extension_user_script_loader_unittest.cc
diff --git a/chrome/browser/extensions/extension_user_script_loader_unittest.cc b/chrome/browser/extensions/extension_user_script_loader_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..068dc6f4d15a7ceb9feb8178cf0f62629daa452f
--- /dev/null
+++ b/chrome/browser/extensions/extension_user_script_loader_unittest.cc
@@ -0,0 +1,276 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/extension_user_script_loader.h"
+
+#include <set>
+#include <string>
+
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/message_loop/message_loop.h"
+#include "base/strings/string_util.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/test/test_browser_thread.h"
+#include "extensions/common/host_id.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using content::BrowserThread;
+using extensions::URLPatternSet;
+
+namespace {
+
+static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
+ int schemes = URLPattern::SCHEME_ALL;
+ extent->AddPattern(URLPattern(schemes, pattern));
+}
+}
+
+namespace extensions {
+
+// Test bringing up a script loader on a specific directory, putting a script
+// in there, etc.
+
+class ExtensionUserScriptLoaderTest : public testing::Test,
+ public content::NotificationObserver {
+ public:
+ ExtensionUserScriptLoaderTest() : shared_memory_(NULL) {}
+
+ void SetUp() override {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+
+ // Register for all user script notifications.
+ registrar_.Add(this,
+ extensions::NOTIFICATION_USER_SCRIPTS_UPDATED,
+ content::NotificationService::AllSources());
+
+ // ExtensionUserScriptLoader posts tasks to the file thread so make the
+ // current thread look like one.
+ file_thread_.reset(new content::TestBrowserThread(
+ BrowserThread::FILE, base::MessageLoop::current()));
+ ui_thread_.reset(new content::TestBrowserThread(
+ BrowserThread::UI, base::MessageLoop::current()));
+ }
+
+ void TearDown() override {
+ file_thread_.reset();
+ ui_thread_.reset();
+ }
+
+ void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) override {
+ DCHECK(type == extensions::NOTIFICATION_USER_SCRIPTS_UPDATED);
+
+ shared_memory_ = content::Details<base::SharedMemory>(details).ptr();
+ if (base::MessageLoop::current() == &message_loop_)
+ base::MessageLoop::current()->Quit();
+ }
+
+ // Directory containing user scripts.
+ base::ScopedTempDir temp_dir_;
+
+ content::NotificationRegistrar registrar_;
+
+ // MessageLoop used in tests.
+ base::MessageLoopForUI message_loop_;
+
+ scoped_ptr<content::TestBrowserThread> file_thread_;
+ scoped_ptr<content::TestBrowserThread> ui_thread_;
+
+ // Updated to the script shared memory when we get notified.
+ base::SharedMemory* shared_memory_;
+};
+
+// Test that we get notified even when there are no scripts.
+TEST_F(ExtensionUserScriptLoaderTest, NoScripts) {
+ TestingProfile profile;
+ ExtensionUserScriptLoader loader(
+ &profile,
+ HostID(),
+ true /* listen_for_extension_system_loaded */);
+ loader.StartLoad();
+ message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
+ message_loop_.Run();
+
+ ASSERT_TRUE(shared_memory_ != NULL);
+}
+
+TEST_F(ExtensionUserScriptLoaderTest, Parse1) {
+ const std::string text(
+ "// This is my awesome script\n"
+ "// It does stuff.\n"
+ "// ==UserScript== trailing garbage\n"
+ "// @name foobar script\n"
+ "// @namespace http://www.google.com/\n"
+ "// @include *mail.google.com*\n"
+ "// \n"
+ "// @othergarbage\n"
+ "// @include *mail.yahoo.com*\r\n"
+ "// @include \t *mail.msn.com*\n" // extra spaces after "@include" OK
+ "//@include not-recognized\n" // must have one space after "//"
+ "// ==/UserScript== trailing garbage\n"
+ "\n"
+ "\n"
+ "alert('hoo!');\n");
+
+ UserScript script;
+ EXPECT_TRUE(ExtensionUserScriptLoader::ParseMetadataHeader(text, &script));
+ ASSERT_EQ(3U, script.globs().size());
+ EXPECT_EQ("*mail.google.com*", script.globs()[0]);
+ EXPECT_EQ("*mail.yahoo.com*", script.globs()[1]);
+ EXPECT_EQ("*mail.msn.com*", script.globs()[2]);
+}
+
+TEST_F(ExtensionUserScriptLoaderTest, Parse2) {
+ const std::string text("default to @include *");
+
+ UserScript script;
+ EXPECT_TRUE(ExtensionUserScriptLoader::ParseMetadataHeader(text, &script));
+ ASSERT_EQ(1U, script.globs().size());
+ EXPECT_EQ("*", script.globs()[0]);
+}
+
+TEST_F(ExtensionUserScriptLoaderTest, Parse3) {
+ const std::string text(
+ "// ==UserScript==\n"
+ "// @include *foo*\n"
+ "// ==/UserScript=="); // no trailing newline
+
+ UserScript script;
+ ExtensionUserScriptLoader::ParseMetadataHeader(text, &script);
+ ASSERT_EQ(1U, script.globs().size());
+ EXPECT_EQ("*foo*", script.globs()[0]);
+}
+
+TEST_F(ExtensionUserScriptLoaderTest, Parse4) {
+ const std::string text(
+ "// ==UserScript==\n"
+ "// @match http://*.mail.google.com/*\n"
+ "// @match \t http://mail.yahoo.com/*\n"
+ "// ==/UserScript==\n");
+
+ URLPatternSet expected_patterns;
+ AddPattern(&expected_patterns, "http://*.mail.google.com/*");
+ AddPattern(&expected_patterns, "http://mail.yahoo.com/*");
+
+ UserScript script;
+ EXPECT_TRUE(ExtensionUserScriptLoader::ParseMetadataHeader(text, &script));
+ EXPECT_EQ(0U, script.globs().size());
+ EXPECT_EQ(expected_patterns, script.url_patterns());
+}
+
+TEST_F(ExtensionUserScriptLoaderTest, Parse5) {
+ const std::string text(
+ "// ==UserScript==\n"
+ "// @match http://*mail.google.com/*\n"
+ "// ==/UserScript==\n");
+
+ // Invalid @match value.
+ UserScript script;
+ EXPECT_FALSE(ExtensionUserScriptLoader::ParseMetadataHeader(text, &script));
+}
+
+TEST_F(ExtensionUserScriptLoaderTest, Parse6) {
+ const std::string text(
+ "// ==UserScript==\n"
+ "// @include http://*.mail.google.com/*\n"
+ "// @match \t http://mail.yahoo.com/*\n"
+ "// ==/UserScript==\n");
+
+ // Allowed to match @include and @match.
+ UserScript script;
+ EXPECT_TRUE(ExtensionUserScriptLoader::ParseMetadataHeader(text, &script));
+}
+
+TEST_F(ExtensionUserScriptLoaderTest, Parse7) {
+ // Greasemonkey allows there to be any leading text before the comment marker.
+ const std::string text(
+ "// ==UserScript==\n"
+ "adsasdfasf// @name hello\n"
+ " // @description\twiggity woo\n"
+ "\t// @match \t http://mail.yahoo.com/*\n"
+ "// ==/UserScript==\n");
+
+ UserScript script;
+ EXPECT_TRUE(ExtensionUserScriptLoader::ParseMetadataHeader(text, &script));
+ ASSERT_EQ("hello", script.name());
+ ASSERT_EQ("wiggity woo", script.description());
+ ASSERT_EQ(1U, script.url_patterns().patterns().size());
+ EXPECT_EQ("http://mail.yahoo.com/*",
+ script.url_patterns().begin()->GetAsString());
+}
+
+TEST_F(ExtensionUserScriptLoaderTest, Parse8) {
+ const std::string text(
+ "// ==UserScript==\n"
+ "// @name myscript\n"
+ "// @match http://www.google.com/*\n"
+ "// @exclude_match http://www.google.com/foo*\n"
+ "// ==/UserScript==\n");
+
+ UserScript script;
+ EXPECT_TRUE(ExtensionUserScriptLoader::ParseMetadataHeader(text, &script));
+ ASSERT_EQ("myscript", script.name());
+ ASSERT_EQ(1U, script.url_patterns().patterns().size());
+ EXPECT_EQ("http://www.google.com/*",
+ script.url_patterns().begin()->GetAsString());
+ ASSERT_EQ(1U, script.exclude_url_patterns().patterns().size());
+ EXPECT_EQ("http://www.google.com/foo*",
+ script.exclude_url_patterns().begin()->GetAsString());
+}
+
+TEST_F(ExtensionUserScriptLoaderTest, SkipBOMAtTheBeginning) {
+ base::FilePath path = temp_dir_.path().AppendASCII("script.user.js");
+ const std::string content("\xEF\xBB\xBF alert('hello');");
+ size_t written = base::WriteFile(path, content.c_str(), content.size());
+ ASSERT_EQ(written, content.size());
+
+ UserScript user_script;
+ user_script.js_scripts().push_back(
+ UserScript::File(temp_dir_.path(), path.BaseName(), GURL()));
+
+ UserScriptList user_scripts;
+ user_scripts.push_back(user_script);
+
+ TestingProfile profile;
+ ExtensionUserScriptLoader loader(
+ &profile,
+ HostID(),
+ true /* listen_for_extension_system_loaded */);
+ loader.LoadScriptsForTest(&user_scripts);
+
+ EXPECT_EQ(content.substr(3),
+ user_scripts[0].js_scripts()[0].GetContent().as_string());
+}
+
+TEST_F(ExtensionUserScriptLoaderTest, LeaveBOMNotAtTheBeginning) {
+ base::FilePath path = temp_dir_.path().AppendASCII("script.user.js");
+ const std::string content("alert('here's a BOOM: \xEF\xBB\xBF');");
+ size_t written = base::WriteFile(path, content.c_str(), content.size());
+ ASSERT_EQ(written, content.size());
+
+ UserScript user_script;
+ user_script.js_scripts().push_back(UserScript::File(
+ temp_dir_.path(), path.BaseName(), GURL()));
+
+ UserScriptList user_scripts;
+ user_scripts.push_back(user_script);
+
+ TestingProfile profile;
+ ExtensionUserScriptLoader loader(
+ &profile,
+ HostID(),
+ true /* listen_for_extension_system_loaded */);
+ loader.LoadScriptsForTest(&user_scripts);
+
+ EXPECT_EQ(content, user_scripts[0].js_scripts()[0].GetContent().as_string());
+}
+
+} // namespace extensions
« no previous file with comments | « chrome/browser/extensions/extension_user_script_loader.cc ('k') | chrome/browser/extensions/shared_user_script_master.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698