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.
5 #include "chrome/browser/chromeos/drive/file_system_util.h"
7 #include "base/file_util.h"
8 #include "base/files/file_path.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/common/chrome_constants.h"
13 #include "chrome/test/base/testing_browser_process.h"
14 #include "chrome/test/base/testing_profile.h"
15 #include "chrome/test/base/testing_profile_manager.h"
16 #include "content/public/test/test_browser_thread_bundle.h"
17 #include "content/public/test/test_file_system_options.h"
18 #include "google_apis/drive/test_util.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "webkit/browser/fileapi/external_mount_points.h"
21 #include "webkit/browser/fileapi/file_system_backend.h"
22 #include "webkit/browser/fileapi/file_system_context.h"
23 #include "webkit/browser/fileapi/file_system_url.h"
24 #include "webkit/browser/fileapi/isolated_context.h"
31 // Sets up ProfileManager for testing and marks the current thread as UI by
32 // TestBrowserThreadBundle. We need the thread since Profile objects must be
33 // touched from UI and hence has CHECK/DCHECKs for it.
34 class ProfileRelatedFileSystemUtilTest : public testing::Test {
36 ProfileRelatedFileSystemUtilTest()
37 : testing_profile_manager_(TestingBrowserProcess::GetGlobal()) {
40 virtual void SetUp() OVERRIDE {
41 ASSERT_TRUE(testing_profile_manager_.SetUp());
44 Profile* CreateProfileWithName(const std::string& name) {
45 return testing_profile_manager_.CreateTestingProfile(
46 chrome::kProfileDirPrefix + name);
50 content::TestBrowserThreadBundle thread_bundle_;
51 TestingProfileManager testing_profile_manager_;
56 TEST(FileSystemUtilTest, FilePathToDriveURL) {
59 // Path with alphabets and numbers.
60 path = GetDriveMyDriveRootPath().AppendASCII("foo/bar012.txt");
61 EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
64 path = GetDriveMyDriveRootPath().AppendASCII(
65 " !\"#$%&'()*+,-.:;<=>?@[\\]^_`{|}~");
66 EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
69 path = GetDriveMyDriveRootPath().AppendASCII("%19%20%21.txt");
70 EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
72 // Path with multi byte characters.
73 base::string16 utf16_string;
74 utf16_string.push_back(0x307b); // HIRAGANA_LETTER_HO
75 utf16_string.push_back(0x3052); // HIRAGANA_LETTER_GE
76 path = GetDriveMyDriveRootPath().Append(
77 base::FilePath::FromUTF8Unsafe(base::UTF16ToUTF8(utf16_string) + ".txt"));
78 EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
81 TEST_F(ProfileRelatedFileSystemUtilTest, GetDriveMountPointPath) {
82 Profile* profile = CreateProfileWithName("hash1");
83 EXPECT_EQ(base::FilePath::FromUTF8Unsafe("/special/drive-hash1"),
84 GetDriveMountPointPath(profile));
87 TEST_F(ProfileRelatedFileSystemUtilTest, ExtractProfileFromPath) {
88 Profile* profile1 = CreateProfileWithName("hash1");
89 Profile* profile2 = CreateProfileWithName("hash2");
90 EXPECT_EQ(profile1, ExtractProfileFromPath(
91 base::FilePath::FromUTF8Unsafe("/special/drive-hash1")));
92 EXPECT_EQ(profile2, ExtractProfileFromPath(
93 base::FilePath::FromUTF8Unsafe("/special/drive-hash2/root/xxx")));
94 EXPECT_EQ(NULL, ExtractProfileFromPath(
95 base::FilePath::FromUTF8Unsafe("/special/non-drive-path")));
98 TEST(FileSystemUtilTest, IsUnderDriveMountPoint) {
99 EXPECT_FALSE(IsUnderDriveMountPoint(
100 base::FilePath::FromUTF8Unsafe("/wherever/foo.txt")));
101 EXPECT_FALSE(IsUnderDriveMountPoint(
102 base::FilePath::FromUTF8Unsafe("/special/foo.txt")));
103 EXPECT_FALSE(IsUnderDriveMountPoint(
104 base::FilePath::FromUTF8Unsafe("special/drive/foo.txt")));
106 EXPECT_TRUE(IsUnderDriveMountPoint(
107 base::FilePath::FromUTF8Unsafe("/special/drive")));
108 EXPECT_TRUE(IsUnderDriveMountPoint(
109 base::FilePath::FromUTF8Unsafe("/special/drive/foo.txt")));
110 EXPECT_TRUE(IsUnderDriveMountPoint(
111 base::FilePath::FromUTF8Unsafe("/special/drive/subdir/foo.txt")));
112 EXPECT_TRUE(IsUnderDriveMountPoint(
113 base::FilePath::FromUTF8Unsafe("/special/drive-xxx/foo.txt")));
116 TEST(FileSystemUtilTest, ExtractDrivePath) {
117 EXPECT_EQ(base::FilePath(),
119 base::FilePath::FromUTF8Unsafe("/wherever/foo.txt")));
120 EXPECT_EQ(base::FilePath(),
122 base::FilePath::FromUTF8Unsafe("/special/foo.txt")));
124 EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive"),
126 base::FilePath::FromUTF8Unsafe("/special/drive")));
127 EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/foo.txt"),
129 base::FilePath::FromUTF8Unsafe("/special/drive/foo.txt")));
130 EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/subdir/foo.txt"),
131 ExtractDrivePath(base::FilePath::FromUTF8Unsafe(
132 "/special/drive/subdir/foo.txt")));
133 EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/foo.txt"),
135 base::FilePath::FromUTF8Unsafe("/special/drive-xxx/foo.txt")));
138 TEST(FileSystemUtilTest, ExtractDrivePathFromFileSystemUrl) {
139 TestingProfile profile;
141 // Set up file system context for testing.
142 base::ScopedTempDir temp_dir_;
143 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
145 base::MessageLoop message_loop;
146 scoped_refptr<fileapi::ExternalMountPoints> mount_points =
147 fileapi::ExternalMountPoints::CreateRefCounted();
148 scoped_refptr<fileapi::FileSystemContext> context(
149 new fileapi::FileSystemContext(
150 base::MessageLoopProxy::current().get(),
151 base::MessageLoopProxy::current().get(),
153 NULL, // special_storage_policy
154 NULL, // quota_manager_proxy,
155 ScopedVector<fileapi::FileSystemBackend>(),
156 temp_dir_.path(), // partition_path
157 content::CreateAllowFileAccessOptions()));
159 // Type:"external" + virtual_path:"drive/foo/bar" resolves to "drive/foo/bar".
160 const std::string& drive_mount_name =
161 GetDriveMountPointPath(&profile).BaseName().AsUTF8Unsafe();
162 mount_points->RegisterFileSystem(
164 fileapi::kFileSystemTypeDrive,
165 fileapi::FileSystemMountOption(),
166 GetDriveMountPointPath(&profile));
168 base::FilePath::FromUTF8Unsafe("drive/foo/bar"),
169 ExtractDrivePathFromFileSystemUrl(context->CrackURL(GURL(
170 "filesystem:chrome-extension://dummy-id/external/" +
171 drive_mount_name + "/foo/bar"))));
173 // Virtual mount name should not affect the extracted path.
174 mount_points->RevokeFileSystem(drive_mount_name);
175 mount_points->RegisterFileSystem(
177 fileapi::kFileSystemTypeDrive,
178 fileapi::FileSystemMountOption(),
179 GetDriveMountPointPath(&profile));
181 base::FilePath::FromUTF8Unsafe("drive/foo/bar"),
182 ExtractDrivePathFromFileSystemUrl(context->CrackURL(GURL(
183 "filesystem:chrome-extension://dummy-id/external/drive2/foo/bar"))));
185 // Type:"external" + virtual_path:"Downloads/foo" is not a Drive path.
186 mount_points->RegisterFileSystem(
188 fileapi::kFileSystemTypeNativeLocal,
189 fileapi::FileSystemMountOption(),
193 ExtractDrivePathFromFileSystemUrl(context->CrackURL(GURL(
194 "filesystem:chrome-extension://dummy-id/external/Downloads/foo"))));
196 // Type:"isolated" + virtual_path:"isolated_id/name" mapped on a Drive path.
197 std::string isolated_name;
198 std::string isolated_id =
199 fileapi::IsolatedContext::GetInstance()->RegisterFileSystemForPath(
200 fileapi::kFileSystemTypeNativeForPlatformApp,
201 GetDriveMountPointPath(&profile).AppendASCII("bar/buz"),
204 base::FilePath::FromUTF8Unsafe("drive/bar/buz"),
205 ExtractDrivePathFromFileSystemUrl(context->CrackURL(GURL(
206 "filesystem:chrome-extension://dummy-id/isolated/" +
207 isolated_id + "/" + isolated_name))));
210 TEST(FileSystemUtilTest, EscapeUnescapeCacheFileName) {
211 const std::string kUnescapedFileName(
212 "tmp:`~!@#$%^&*()-_=+[{|]}\\\\;\',<.>/?");
213 const std::string kEscapedFileName(
214 "tmp:`~!@#$%25^&*()-_=+[{|]}\\\\;\',<%2E>%2F?");
215 EXPECT_EQ(kEscapedFileName, EscapeCacheFileName(kUnescapedFileName));
216 EXPECT_EQ(kUnescapedFileName, UnescapeCacheFileName(kEscapedFileName));
219 TEST(FileSystemUtilTest, NormalizeFileName) {
220 EXPECT_EQ("", NormalizeFileName(""));
221 EXPECT_EQ("foo", NormalizeFileName("foo"));
223 EXPECT_EQ("foo_zzz", NormalizeFileName("foo/zzz"));
224 EXPECT_EQ("___", NormalizeFileName("///"));
225 // Japanese hiragana "hi" + semi-voiced-mark is normalized to "pi".
226 EXPECT_EQ("\xE3\x81\xB4", NormalizeFileName("\xE3\x81\xB2\xE3\x82\x9A"));
228 EXPECT_EQ("_", NormalizeFileName("."));
229 EXPECT_EQ("_", NormalizeFileName(".."));
230 EXPECT_EQ("_", NormalizeFileName("..."));
231 EXPECT_EQ(".bashrc", NormalizeFileName(".bashrc"));
232 EXPECT_EQ("._", NormalizeFileName("./"));
235 TEST(FileSystemUtilTest, GetCacheRootPath) {
236 TestingProfile profile;
237 base::FilePath profile_path = profile.GetPath();
238 EXPECT_EQ(profile_path.AppendASCII("GCache/v1"),
239 util::GetCacheRootPath(&profile));
242 TEST(FileSystemUtilTest, GDocFile) {
243 base::ScopedTempDir temp_dir;
244 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
246 GURL url("https://docs.google.com/document/d/"
247 "1YsCnrMxxgp7LDdtlFDt-WdtEIth89vA9inrILtvK-Ug/edit");
248 std::string resource_id("1YsCnrMxxgp7LDdtlFDt-WdtEIth89vA9inrILtvK-Ug");
250 // Read and write gdoc.
251 base::FilePath file = temp_dir.path().AppendASCII("test.gdoc");
252 EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
253 EXPECT_TRUE(HasGDocFileExtension(file));
254 EXPECT_EQ(url, ReadUrlFromGDocFile(file));
255 EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
257 // Read and write gsheet.
258 file = temp_dir.path().AppendASCII("test.gsheet");
259 EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
260 EXPECT_TRUE(HasGDocFileExtension(file));
261 EXPECT_EQ(url, ReadUrlFromGDocFile(file));
262 EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
264 // Read and write gslides.
265 file = temp_dir.path().AppendASCII("test.gslides");
266 EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
267 EXPECT_TRUE(HasGDocFileExtension(file));
268 EXPECT_EQ(url, ReadUrlFromGDocFile(file));
269 EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
271 // Read and write gdraw.
272 file = temp_dir.path().AppendASCII("test.gdraw");
273 EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
274 EXPECT_TRUE(HasGDocFileExtension(file));
275 EXPECT_EQ(url, ReadUrlFromGDocFile(file));
276 EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
278 // Read and write gtable.
279 file = temp_dir.path().AppendASCII("test.gtable");
280 EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
281 EXPECT_TRUE(HasGDocFileExtension(file));
282 EXPECT_EQ(url, ReadUrlFromGDocFile(file));
283 EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
285 // Read and write glink.
286 file = temp_dir.path().AppendASCII("test.glink");
287 EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
288 EXPECT_TRUE(HasGDocFileExtension(file));
289 EXPECT_EQ(url, ReadUrlFromGDocFile(file));
290 EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
293 file = temp_dir.path().AppendASCII("test.txt");
294 std::string data = "Hello world!";
295 EXPECT_TRUE(google_apis::test_util::WriteStringToFile(file, data));
296 EXPECT_FALSE(HasGDocFileExtension(file));
297 EXPECT_TRUE(ReadUrlFromGDocFile(file).is_empty());
298 EXPECT_TRUE(ReadResourceIdFromGDocFile(file).empty());