blob: 7ee962d767581d03477d530277f3ddafb8da7363 [file] [log] [blame]
// 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 "extensions/browser/extension_creator_filter.h"
#include <stddef.h>
#include <memory>
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/stl_util.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
#if defined(OS_WIN)
#include <windows.h>
#endif
namespace {
class ExtensionCreatorFilterTest : public PlatformTest {
protected:
void SetUp() override {
PlatformTest::SetUp();
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
extension_dir_ = temp_dir_.GetPath();
filter_ = base::MakeRefCounted<extensions::ExtensionCreatorFilter>(
extension_dir_);
}
base::FilePath CreateTestFile(const base::FilePath& file_path) {
return CreateRelativeFilePath(file_path);
}
// Creates an empty file with the given relative path. Creates parent
// directories if needed.
base::FilePath CreateRelativeFilePath(
const base::FilePath& relative_file_path) {
base::FilePath path = extension_dir_.Append(relative_file_path);
EXPECT_TRUE(base::CreateDirectory(path.DirName()));
std::string contents = "test";
EXPECT_EQ(static_cast<int>(contents.size()),
base::WriteFile(path, contents.c_str(), contents.size()));
return path;
}
base::FilePath CreateTestFileInDir(
const base::FilePath::StringType& file_name,
const base::FilePath::StringType& dir) {
return CreateRelativeFilePath(base::FilePath(dir).Append(file_name));
}
scoped_refptr<extensions::ExtensionCreatorFilter> filter_;
base::ScopedTempDir temp_dir_;
base::FilePath extension_dir_;
};
struct UnaryBooleanTestData {
const base::FilePath::CharType* input;
bool expected;
};
TEST_F(ExtensionCreatorFilterTest, NormalCases) {
const struct UnaryBooleanTestData cases[] = {
{FILE_PATH_LITERAL("foo"), true},
{FILE_PATH_LITERAL(".foo"), false},
{FILE_PATH_LITERAL("~foo"), true},
{FILE_PATH_LITERAL("foo~"), false},
{FILE_PATH_LITERAL("#foo"), true},
{FILE_PATH_LITERAL("foo#"), true},
{FILE_PATH_LITERAL("#foo#"), false},
{FILE_PATH_LITERAL(".svn"), false},
{FILE_PATH_LITERAL("__MACOSX"), false},
{FILE_PATH_LITERAL(".DS_Store"), false},
{FILE_PATH_LITERAL("desktop.ini"), false},
{FILE_PATH_LITERAL("Thumbs.db"), false},
};
for (size_t i = 0; i < base::size(cases); ++i) {
base::FilePath input(cases[i].input);
base::FilePath test_file(CreateTestFile(input));
bool observed = filter_->ShouldPackageFile(test_file);
EXPECT_EQ(cases[i].expected, observed)
<< "i: " << i << ", input: " << test_file.value();
}
}
TEST_F(ExtensionCreatorFilterTest, MetadataFolderExcluded) {
const struct UnaryBooleanTestData cases[] = {
{FILE_PATH_LITERAL("_metadata/foo"), false},
{FILE_PATH_LITERAL("_metadata/abc/foo"), false},
{FILE_PATH_LITERAL("_metadata/abc/xyz/foo"), false},
{FILE_PATH_LITERAL("abc/_metadata/xyz"), true},
{FILE_PATH_LITERAL("xyz/_metadata"), true},
};
// Create and test the filepaths.
for (size_t i = 0; i < base::size(cases); ++i) {
base::FilePath test_file =
CreateRelativeFilePath(base::FilePath(cases[i].input));
bool observed = filter_->ShouldPackageFile(test_file);
EXPECT_EQ(cases[i].expected, observed)
<< "i: " << i << ", input: " << test_file.value();
}
// Also test directories.
const struct UnaryBooleanTestData directory_cases[] = {
{FILE_PATH_LITERAL("_metadata"), false},
{FILE_PATH_LITERAL("_metadata/abc"), false},
{FILE_PATH_LITERAL("_metadata/abc/xyz"), false},
{FILE_PATH_LITERAL("abc"), true},
{FILE_PATH_LITERAL("abc/_metadata"), true},
{FILE_PATH_LITERAL("xyz"), true},
};
for (size_t i = 0; i < base::size(directory_cases); ++i) {
base::FilePath directory = extension_dir_.Append(directory_cases[i].input);
bool observed = filter_->ShouldPackageFile(directory);
EXPECT_EQ(directory_cases[i].expected, observed)
<< "i: " << i << ", input: " << directory.value();
}
}
struct StringStringWithBooleanTestData {
const base::FilePath::StringType file_name;
const base::FilePath::StringType dir;
bool expected;
};
// Ignore the files in special directories, including ".git", ".svn",
// "__MACOSX".
TEST_F(ExtensionCreatorFilterTest, IgnoreFilesInSpecialDir) {
const struct StringStringWithBooleanTestData cases[] = {
{FILE_PATH_LITERAL("foo"), FILE_PATH_LITERAL(".git"), false},
{FILE_PATH_LITERAL("goo"), FILE_PATH_LITERAL(".svn"), false},
{FILE_PATH_LITERAL("foo"), FILE_PATH_LITERAL("__MACOSX"), false},
{FILE_PATH_LITERAL("foo"), FILE_PATH_LITERAL("foo"), true},
{FILE_PATH_LITERAL("index.js"), FILE_PATH_LITERAL("scripts"), true},
};
for (size_t i = 0; i < base::size(cases); ++i) {
base::FilePath test_file(
CreateTestFileInDir(cases[i].file_name, cases[i].dir));
bool observed = filter_->ShouldPackageFile(test_file);
EXPECT_EQ(cases[i].expected, observed)
<< "i: " << i << ", input: " << test_file.value();
}
}
#if defined(OS_WIN)
struct StringBooleanWithBooleanTestData {
const base::FilePath::CharType* input_char;
bool input_bool;
bool expected;
};
TEST_F(ExtensionCreatorFilterTest, WindowsHiddenFiles) {
const struct StringBooleanWithBooleanTestData cases[] = {
{FILE_PATH_LITERAL("a-normal-file"), false, true},
{FILE_PATH_LITERAL(".a-dot-file"), false, false},
{FILE_PATH_LITERAL(".a-dot-file-that-we-have-set-to-hidden"), true,
false},
{FILE_PATH_LITERAL("a-file-that-we-have-set-to-hidden"), true, false},
{FILE_PATH_LITERAL("a-file-that-we-have-not-set-to-hidden"), false, true},
};
for (size_t i = 0; i < base::size(cases); ++i) {
base::FilePath input(cases[i].input_char);
bool should_hide = cases[i].input_bool;
base::FilePath test_file(CreateTestFile(input));
if (should_hide) {
SetFileAttributes(test_file.value().c_str(), FILE_ATTRIBUTE_HIDDEN);
}
bool observed = filter_->ShouldPackageFile(test_file);
EXPECT_EQ(cases[i].expected, observed)
<< "i: " << i << ", input: " << test_file.value();
}
}
#endif
} // namespace