file_system_util_unittest.cc revision 558790d6acca3451cf3a6b497803a5f07d0bec58
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
5#include "chrome/browser/chromeos/drive/file_system_util.h"
6
7#include "base/file_util.h"
8#include "base/files/file_path.h"
9#include "base/files/scoped_temp_dir.h"
10#include "base/md5.h"
11#include "base/message_loop/message_loop.h"
12#include "base/strings/utf_string_conversions.h"
13#include "chrome/browser/google_apis/test_util.h"
14#include "chrome/test/base/testing_profile.h"
15#include "testing/gtest/include/gtest/gtest.h"
16#include "webkit/browser/fileapi/external_mount_points.h"
17#include "webkit/browser/fileapi/file_system_backend.h"
18#include "webkit/browser/fileapi/file_system_context.h"
19#include "webkit/browser/fileapi/file_system_task_runners.h"
20#include "webkit/browser/fileapi/file_system_url.h"
21#include "webkit/browser/fileapi/isolated_context.h"
22#include "webkit/browser/fileapi/mock_file_system_options.h"
23
24namespace drive {
25namespace util {
26
27TEST(FileSystemUtilTest, FilePathToDriveURL) {
28  base::FilePath path;
29
30  // Path with alphabets and numbers.
31  path = GetDriveMyDriveRootPath().AppendASCII("foo/bar012.txt");
32  EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
33
34  // Path with symbols.
35  path = GetDriveMyDriveRootPath().AppendASCII(
36      " !\"#$%&'()*+,-.:;<=>?@[\\]^_`{|}~");
37  EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
38
39  // Path with '%'.
40  path = GetDriveMyDriveRootPath().AppendASCII("%19%20%21.txt");
41  EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
42
43  // Path with multi byte characters.
44  string16 utf16_string;
45  utf16_string.push_back(0x307b);  // HIRAGANA_LETTER_HO
46  utf16_string.push_back(0x3052);  // HIRAGANA_LETTER_GE
47  path = GetDriveMyDriveRootPath().Append(
48      base::FilePath::FromUTF8Unsafe(UTF16ToUTF8(utf16_string) + ".txt"));
49  EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
50}
51
52TEST(FileSystemUtilTest, IsUnderDriveMountPoint) {
53  EXPECT_FALSE(IsUnderDriveMountPoint(
54      base::FilePath::FromUTF8Unsafe("/wherever/foo.txt")));
55  EXPECT_FALSE(IsUnderDriveMountPoint(
56      base::FilePath::FromUTF8Unsafe("/special/foo.txt")));
57  EXPECT_FALSE(IsUnderDriveMountPoint(
58      base::FilePath::FromUTF8Unsafe("/special/drivex/foo.txt")));
59  EXPECT_FALSE(IsUnderDriveMountPoint(
60      base::FilePath::FromUTF8Unsafe("special/drivex/foo.txt")));
61
62  EXPECT_TRUE(IsUnderDriveMountPoint(
63      base::FilePath::FromUTF8Unsafe("/special/drive")));
64  EXPECT_TRUE(IsUnderDriveMountPoint(
65      base::FilePath::FromUTF8Unsafe("/special/drive/foo.txt")));
66  EXPECT_TRUE(IsUnderDriveMountPoint(
67      base::FilePath::FromUTF8Unsafe("/special/drive/subdir/foo.txt")));
68}
69
70TEST(FileSystemUtilTest, ExtractDrivePath) {
71  EXPECT_EQ(base::FilePath(),
72            ExtractDrivePath(
73                base::FilePath::FromUTF8Unsafe("/wherever/foo.txt")));
74  EXPECT_EQ(base::FilePath(),
75            ExtractDrivePath(
76                base::FilePath::FromUTF8Unsafe("/special/foo.txt")));
77  EXPECT_EQ(base::FilePath(),
78            ExtractDrivePath(
79                base::FilePath::FromUTF8Unsafe("/special/drivex/foo.txt")));
80
81  EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive"),
82            ExtractDrivePath(
83                base::FilePath::FromUTF8Unsafe("/special/drive")));
84  EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/foo.txt"),
85            ExtractDrivePath(
86                base::FilePath::FromUTF8Unsafe("/special/drive/foo.txt")));
87  EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/subdir/foo.txt"),
88            ExtractDrivePath(base::FilePath::FromUTF8Unsafe(
89                "/special/drive/subdir/foo.txt")));
90}
91
92TEST(FileSystemUtilTest, ExtractDrivePathFromFileSystemUrl) {
93  // Set up file system context for testing.
94  base::ScopedTempDir temp_dir_;
95  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
96
97  base::MessageLoop message_loop;
98  scoped_refptr<fileapi::ExternalMountPoints> mount_points =
99      fileapi::ExternalMountPoints::CreateRefCounted();
100  scoped_refptr<fileapi::FileSystemContext> context(
101      new fileapi::FileSystemContext(
102          fileapi::FileSystemTaskRunners::CreateMockTaskRunners(),
103          mount_points.get(),
104          NULL,  // special_storage_policy
105          NULL,  // quota_manager_proxy,
106          ScopedVector<fileapi::FileSystemBackend>(),
107          temp_dir_.path(),  // partition_path
108          fileapi::CreateAllowFileAccessOptions()));
109
110  // Type:"external" + virtual_path:"drive/foo/bar" resolves to "drive/foo/bar".
111  const std::string& drive_mount_name =
112      GetDriveMountPointPath().BaseName().AsUTF8Unsafe();
113  mount_points->RegisterFileSystem(
114      drive_mount_name,
115      fileapi::kFileSystemTypeDrive,
116      GetDriveMountPointPath());
117  EXPECT_EQ(
118      base::FilePath::FromUTF8Unsafe(drive_mount_name + "/foo/bar"),
119      ExtractDrivePathFromFileSystemUrl(context->CrackURL(GURL(
120          "filesystem:chrome-extension://dummy-id/external/" +
121          drive_mount_name + "/foo/bar"))));
122
123  // Virtual mount name should not affect the extracted path.
124  mount_points->RevokeFileSystem(drive_mount_name);
125  mount_points->RegisterFileSystem(
126      "drive2",
127      fileapi::kFileSystemTypeDrive,
128      GetDriveMountPointPath());
129  EXPECT_EQ(
130      base::FilePath::FromUTF8Unsafe(drive_mount_name + "/foo/bar"),
131      ExtractDrivePathFromFileSystemUrl(context->CrackURL(GURL(
132          "filesystem:chrome-extension://dummy-id/external/drive2/foo/bar"))));
133
134  // Type:"external" + virtual_path:"Downloads/foo" is not a Drive path.
135  mount_points->RegisterFileSystem(
136      "Downloads",
137      fileapi::kFileSystemTypeNativeLocal,
138      temp_dir_.path());
139  EXPECT_EQ(
140      base::FilePath(),
141      ExtractDrivePathFromFileSystemUrl(context->CrackURL(GURL(
142          "filesystem:chrome-extension://dummy-id/external/Downloads/foo"))));
143
144  // Type:"isolated" + virtual_path:"isolated_id/name" mapped on a Drive path.
145  std::string isolated_name;
146  std::string isolated_id =
147      fileapi::IsolatedContext::GetInstance()->RegisterFileSystemForPath(
148          fileapi::kFileSystemTypeNativeForPlatformApp,
149          GetDriveMountPointPath().AppendASCII("bar/buz"),
150          &isolated_name);
151  EXPECT_EQ(
152      base::FilePath::FromUTF8Unsafe(drive_mount_name + "/bar/buz"),
153      ExtractDrivePathFromFileSystemUrl(context->CrackURL(GURL(
154          "filesystem:chrome-extension://dummy-id/isolated/" +
155          isolated_id + "/" + isolated_name))));
156}
157
158TEST(FileSystemUtilTest, EscapeUnescapeCacheFileName) {
159  const std::string kUnescapedFileName(
160      "tmp:`~!@#$%^&*()-_=+[{|]}\\\\;\',<.>/?");
161  const std::string kEscapedFileName(
162      "tmp:`~!@#$%25^&*()-_=+[{|]}\\\\;\',<%2E>%2F?");
163  EXPECT_EQ(kEscapedFileName, EscapeCacheFileName(kUnescapedFileName));
164  EXPECT_EQ(kUnescapedFileName, UnescapeCacheFileName(kEscapedFileName));
165}
166
167TEST(FileSystemUtilTest, NormalizeFileName) {
168  EXPECT_EQ("", NormalizeFileName(""));
169  EXPECT_EQ("foo", NormalizeFileName("foo"));
170  EXPECT_EQ("foo\xE2\x88\x95zzz", NormalizeFileName("foo/zzz"));
171  EXPECT_EQ("\xE2\x88\x95\xE2\x88\x95\xE2\x88\x95", NormalizeFileName("///"));
172  // Japanese hiragana "hi" + semi-voiced-mark is normalized to "pi".
173  EXPECT_EQ("\xE3\x81\xB4", NormalizeFileName("\xE3\x81\xB2\xE3\x82\x9A"));
174}
175
176TEST(FileSystemUtilTest, GetCacheRootPath) {
177  TestingProfile profile;
178  base::FilePath profile_path = profile.GetPath();
179  EXPECT_EQ(profile_path.AppendASCII("GCache/v1"),
180            util::GetCacheRootPath(&profile));
181}
182
183TEST(FileSystemUtilTest, MigrateCacheFilesFromOldDirectories) {
184  base::ScopedTempDir temp_dir;
185  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
186
187  const base::FilePath persistent_directory =
188      temp_dir.path().AppendASCII("persistent");
189  const base::FilePath tmp_directory = temp_dir.path().AppendASCII("tmp");
190  const base::FilePath files_directory =
191      temp_dir.path().Append(kCacheFileDirectory);
192
193  // Prepare directories.
194  ASSERT_TRUE(file_util::CreateDirectory(persistent_directory));
195  ASSERT_TRUE(file_util::CreateDirectory(tmp_directory));
196  ASSERT_TRUE(file_util::CreateDirectory(files_directory));
197
198  // Put some files.
199  ASSERT_TRUE(google_apis::test_util::WriteStringToFile(
200      persistent_directory.AppendASCII("foo.abc"), "foo"));
201  ASSERT_TRUE(google_apis::test_util::WriteStringToFile(
202      tmp_directory.AppendASCII("bar.123"), "bar"));
203
204  // Migrate.
205  MigrateCacheFilesFromOldDirectories(temp_dir.path());
206
207  EXPECT_FALSE(base::PathExists(persistent_directory));
208  EXPECT_TRUE(base::PathExists(files_directory.AppendASCII("foo.abc")));
209  EXPECT_TRUE(base::PathExists(files_directory.AppendASCII("bar.123")));
210}
211
212TEST(FileSystemUtilTest, NeedsNamespaceMigration) {
213  // Not Drive cases.
214  EXPECT_FALSE(NeedsNamespaceMigration(
215      base::FilePath::FromUTF8Unsafe("/Downloads")));
216  EXPECT_FALSE(NeedsNamespaceMigration(
217      base::FilePath::FromUTF8Unsafe("/Downloads/x")));
218  EXPECT_FALSE(NeedsNamespaceMigration(
219      base::FilePath::FromUTF8Unsafe("/wherever/foo.txt")));
220  EXPECT_FALSE(NeedsNamespaceMigration(
221      base::FilePath::FromUTF8Unsafe("/special/foo.txt")));
222  EXPECT_FALSE(NeedsNamespaceMigration(
223      base::FilePath::FromUTF8Unsafe("/special/drivex/foo.txt")));
224  EXPECT_FALSE(NeedsNamespaceMigration(
225      base::FilePath::FromUTF8Unsafe("special/drivex/foo.txt")));
226
227  // Before migration.
228  EXPECT_TRUE(NeedsNamespaceMigration(
229      base::FilePath::FromUTF8Unsafe("/special/drive")));
230  EXPECT_TRUE(NeedsNamespaceMigration(
231      base::FilePath::FromUTF8Unsafe("/special/drive/foo.txt")));
232  EXPECT_TRUE(NeedsNamespaceMigration(
233      base::FilePath::FromUTF8Unsafe("/special/drive/subdir/foo.txt")));
234
235  // Already migrated.
236  EXPECT_FALSE(NeedsNamespaceMigration(
237      base::FilePath::FromUTF8Unsafe("/special/drive/root")));
238  EXPECT_FALSE(NeedsNamespaceMigration(
239      base::FilePath::FromUTF8Unsafe("/special/drive/root/dir1")));
240  EXPECT_FALSE(NeedsNamespaceMigration(
241      base::FilePath::FromUTF8Unsafe("/special/drive/root/root")));
242  EXPECT_FALSE(NeedsNamespaceMigration(
243      base::FilePath::FromUTF8Unsafe("/special/drive/root/root/dir1")));
244}
245
246TEST(FileSystemUtilTest, ConvertToMyDriveNamespace) {
247  // Migration cases.
248  EXPECT_EQ(base::FilePath::FromUTF8Unsafe("/special/drive/root"),
249            drive::util::ConvertToMyDriveNamespace(
250                base::FilePath::FromUTF8Unsafe("/special/drive")));
251
252  EXPECT_EQ(base::FilePath::FromUTF8Unsafe("/special/drive/root/dir1"),
253            drive::util::ConvertToMyDriveNamespace(
254                base::FilePath::FromUTF8Unsafe("/special/drive/dir1")));
255}
256
257TEST(FileSystemUtilTest, IsSpecialResourceId) {
258  EXPECT_FALSE(util::IsSpecialResourceId("abc"));
259  EXPECT_FALSE(util::IsSpecialResourceId("file:123"));
260  EXPECT_FALSE(util::IsSpecialResourceId("folder:root"));
261  EXPECT_FALSE(util::IsSpecialResourceId("folder:xyz"));
262
263  EXPECT_TRUE(util::IsSpecialResourceId("<drive>"));
264  EXPECT_TRUE(util::IsSpecialResourceId("<other>"));
265}
266
267TEST(FileSystemUtilTest, GDocFile) {
268  base::ScopedTempDir temp_dir;
269  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
270
271  GURL url("https://docs.google.com/document/d/"
272           "1YsCnrMxxgp7LDdtlFDt-WdtEIth89vA9inrILtvK-Ug/edit");
273  std::string resource_id("1YsCnrMxxgp7LDdtlFDt-WdtEIth89vA9inrILtvK-Ug");
274
275  // Read and write gdoc.
276  base::FilePath file = temp_dir.path().AppendASCII("test.gdoc");
277  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
278  EXPECT_TRUE(HasGDocFileExtension(file));
279  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
280  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
281
282  // Read and write gsheet.
283  file = temp_dir.path().AppendASCII("test.gsheet");
284  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
285  EXPECT_TRUE(HasGDocFileExtension(file));
286  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
287  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
288
289  // Read and write gslides.
290  file = temp_dir.path().AppendASCII("test.gslides");
291  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
292  EXPECT_TRUE(HasGDocFileExtension(file));
293  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
294  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
295
296  // Read and write gdraw.
297  file = temp_dir.path().AppendASCII("test.gdraw");
298  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
299  EXPECT_TRUE(HasGDocFileExtension(file));
300  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
301  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
302
303  // Read and write gtable.
304  file = temp_dir.path().AppendASCII("test.gtable");
305  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
306  EXPECT_TRUE(HasGDocFileExtension(file));
307  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
308  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
309
310  // Read and write glink.
311  file = temp_dir.path().AppendASCII("test.glink");
312  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
313  EXPECT_TRUE(HasGDocFileExtension(file));
314  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
315  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
316
317  // Non GDoc file.
318  file = temp_dir.path().AppendASCII("test.txt");
319  std::string data = "Hello world!";
320  EXPECT_TRUE(google_apis::test_util::WriteStringToFile(file, data));
321  EXPECT_FALSE(HasGDocFileExtension(file));
322  EXPECT_TRUE(ReadUrlFromGDocFile(file).is_empty());
323  EXPECT_TRUE(ReadResourceIdFromGDocFile(file).empty());
324}
325
326TEST(FileSystemUtilTest, GetMd5Digest) {
327  base::ScopedTempDir temp_dir;
328  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
329
330  base::FilePath path = temp_dir.path().AppendASCII("test.txt");
331  const char kTestData[] = "abcdefghijklmnopqrstuvwxyz0123456789";
332  ASSERT_TRUE(google_apis::test_util::WriteStringToFile(path, kTestData));
333
334  EXPECT_EQ(base::MD5String(kTestData), GetMd5Digest(path));
335}
336
337}  // namespace util
338}  // namespace drive
339