summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/user_script_master_unittest.cc
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-07-29 17:14:53 +0100
committerBen Murdoch <benm@google.com>2010-08-04 14:29:45 +0100
commitc407dc5cd9bdc5668497f21b26b09d988ab439de (patch)
tree7eaf8707c0309516bdb042ad976feedaf72b0bb1 /chrome/browser/extensions/user_script_master_unittest.cc
parent0998b1cdac5733f299c12d88bc31ef9c8035b8fa (diff)
downloadexternal_chromium-c407dc5cd9bdc5668497f21b26b09d988ab439de.zip
external_chromium-c407dc5cd9bdc5668497f21b26b09d988ab439de.tar.gz
external_chromium-c407dc5cd9bdc5668497f21b26b09d988ab439de.tar.bz2
Merge Chromium src@r53293
Change-Id: Ia79acf8670f385cee48c45b0a75371d8e950af34
Diffstat (limited to 'chrome/browser/extensions/user_script_master_unittest.cc')
-rw-r--r--chrome/browser/extensions/user_script_master_unittest.cc264
1 files changed, 264 insertions, 0 deletions
diff --git a/chrome/browser/extensions/user_script_master_unittest.cc b/chrome/browser/extensions/user_script_master_unittest.cc
new file mode 100644
index 0000000..3760941
--- /dev/null
+++ b/chrome/browser/extensions/user_script_master_unittest.cc
@@ -0,0 +1,264 @@
+// Copyright (c) 2008 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/user_script_master.h"
+
+#include <string>
+
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/message_loop.h"
+#include "base/path_service.h"
+#include "base/string_util.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/common/notification_registrar.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/test/testing_profile.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// Test bringing up a master on a specific directory, putting a script
+// in there, etc.
+
+class UserScriptMasterTest : public testing::Test,
+ public NotificationObserver {
+ public:
+ UserScriptMasterTest()
+ : message_loop_(MessageLoop::TYPE_UI),
+ shared_memory_(NULL) {
+ }
+
+ virtual void SetUp() {
+ // Name a subdirectory of the temp directory.
+ FilePath tmp_dir;
+ ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &tmp_dir));
+ script_dir_ = tmp_dir.AppendASCII("UserScriptTest");
+
+ // Create a fresh, empty copy of this directory.
+ file_util::Delete(script_dir_, true);
+ file_util::CreateDirectory(script_dir_);
+
+ // Register for all user script notifications.
+ registrar_.Add(this, NotificationType::USER_SCRIPTS_UPDATED,
+ NotificationService::AllSources());
+
+ // UserScriptMaster posts tasks to the file thread so make the current
+ // thread look like one.
+ file_thread_.reset(new ChromeThread(
+ ChromeThread::FILE, MessageLoop::current()));
+ }
+
+ virtual void TearDown() {
+ // Clean up test directory.
+ ASSERT_TRUE(file_util::Delete(script_dir_, true));
+ ASSERT_FALSE(file_util::PathExists(script_dir_));
+ file_thread_.reset();
+ }
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(type == NotificationType::USER_SCRIPTS_UPDATED);
+
+ shared_memory_ = Details<base::SharedMemory>(details).ptr();
+ if (MessageLoop::current() == &message_loop_)
+ MessageLoop::current()->Quit();
+ }
+
+ NotificationRegistrar registrar_;
+
+ // MessageLoop used in tests.
+ MessageLoop message_loop_;
+
+ scoped_ptr<ChromeThread> file_thread_;
+
+ // Directory containing user scripts.
+ FilePath script_dir_;
+
+ // 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(UserScriptMasterTest, NoScripts) {
+ TestingProfile profile;
+ scoped_refptr<UserScriptMaster> master(new UserScriptMaster(script_dir_,
+ &profile));
+ master->StartScan();
+ message_loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask);
+ message_loop_.Run();
+
+ ASSERT_TRUE(shared_memory_ != NULL);
+}
+
+// Test that we get notified about scripts if they're already in the test dir.
+TEST_F(UserScriptMasterTest, ExistingScripts) {
+ TestingProfile profile;
+ FilePath path = script_dir_.AppendASCII("script.user.js");
+
+ const char content[] = "some content";
+ size_t written = file_util::WriteFile(path, content, sizeof(content));
+ ASSERT_EQ(written, sizeof(content));
+
+ scoped_refptr<UserScriptMaster> master(new UserScriptMaster(script_dir_,
+ &profile));
+ master->StartScan();
+
+ message_loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask);
+ message_loop_.Run();
+
+ ASSERT_TRUE(shared_memory_ != NULL);
+}
+
+TEST_F(UserScriptMasterTest, 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(UserScriptMaster::ScriptReloader::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(UserScriptMasterTest, Parse2) {
+ const std::string text("default to @include *");
+
+ UserScript script;
+ EXPECT_TRUE(UserScriptMaster::ScriptReloader::ParseMetadataHeader(
+ text, &script));
+ ASSERT_EQ(1U, script.globs().size());
+ EXPECT_EQ("*", script.globs()[0]);
+}
+
+TEST_F(UserScriptMasterTest, Parse3) {
+ const std::string text(
+ "// ==UserScript==\n"
+ "// @include *foo*\n"
+ "// ==/UserScript=="); // no trailing newline
+
+ UserScript script;
+ UserScriptMaster::ScriptReloader::ParseMetadataHeader(text, &script);
+ ASSERT_EQ(1U, script.globs().size());
+ EXPECT_EQ("*foo*", script.globs()[0]);
+}
+
+TEST_F(UserScriptMasterTest, Parse4) {
+ const std::string text(
+ "// ==UserScript==\n"
+ "// @match http://*.mail.google.com/*\n"
+ "// @match \t http://mail.yahoo.com/*\n"
+ "// ==/UserScript==\n");
+
+ UserScript script;
+ EXPECT_TRUE(UserScriptMaster::ScriptReloader::ParseMetadataHeader(
+ text, &script));
+ EXPECT_EQ(0U, script.globs().size());
+ ASSERT_EQ(2U, script.url_patterns().size());
+ EXPECT_EQ("http://*.mail.google.com/*",
+ script.url_patterns()[0].GetAsString());
+ EXPECT_EQ("http://mail.yahoo.com/*",
+ script.url_patterns()[1].GetAsString());
+}
+
+TEST_F(UserScriptMasterTest, Parse5) {
+ const std::string text(
+ "// ==UserScript==\n"
+ "// @match http://*mail.google.com/*\n"
+ "// ==/UserScript==\n");
+
+ // Invalid @match value.
+ UserScript script;
+ EXPECT_FALSE(UserScriptMaster::ScriptReloader::ParseMetadataHeader(
+ text, &script));
+}
+
+TEST_F(UserScriptMasterTest, 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(UserScriptMaster::ScriptReloader::ParseMetadataHeader(
+ text, &script));
+}
+
+TEST_F(UserScriptMasterTest, 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(UserScriptMaster::ScriptReloader::ParseMetadataHeader(
+ text, &script));
+ ASSERT_EQ("hello", script.name());
+ ASSERT_EQ("wiggity woo", script.description());
+ ASSERT_EQ(1U, script.url_patterns().size());
+ EXPECT_EQ("http://mail.yahoo.com/*",
+ script.url_patterns()[0].GetAsString());
+}
+
+TEST_F(UserScriptMasterTest, SkipBOMAtTheBeginning) {
+ FilePath path = script_dir_.AppendASCII("script.user.js");
+
+ const std::string content(
+ "\xEF\xBB\xBF// ==UserScript==\n"
+ "// @match http://*.mail.google.com/*\n"
+ "// ==/UserScript==\n");
+ size_t written = file_util::WriteFile(path, content.c_str(), content.size());
+ ASSERT_EQ(written, content.size());
+
+ UserScriptList script_list;
+ UserScriptMaster::ScriptReloader::LoadScriptsFromDirectory(
+ script_dir_, &script_list);
+ ASSERT_EQ(1U, script_list.size());
+
+ EXPECT_EQ(content.substr(3),
+ script_list[0].js_scripts()[0].GetContent().as_string());
+ EXPECT_EQ("http://*.mail.google.com/*",
+ script_list[0].url_patterns()[0].GetAsString());
+}
+
+TEST_F(UserScriptMasterTest, LeaveBOMNotAtTheBeginning) {
+ FilePath path = script_dir_.AppendASCII("script.user.js");
+
+ const std::string content(
+ "// ==UserScript==\n"
+ "// @match http://*.mail.google.com/*\n"
+ "// ==/UserScript==\n"
+ "// @bom \xEF\xBB\xBF");
+ size_t written = file_util::WriteFile(path, content.c_str(), content.size());
+ ASSERT_EQ(written, content.size());
+
+ UserScriptList script_list;
+ UserScriptMaster::ScriptReloader::LoadScriptsFromDirectory(
+ script_dir_, &script_list);
+ ASSERT_EQ(1U, script_list.size());
+
+ EXPECT_EQ(content, script_list[0].js_scripts()[0].GetContent().as_string());
+ EXPECT_EQ("http://*.mail.google.com/*",
+ script_list[0].url_patterns()[0].GetAsString());
+}