Roll src/third_party/WebKit aa8346d:dbb8a38 (svn 202629:202630)
[chromium-blink-merge.git] / chrome / browser / platform_util_unittest.cc
blobcd30a7f12ed49580f002ab372548d9137a06c410
1 // Copyright 2015 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.
5 #include "chrome/browser/platform_util.h"
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/files/file_util.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/run_loop.h"
13 #include "chrome/browser/platform_util_internal.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 #if defined(OS_CHROMEOS)
17 #include "base/json/json_string_value_serializer.h"
18 #include "base/values.h"
19 #include "chrome/browser/chrome_content_browser_client.h"
20 #include "chrome/browser/chromeos/file_manager/app_id.h"
21 #include "chrome/browser/chromeos/fileapi/file_system_backend.h"
22 #include "chrome/browser/extensions/extension_special_storage_policy.h"
23 #include "chrome/test/base/browser_with_test_window_test.h"
24 #include "content/public/browser/browser_context.h"
25 #include "content/public/common/content_client.h"
26 #include "content/public/test/mock_special_storage_policy.h"
27 #include "extensions/browser/extension_registry.h"
28 #include "extensions/common/extension.h"
29 #include "storage/browser/fileapi/external_mount_points.h"
30 #include "storage/common/fileapi/file_system_types.h"
31 #else
32 #include "content/public/test/test_browser_thread_bundle.h"
33 #endif
35 namespace platform_util {
37 namespace {
39 #if defined(OS_CHROMEOS)
41 // ChromeContentBrowserClient subclass that sets up a custom file system backend
42 // that allows the test to grant file access to the file manager extension ID
43 // without having to install the extension.
44 class PlatformUtilTestContentBrowserClient : public ChromeContentBrowserClient {
45 public:
46 void GetAdditionalFileSystemBackends(
47 content::BrowserContext* browser_context,
48 const base::FilePath& storage_partition_path,
49 ScopedVector<storage::FileSystemBackend>* additional_backends) override {
50 storage::ExternalMountPoints* external_mount_points =
51 content::BrowserContext::GetMountPoints(browser_context);
53 // New FileSystemBackend that uses our MockSpecialStoragePolicy.
54 chromeos::FileSystemBackend* backend = new chromeos::FileSystemBackend(
55 nullptr, nullptr, nullptr, external_mount_points,
56 storage::ExternalMountPoints::GetSystemInstance());
57 additional_backends->push_back(backend);
61 // Base test fixture class to be used on Chrome OS.
62 class PlatformUtilTestBase : public BrowserWithTestWindowTest {
63 protected:
64 void SetUpPlatformFixture(const base::FilePath& test_directory) {
65 content_browser_client_.reset(new PlatformUtilTestContentBrowserClient());
66 old_content_browser_client_ =
67 content::SetBrowserClientForTesting(content_browser_client_.get());
69 // The test_directory needs to be mounted for it to be accessible.
70 content::BrowserContext::GetMountPoints(GetProfile())
71 ->RegisterFileSystem("test", storage::kFileSystemTypeNativeLocal,
72 storage::FileSystemMountOption(), test_directory);
74 // To test opening a file, we are going to register a mock extension that
75 // handles .txt files. The extension doesn't actually need to exist due to
76 // the DisableShellOperationsForTesting() call which prevents the extension
77 // from being invoked.
78 std::string error;
79 int error_code = 0;
81 std::string json_manifest =
82 "{"
83 " \"manifest_version\": 2,"
84 " \"name\": \"Test extension\","
85 " \"version\": \"0\","
86 " \"app\": { \"background\": { \"scripts\": [\"main.js\"] }},"
87 " \"file_handlers\": {"
88 " \"text\": {"
89 " \"extensions\": [ \"txt\" ],"
90 " \"title\": \"Text\""
91 " }"
92 " }"
93 "}";
94 JSONStringValueDeserializer json_string_deserializer(json_manifest);
95 scoped_ptr<base::Value> manifest(
96 json_string_deserializer.Deserialize(&error_code, &error));
97 base::DictionaryValue* manifest_dictionary;
99 manifest->GetAsDictionary(&manifest_dictionary);
100 ASSERT_TRUE(manifest_dictionary);
102 scoped_refptr<extensions::Extension> extension =
103 extensions::Extension::Create(
104 test_directory.AppendASCII("invalid-extension"),
105 extensions::Manifest::INVALID_LOCATION, *manifest_dictionary,
106 extensions::Extension::NO_FLAGS, &error);
107 ASSERT_TRUE(error.empty()) << error;
108 extensions::ExtensionRegistry::Get(GetProfile())->AddEnabled(extension);
111 void TearDown() override {
112 content::ContentBrowserClient* content_browser_client =
113 content::SetBrowserClientForTesting(old_content_browser_client_);
114 old_content_browser_client_ = nullptr;
115 DCHECK_EQ(static_cast<content::ContentBrowserClient*>(
116 content_browser_client_.get()),
117 content_browser_client)
118 << "ContentBrowserClient changed during test.";
119 BrowserWithTestWindowTest::TearDown();
122 private:
123 scoped_ptr<content::ContentBrowserClient> content_browser_client_;
124 content::ContentBrowserClient* old_content_browser_client_ = nullptr;
127 #else
129 // Test fixture used by all desktop platforms other than Chrome OS.
130 class PlatformUtilTestBase : public testing::Test {
131 protected:
132 Profile* GetProfile() { return nullptr; }
133 void SetUpPlatformFixture(const base::FilePath&) {}
135 private:
136 content::TestBrowserThreadBundle thread_bundle_;
139 #endif
141 class PlatformUtilTest : public PlatformUtilTestBase {
142 public:
143 void SetUp() override {
144 ASSERT_NO_FATAL_FAILURE(PlatformUtilTestBase::SetUp());
146 static const char kTestFileData[] = "Cow says moo!";
147 const int kTestFileDataLength = arraysize(kTestFileData) - 1;
149 // This prevents platfrom_util from invoking any shell or external APIs
150 // during tests. Doing so may result in external applications being launched
151 // and intefering with tests.
152 internal::DisableShellOperationsForTesting();
154 ASSERT_TRUE(directory_.CreateUniqueTempDir());
156 // A valid file.
157 existing_file_ = directory_.path().AppendASCII("test_file.txt");
158 ASSERT_EQ(
159 kTestFileDataLength,
160 base::WriteFile(existing_file_, kTestFileData, kTestFileDataLength));
162 // A valid folder.
163 existing_folder_ = directory_.path().AppendASCII("test_folder");
164 ASSERT_TRUE(base::CreateDirectory(existing_folder_));
166 // A non-existent path.
167 nowhere_ = directory_.path().AppendASCII("nowhere");
169 SetUpPlatformFixture(directory_.path());
172 OpenOperationResult CallOpenItem(const base::FilePath& path,
173 OpenItemType item_type) {
174 base::RunLoop run_loop;
175 OpenOperationResult result = OPEN_SUCCEEDED;
176 OpenOperationCallback callback =
177 base::Bind(&OnOpenOperationDone, run_loop.QuitClosure(), &result);
178 OpenItem(GetProfile(), path, item_type, callback);
179 run_loop.Run();
180 return result;
183 base::FilePath existing_file_;
184 base::FilePath existing_folder_;
185 base::FilePath nowhere_;
187 protected:
188 base::ScopedTempDir directory_;
190 private:
191 scoped_ptr<base::RunLoop> run_loop_;
193 static void OnOpenOperationDone(const base::Closure& closure,
194 OpenOperationResult* store_result,
195 OpenOperationResult result) {
196 *store_result = result;
197 closure.Run();
201 } // namespace
203 TEST_F(PlatformUtilTest, OpenFile) {
204 EXPECT_EQ(OPEN_SUCCEEDED, CallOpenItem(existing_file_, OPEN_FILE));
205 EXPECT_EQ(OPEN_FAILED_INVALID_TYPE,
206 CallOpenItem(existing_folder_, OPEN_FILE));
207 EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND, CallOpenItem(nowhere_, OPEN_FILE));
210 TEST_F(PlatformUtilTest, OpenFolder) {
211 EXPECT_EQ(OPEN_SUCCEEDED, CallOpenItem(existing_folder_, OPEN_FOLDER));
212 EXPECT_EQ(OPEN_FAILED_INVALID_TYPE,
213 CallOpenItem(existing_file_, OPEN_FOLDER));
214 EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND, CallOpenItem(nowhere_, OPEN_FOLDER));
217 #if defined(OS_POSIX)
218 // Symbolic links are currently only supported on Posix. Windows technically
219 // supports it as well, but not on Windows XP.
220 class PlatformUtilPosixTest : public PlatformUtilTest {
221 public:
222 void SetUp() override {
223 ASSERT_NO_FATAL_FAILURE(PlatformUtilTest::SetUp());
225 symlink_to_file_ = directory_.path().AppendASCII("l_file.txt");
226 ASSERT_TRUE(base::CreateSymbolicLink(existing_file_, symlink_to_file_));
227 symlink_to_folder_ = directory_.path().AppendASCII("l_folder");
228 ASSERT_TRUE(base::CreateSymbolicLink(existing_folder_, symlink_to_folder_));
229 symlink_to_nowhere_ = directory_.path().AppendASCII("l_nowhere");
230 ASSERT_TRUE(base::CreateSymbolicLink(nowhere_, symlink_to_nowhere_));
233 protected:
234 base::FilePath symlink_to_file_;
235 base::FilePath symlink_to_folder_;
236 base::FilePath symlink_to_nowhere_;
238 #endif // OS_POSIX
240 #if defined(OS_CHROMEOS)
241 // ChromeOS doesn't follow symbolic links in sandboxed filesystems. So all the
242 // symbolic link tests should return PATH_NOT_FOUND.
244 TEST_F(PlatformUtilPosixTest, OpenFileWithPosixSymlinksChromeOS) {
245 EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND,
246 CallOpenItem(symlink_to_file_, OPEN_FILE));
247 EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND,
248 CallOpenItem(symlink_to_folder_, OPEN_FILE));
249 EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND,
250 CallOpenItem(symlink_to_nowhere_, OPEN_FILE));
253 TEST_F(PlatformUtilPosixTest, OpenFolderWithPosixSymlinksChromeOS) {
254 EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND,
255 CallOpenItem(symlink_to_folder_, OPEN_FOLDER));
256 EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND,
257 CallOpenItem(symlink_to_file_, OPEN_FOLDER));
258 EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND,
259 CallOpenItem(symlink_to_nowhere_, OPEN_FOLDER));
262 TEST_F(PlatformUtilTest, OpenFileWithUnhandledFileType) {
263 base::FilePath unhandled_file =
264 directory_.path().AppendASCII("myfile.filetype");
265 ASSERT_EQ(3, base::WriteFile(unhandled_file, "cat", 3));
266 EXPECT_EQ(OPEN_FAILED_NO_HANLDER_FOR_FILE_TYPE,
267 CallOpenItem(unhandled_file, OPEN_FILE));
269 #endif // OS_CHROMEOS
271 #if defined(OS_POSIX) && !defined(OS_CHROMEOS)
272 // On all other Posix platforms, the symbolic link tests should work as
273 // expected.
275 TEST_F(PlatformUtilPosixTest, OpenFileWithPosixSymlinks) {
276 EXPECT_EQ(OPEN_SUCCEEDED, CallOpenItem(symlink_to_file_, OPEN_FILE));
277 EXPECT_EQ(OPEN_FAILED_INVALID_TYPE,
278 CallOpenItem(symlink_to_folder_, OPEN_FILE));
279 EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND,
280 CallOpenItem(symlink_to_nowhere_, OPEN_FILE));
283 TEST_F(PlatformUtilPosixTest, OpenFolderWithPosixSymlinks) {
284 EXPECT_EQ(OPEN_SUCCEEDED, CallOpenItem(symlink_to_folder_, OPEN_FOLDER));
285 EXPECT_EQ(OPEN_FAILED_INVALID_TYPE,
286 CallOpenItem(symlink_to_file_, OPEN_FOLDER));
287 EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND,
288 CallOpenItem(symlink_to_nowhere_, OPEN_FOLDER));
290 #endif // OS_POSIX && !OS_CHROMEOS
292 } // namespace platform_util