[email protected] | f9a4c41a | 2012-05-30 00:05:32 | [diff] [blame] | 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 | |
avi | 6846aef | 2015-12-26 01:09:38 | [diff] [blame] | 5 | #include <stddef.h> |
| 6 | |
jsbell | 0d496dc | 2016-10-28 22:23:57 | [diff] [blame] | 7 | #include <vector> |
| 8 | |
erikchen | 22de64a3 | 2014-10-10 18:27:43 | [diff] [blame] | 9 | #include "base/command_line.h" |
| 10 | #include "base/files/file_path.h" |
| 11 | #include "base/files/file_util.h" |
| 12 | #include "base/files/scoped_temp_dir.h" |
erikchen | 22de64a3 | 2014-10-10 18:27:43 | [diff] [blame] | 13 | #include "base/path_service.h" |
| 14 | #include "base/process/launch.h" |
Avi Drissman | 5f0fb8c | 2018-12-25 23:20:49 | [diff] [blame] | 15 | #include "base/stl_util.h" |
avi | 6846aef | 2015-12-26 01:09:38 | [diff] [blame] | 16 | #include "build/build_config.h" |
[email protected] | f9a4c41a | 2012-05-30 00:05:32 | [diff] [blame] | 17 | #include "chrome/browser/file_select_helper.h" |
erikchen | 22de64a3 | 2014-10-10 18:27:43 | [diff] [blame] | 18 | #include "chrome/common/chrome_paths.h" |
jsbell | 0d496dc | 2016-10-28 22:23:57 | [diff] [blame] | 19 | #include "chrome/test/base/testing_profile.h" |
| 20 | #include "content/public/test/test_browser_thread_bundle.h" |
[email protected] | f9a4c41a | 2012-05-30 00:05:32 | [diff] [blame] | 21 | #include "testing/gtest/include/gtest/gtest.h" |
| 22 | |
Kent Tamura | c260c9a | 2018-09-14 09:10:56 | [diff] [blame] | 23 | using blink::mojom::FileChooserParams; |
jsbell | 0d496dc | 2016-10-28 22:23:57 | [diff] [blame] | 24 | |
erikchen | 22de64a3 | 2014-10-10 18:27:43 | [diff] [blame] | 25 | class FileSelectHelperTest : public testing::Test { |
| 26 | public: |
| 27 | FileSelectHelperTest() {} |
| 28 | |
| 29 | protected: |
dcheng | e1bc798 | 2014-10-30 00:32:40 | [diff] [blame] | 30 | void SetUp() override { |
Avi Drissman | 9098f900 | 2018-05-04 00:11:52 | [diff] [blame] | 31 | ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &data_dir_)); |
erikchen | 22de64a3 | 2014-10-10 18:27:43 | [diff] [blame] | 32 | data_dir_ = data_dir_.AppendASCII("file_select_helper"); |
| 33 | ASSERT_TRUE(base::PathExists(data_dir_)); |
| 34 | } |
| 35 | |
| 36 | // The path to input data used in tests. |
| 37 | base::FilePath data_dir_; |
| 38 | |
| 39 | private: |
| 40 | DISALLOW_COPY_AND_ASSIGN(FileSelectHelperTest); |
| 41 | }; |
| 42 | |
| 43 | TEST_F(FileSelectHelperTest, IsAcceptTypeValid) { |
[email protected] | f9a4c41a | 2012-05-30 00:05:32 | [diff] [blame] | 44 | EXPECT_TRUE(FileSelectHelper::IsAcceptTypeValid("a/b")); |
| 45 | EXPECT_TRUE(FileSelectHelper::IsAcceptTypeValid("abc/def")); |
| 46 | EXPECT_TRUE(FileSelectHelper::IsAcceptTypeValid("abc/*")); |
| 47 | EXPECT_TRUE(FileSelectHelper::IsAcceptTypeValid(".a")); |
| 48 | EXPECT_TRUE(FileSelectHelper::IsAcceptTypeValid(".abc")); |
| 49 | |
| 50 | EXPECT_FALSE(FileSelectHelper::IsAcceptTypeValid(".")); |
| 51 | EXPECT_FALSE(FileSelectHelper::IsAcceptTypeValid("/")); |
| 52 | EXPECT_FALSE(FileSelectHelper::IsAcceptTypeValid("ABC/*")); |
| 53 | EXPECT_FALSE(FileSelectHelper::IsAcceptTypeValid("abc/def ")); |
| 54 | } |
erikchen | 22de64a3 | 2014-10-10 18:27:43 | [diff] [blame] | 55 | |
jam | 1c5a9149 | 2016-02-24 20:47:53 | [diff] [blame] | 56 | #if defined(OS_MACOSX) |
erikchen | 22de64a3 | 2014-10-10 18:27:43 | [diff] [blame] | 57 | TEST_F(FileSelectHelperTest, ZipPackage) { |
| 58 | // Zip the package. |
| 59 | const char app_name[] = "CalculatorFake.app"; |
| 60 | base::FilePath src = data_dir_.Append(app_name); |
| 61 | base::FilePath dest = FileSelectHelper::ZipPackage(src); |
| 62 | ASSERT_FALSE(dest.empty()); |
| 63 | ASSERT_TRUE(base::PathExists(dest)); |
| 64 | |
| 65 | base::ScopedTempDir temp_dir; |
| 66 | ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 67 | |
| 68 | // Unzip the package into a temporary directory. |
avi | 556c0502 | 2014-12-22 23:31:43 | [diff] [blame] | 69 | base::CommandLine cl(base::FilePath("/usr/bin/unzip")); |
erikchen | 22de64a3 | 2014-10-10 18:27:43 | [diff] [blame] | 70 | cl.AppendArg(dest.value().c_str()); |
| 71 | cl.AppendArg("-d"); |
vabr | 0c237ae | 2016-09-14 09:24:28 | [diff] [blame] | 72 | cl.AppendArg(temp_dir.GetPath().value().c_str()); |
erikchen | 22de64a3 | 2014-10-10 18:27:43 | [diff] [blame] | 73 | std::string output; |
| 74 | EXPECT_TRUE(base::GetAppOutput(cl, &output)); |
| 75 | |
| 76 | // Verify that several key files haven't changed. |
| 77 | const char* files_to_verify[] = {"Contents/Info.plist", |
| 78 | "Contents/MacOS/Calculator", |
| 79 | "Contents/_CodeSignature/CodeResources"}; |
Avi Drissman | 5f0fb8c | 2018-12-25 23:20:49 | [diff] [blame] | 80 | size_t file_count = base::size(files_to_verify); |
erikchen | 22de64a3 | 2014-10-10 18:27:43 | [diff] [blame] | 81 | for (size_t i = 0; i < file_count; i++) { |
| 82 | const char* relative_path = files_to_verify[i]; |
| 83 | base::FilePath orig_file = src.Append(relative_path); |
| 84 | base::FilePath final_file = |
vabr | 0c237ae | 2016-09-14 09:24:28 | [diff] [blame] | 85 | temp_dir.GetPath().Append(app_name).Append(relative_path); |
erikchen | 22de64a3 | 2014-10-10 18:27:43 | [diff] [blame] | 86 | EXPECT_TRUE(base::ContentsEqual(orig_file, final_file)); |
| 87 | } |
| 88 | } |
jam | 1c5a9149 | 2016-02-24 20:47:53 | [diff] [blame] | 89 | #endif // defined(OS_MACOSX) |
asanka | ee261f3 | 2015-10-27 21:04:28 | [diff] [blame] | 90 | |
| 91 | TEST_F(FileSelectHelperTest, GetSanitizedFileName) { |
| 92 | // The empty path should be preserved. |
| 93 | EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("")), |
| 94 | FileSelectHelper::GetSanitizedFileName(base::FilePath())); |
| 95 | |
| 96 | EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("ascii.txt")), |
| 97 | FileSelectHelper::GetSanitizedFileName( |
| 98 | base::FilePath(FILE_PATH_LITERAL("ascii.txt")))); |
Xing Liu | f5d0556 | 2017-08-10 20:49:24 | [diff] [blame] | 99 | EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("trailing-spaces_")), |
asanka | ee261f3 | 2015-10-27 21:04:28 | [diff] [blame] | 100 | FileSelectHelper::GetSanitizedFileName( |
| 101 | base::FilePath(FILE_PATH_LITERAL("trailing-spaces ")))); |
Xing Liu | f5d0556 | 2017-08-10 20:49:24 | [diff] [blame] | 102 | EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("path_components_in_name")), |
asanka | ee261f3 | 2015-10-27 21:04:28 | [diff] [blame] | 103 | FileSelectHelper::GetSanitizedFileName( |
| 104 | base::FilePath(FILE_PATH_LITERAL("path/components/in/name")))); |
| 105 | |
| 106 | #if defined(OS_WIN) |
| 107 | // Invalid UTF-16. However, note that on Windows, the invalid UTF-16 will pass |
| 108 | // through without error. |
| 109 | base::FilePath::CharType kBadName[] = {0xd801, 0xdc37, 0xdc17, 0}; |
| 110 | #else |
| 111 | // Invalid UTF-8 |
| 112 | base::FilePath::CharType kBadName[] = {0xe3, 0x81, 0x81, 0x81, 0x82, 0}; |
| 113 | #endif |
| 114 | base::FilePath bad_filename(kBadName); |
| 115 | ASSERT_FALSE(bad_filename.empty()); |
| 116 | // The only thing we are testing is that if the source filename was non-empty, |
| 117 | // the resulting filename is also not empty. Invalid encoded filenames can |
| 118 | // cause conversions to fail. Such failures shouldn't cause the resulting |
| 119 | // filename to disappear. |
| 120 | EXPECT_FALSE(FileSelectHelper::GetSanitizedFileName(bad_filename).empty()); |
| 121 | } |
jsbell | 0d496dc | 2016-10-28 22:23:57 | [diff] [blame] | 122 | |
| 123 | TEST_F(FileSelectHelperTest, LastSelectedDirectory) { |
| 124 | content::TestBrowserThreadBundle browser_thread_bundle; |
| 125 | TestingProfile profile; |
| 126 | scoped_refptr<FileSelectHelper> file_select_helper = |
| 127 | new FileSelectHelper(&profile); |
| 128 | |
| 129 | const int index = 0; |
| 130 | void* params = nullptr; |
| 131 | |
| 132 | const base::FilePath dir_path_1 = data_dir_.AppendASCII("dir1"); |
| 133 | const base::FilePath dir_path_2 = data_dir_.AppendASCII("dir2"); |
| 134 | const base::FilePath file_path_1 = dir_path_1.AppendASCII("file1.txt"); |
| 135 | const base::FilePath file_path_2 = dir_path_1.AppendASCII("file2.txt"); |
| 136 | const base::FilePath file_path_3 = dir_path_2.AppendASCII("file3.txt"); |
| 137 | std::vector<base::FilePath> files; // Both in dir1. |
| 138 | files.push_back(file_path_1); |
| 139 | files.push_back(file_path_2); |
| 140 | std::vector<base::FilePath> dirs; |
| 141 | dirs.push_back(dir_path_1); |
| 142 | dirs.push_back(dir_path_2); |
| 143 | |
| 144 | // Modes where the parent of the selection is remembered. |
| 145 | const std::vector<FileChooserParams::Mode> modes = { |
Kent Tamura | c260c9a | 2018-09-14 09:10:56 | [diff] [blame] | 146 | FileChooserParams::Mode::kOpen, FileChooserParams::Mode::kOpenMultiple, |
| 147 | FileChooserParams::Mode::kSave, |
jsbell | 0d496dc | 2016-10-28 22:23:57 | [diff] [blame] | 148 | }; |
| 149 | |
| 150 | for (const auto& mode : modes) { |
| 151 | file_select_helper->dialog_mode_ = mode; |
| 152 | |
| 153 | file_select_helper->AddRef(); // Normally called by RunFileChooser(). |
| 154 | file_select_helper->FileSelected(file_path_1, index, params); |
| 155 | EXPECT_EQ(dir_path_1, profile.last_selected_directory()); |
| 156 | |
| 157 | file_select_helper->AddRef(); // Normally called by RunFileChooser(). |
| 158 | file_select_helper->FileSelected(file_path_2, index, params); |
| 159 | EXPECT_EQ(dir_path_1, profile.last_selected_directory()); |
| 160 | |
| 161 | file_select_helper->AddRef(); // Normally called by RunFileChooser(). |
| 162 | file_select_helper->FileSelected(file_path_3, index, params); |
| 163 | EXPECT_EQ(dir_path_2, profile.last_selected_directory()); |
| 164 | |
| 165 | file_select_helper->AddRef(); // Normally called by RunFileChooser(). |
| 166 | file_select_helper->MultiFilesSelected(files, params); |
| 167 | EXPECT_EQ(dir_path_1, profile.last_selected_directory()); |
| 168 | } |
| 169 | |
| 170 | // Type where the selected folder itself is remembered. |
Kent Tamura | c260c9a | 2018-09-14 09:10:56 | [diff] [blame] | 171 | file_select_helper->dialog_mode_ = FileChooserParams::Mode::kUploadFolder; |
jsbell | 0d496dc | 2016-10-28 22:23:57 | [diff] [blame] | 172 | |
| 173 | file_select_helper->AddRef(); // Normally called by RunFileChooser(). |
| 174 | file_select_helper->FileSelected(dir_path_1, index, params); |
| 175 | EXPECT_EQ(dir_path_1, profile.last_selected_directory()); |
| 176 | |
| 177 | file_select_helper->AddRef(); // Normally called by RunFileChooser(). |
| 178 | file_select_helper->FileSelected(dir_path_2, index, params); |
| 179 | EXPECT_EQ(dir_path_2, profile.last_selected_directory()); |
| 180 | |
| 181 | file_select_helper->AddRef(); // Normally called by RunFileChooser(). |
| 182 | file_select_helper->MultiFilesSelected(dirs, params); |
| 183 | EXPECT_EQ(dir_path_1, profile.last_selected_directory()); |
| 184 | } |