// Copyright (c) 2012 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/convert_user_script.h"

#include <memory>
#include <string>
#include <vector>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace extensions {

namespace {

static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
  int schemes = URLPattern::SCHEME_ALL;
  extent->AddPattern(URLPattern(schemes, pattern));
}

}

class ExtensionFromUserScript : public testing::Test {
};

TEST_F(ExtensionFromUserScript, Basic) {
  base::ScopedTempDir extensions_dir;
  ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());

  base::FilePath test_file;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
  test_file = test_file.AppendASCII("extensions")
                       .AppendASCII("user_script_basic.user.js");

  base::string16 error;
  scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
      test_file, GURL("http://www.google.com/foo"),
      extensions_dir.path(), &error));

  ASSERT_TRUE(extension.get());
  EXPECT_EQ(base::string16(), error);

  // Use a temp dir so that the extensions dir will clean itself up.
  base::ScopedTempDir ext_dir;
  EXPECT_TRUE(ext_dir.Set(extension->path()));

  // Validate generated extension metadata.
  EXPECT_EQ("My user script", extension->name());
  EXPECT_EQ("2.2.2", extension->VersionString());
  EXPECT_EQ("Does totally awesome stuff.", extension->description());
  EXPECT_EQ("IhCFCg9PMQTAcJdc9ytUP99WME+4yh6aMnM1uupkovo=",
            extension->public_key());
  EXPECT_EQ(Manifest::TYPE_USER_SCRIPT, extension->GetType());

  ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension.get()).size());
  const UserScript& script =
      ContentScriptsInfo::GetContentScripts(extension.get())[0];
  EXPECT_EQ(UserScript::DOCUMENT_IDLE, script.run_location());
  ASSERT_EQ(2u, script.globs().size());
  EXPECT_EQ("http://www.google.com/*", script.globs().at(0));
  EXPECT_EQ("http://www.yahoo.com/*", script.globs().at(1));
  ASSERT_EQ(1u, script.exclude_globs().size());
  EXPECT_EQ("*foo*", script.exclude_globs().at(0));
  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());
  EXPECT_TRUE(script.emulate_greasemonkey());

  // Make sure the files actually exist on disk.
  EXPECT_TRUE(base::PathExists(
      extension->path().Append(script.js_scripts()[0].relative_path())));
  EXPECT_TRUE(base::PathExists(
      extension->path().Append(kManifestFilename)));
}

TEST_F(ExtensionFromUserScript, NoMetadata) {
  base::ScopedTempDir extensions_dir;
  ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());

  base::FilePath test_file;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
  test_file = test_file.AppendASCII("extensions")
                       .AppendASCII("user_script_no_metadata.user.js");

  base::string16 error;
  scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
      test_file, GURL("http://www.google.com/foo/bar.user.js?monkey"),
      extensions_dir.path(), &error));

  ASSERT_TRUE(extension.get());
  EXPECT_EQ(base::string16(), error);

  // Use a temp dir so that the extensions dir will clean itself up.
  base::ScopedTempDir ext_dir;
  EXPECT_TRUE(ext_dir.Set(extension->path()));

  // Validate generated extension metadata.
  EXPECT_EQ("bar.user.js", extension->name());
  EXPECT_EQ("1.0", extension->VersionString());
  EXPECT_EQ("", extension->description());
  EXPECT_EQ("k1WxKx54hX6tfl5gQaXD/m4d9QUMwRdXWM4RW+QkWcY=",
            extension->public_key());
  EXPECT_EQ(Manifest::TYPE_USER_SCRIPT, extension->GetType());

  ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension.get()).size());
  const UserScript& script =
      ContentScriptsInfo::GetContentScripts(extension.get())[0];
  ASSERT_EQ(1u, script.globs().size());
  EXPECT_EQ("*", script.globs()[0]);
  EXPECT_EQ(0u, script.exclude_globs().size());
  EXPECT_TRUE(script.emulate_greasemonkey());

  URLPatternSet expected;
  AddPattern(&expected, "http://*/*");
  AddPattern(&expected, "https://*/*");
  EXPECT_EQ(expected, script.url_patterns());

  // Make sure the files actually exist on disk.
  EXPECT_TRUE(base::PathExists(
      extension->path().Append(script.js_scripts()[0].relative_path())));
  EXPECT_TRUE(base::PathExists(
      extension->path().Append(kManifestFilename)));
}

TEST_F(ExtensionFromUserScript, NotUTF8) {
  base::ScopedTempDir extensions_dir;
  ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());

  base::FilePath test_file;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
  test_file = test_file.AppendASCII("extensions")
                       .AppendASCII("user_script_not_utf8.user.js");

  base::string16 error;
  scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
      test_file, GURL("http://www.google.com/foo/bar.user.js?monkey"),
      extensions_dir.path(), &error));

  ASSERT_FALSE(extension.get());
  EXPECT_EQ(base::ASCIIToUTF16("User script must be UTF8 encoded."), error);
}

TEST_F(ExtensionFromUserScript, RunAtDocumentStart) {
  base::ScopedTempDir extensions_dir;
  ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());

  base::FilePath test_file;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
  test_file = test_file.AppendASCII("extensions")
                       .AppendASCII("user_script_run_at_start.user.js");

  base::string16 error;
  scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
      test_file, GURL("http://www.google.com/foo"),
      extensions_dir.path(), &error));

  ASSERT_TRUE(extension.get());
  EXPECT_EQ(base::string16(), error);

  // Use a temp dir so that the extensions dir will clean itself up.
  base::ScopedTempDir ext_dir;
  EXPECT_TRUE(ext_dir.Set(extension->path()));

  // Validate generated extension metadata.
  EXPECT_EQ("Document Start Test", extension->name());
  EXPECT_EQ("This script tests document-start", extension->description());
  EXPECT_EQ("RjmyI7+Gp/YHcW1qnu4xDxkJcL4cV4kTzdCA4BajCbk=",
            extension->public_key());
  EXPECT_EQ(Manifest::TYPE_USER_SCRIPT, extension->GetType());

  // Validate run location.
  ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension.get()).size());
  const UserScript& script =
      ContentScriptsInfo::GetContentScripts(extension.get())[0];
  EXPECT_EQ(UserScript::DOCUMENT_START, script.run_location());
}

TEST_F(ExtensionFromUserScript, RunAtDocumentEnd) {
  base::ScopedTempDir extensions_dir;
  ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());

  base::FilePath test_file;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
  test_file = test_file.AppendASCII("extensions")
                       .AppendASCII("user_script_run_at_end.user.js");

  base::string16 error;
  scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
      test_file, GURL("http://www.google.com/foo"),
      extensions_dir.path(), &error));

  ASSERT_TRUE(extension.get());
  EXPECT_EQ(base::string16(), error);

  // Use a temp dir so that the extensions dir will clean itself up.
  base::ScopedTempDir ext_dir;
  EXPECT_TRUE(ext_dir.Set(extension->path()));

  // Validate generated extension metadata.
  EXPECT_EQ("Document End Test", extension->name());
  EXPECT_EQ("This script tests document-end", extension->description());
  EXPECT_EQ("cpr5i8Mi24FzECV8UJe6tanwlU8SWesZosJ915YISvQ=",
            extension->public_key());
  EXPECT_EQ(Manifest::TYPE_USER_SCRIPT, extension->GetType());

  // Validate run location.
  ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension.get()).size());
  const UserScript& script =
      ContentScriptsInfo::GetContentScripts(extension.get())[0];
  EXPECT_EQ(UserScript::DOCUMENT_END, script.run_location());
}

TEST_F(ExtensionFromUserScript, RunAtDocumentIdle) {
  base::ScopedTempDir extensions_dir;
  ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());

  base::FilePath test_file;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
  test_file = test_file.AppendASCII("extensions")
                       .AppendASCII("user_script_run_at_idle.user.js");
  ASSERT_TRUE(base::PathExists(test_file)) << test_file.value();

  base::string16 error;
  scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
      test_file, GURL("http://www.google.com/foo"),
      extensions_dir.path(), &error));

  ASSERT_TRUE(extension.get());
  EXPECT_EQ(base::string16(), error);

  // Use a temp dir so that the extensions dir will clean itself up.
  base::ScopedTempDir ext_dir;
  EXPECT_TRUE(ext_dir.Set(extension->path()));

  // Validate generated extension metadata.
  EXPECT_EQ("Document Idle Test", extension->name());
  EXPECT_EQ("This script tests document-idle", extension->description());
  EXPECT_EQ("kHnHKec3O/RKKo5/Iu1hKqe4wQERthL0639isNtsfiY=",
            extension->public_key());
  EXPECT_EQ(Manifest::TYPE_USER_SCRIPT, extension->GetType());

  // Validate run location.
  ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension.get()).size());
  const UserScript& script =
      ContentScriptsInfo::GetContentScripts(extension.get())[0];
  EXPECT_EQ(UserScript::DOCUMENT_IDLE, script.run_location());
}

}  // namespace extensions
