file_system_util_unittest.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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/message_loop.h"
11#include "base/utf_string_conversions.h"
12#include "chrome/test/base/testing_profile.h"
13#include "testing/gtest/include/gtest/gtest.h"
14#include "webkit/browser/fileapi/external_mount_points.h"
15#include "webkit/browser/fileapi/file_system_context.h"
16#include "webkit/browser/fileapi/file_system_mount_point_provider.h"
17#include "webkit/browser/fileapi/file_system_task_runners.h"
18#include "webkit/browser/fileapi/file_system_url.h"
19#include "webkit/browser/fileapi/isolated_context.h"
20#include "webkit/browser/fileapi/mock_file_system_options.h"
21
22namespace drive {
23namespace util {
24
25TEST(FileSystemUtilTest, FilePathToDriveURL) {
26  base::FilePath path;
27
28  // Path with alphabets and numbers.
29  path = GetDriveMyDriveRootPath().AppendASCII("foo/bar012.txt");
30  EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
31
32  // Path with symbols.
33  path = GetDriveMyDriveRootPath().AppendASCII(
34      " !\"#$%&'()*+,-.:;<=>?@[\\]^_`{|}~");
35  EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
36
37  // Path with '%'.
38  path = GetDriveMyDriveRootPath().AppendASCII("%19%20%21.txt");
39  EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
40
41  // Path with multi byte characters.
42  string16 utf16_string;
43  utf16_string.push_back(0x307b);  // HIRAGANA_LETTER_HO
44  utf16_string.push_back(0x3052);  // HIRAGANA_LETTER_GE
45  path = GetDriveMyDriveRootPath().Append(
46      base::FilePath::FromUTF8Unsafe(UTF16ToUTF8(utf16_string) + ".txt"));
47  EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
48}
49
50TEST(FileSystemUtilTest, IsUnderDriveMountPoint) {
51  EXPECT_FALSE(IsUnderDriveMountPoint(
52      base::FilePath::FromUTF8Unsafe("/wherever/foo.txt")));
53  EXPECT_FALSE(IsUnderDriveMountPoint(
54      base::FilePath::FromUTF8Unsafe("/special/foo.txt")));
55  EXPECT_FALSE(IsUnderDriveMountPoint(
56      base::FilePath::FromUTF8Unsafe("/special/drivex/foo.txt")));
57  EXPECT_FALSE(IsUnderDriveMountPoint(
58      base::FilePath::FromUTF8Unsafe("special/drivex/foo.txt")));
59
60  EXPECT_TRUE(IsUnderDriveMountPoint(
61      base::FilePath::FromUTF8Unsafe("/special/drive")));
62  EXPECT_TRUE(IsUnderDriveMountPoint(
63      base::FilePath::FromUTF8Unsafe("/special/drive/foo.txt")));
64  EXPECT_TRUE(IsUnderDriveMountPoint(
65      base::FilePath::FromUTF8Unsafe("/special/drive/subdir/foo.txt")));
66}
67
68TEST(FileSystemUtilTest, ExtractDrivePath) {
69  EXPECT_EQ(base::FilePath(),
70            ExtractDrivePath(
71                base::FilePath::FromUTF8Unsafe("/wherever/foo.txt")));
72  EXPECT_EQ(base::FilePath(),
73            ExtractDrivePath(
74                base::FilePath::FromUTF8Unsafe("/special/foo.txt")));
75  EXPECT_EQ(base::FilePath(),
76            ExtractDrivePath(
77                base::FilePath::FromUTF8Unsafe("/special/drivex/foo.txt")));
78
79  EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive"),
80            ExtractDrivePath(
81                base::FilePath::FromUTF8Unsafe("/special/drive")));
82  EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/foo.txt"),
83            ExtractDrivePath(
84                base::FilePath::FromUTF8Unsafe("/special/drive/foo.txt")));
85  EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/subdir/foo.txt"),
86            ExtractDrivePath(base::FilePath::FromUTF8Unsafe(
87                "/special/drive/subdir/foo.txt")));
88}
89
90TEST(FileSystemUtilTest, ExtractDrivePathFromFileSystemUrl) {
91  // Set up file system context for testing.
92  base::ScopedTempDir temp_dir_;
93  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
94
95  base::MessageLoop message_loop;
96  scoped_refptr<fileapi::ExternalMountPoints> mount_points =
97      fileapi::ExternalMountPoints::CreateRefCounted();
98  scoped_refptr<fileapi::FileSystemContext> context(
99      new fileapi::FileSystemContext(
100          fileapi::FileSystemTaskRunners::CreateMockTaskRunners(),
101          mount_points,
102          NULL,  // special_storage_policy
103          NULL,  // quota_manager_proxy,
104          ScopedVector<fileapi::FileSystemMountPointProvider>(),
105          temp_dir_.path(),  // partition_path
106          fileapi::CreateAllowFileAccessOptions()));
107
108  // Type:"external" + virtual_path:"drive/foo/bar" resolves to "drive/foo/bar".
109  const std::string& drive_mount_name =
110      GetDriveMountPointPath().BaseName().AsUTF8Unsafe();
111  mount_points->RegisterRemoteFileSystem(
112      drive_mount_name,
113      fileapi::kFileSystemTypeDrive,
114      NULL,  // RemoteFileSystemProxyInterface
115      GetDriveMountPointPath());
116  EXPECT_EQ(
117      base::FilePath::FromUTF8Unsafe(drive_mount_name + "/foo/bar"),
118      ExtractDrivePathFromFileSystemUrl(context->CrackURL(GURL(
119          "filesystem:chrome-extension://dummy-id/external/" +
120          drive_mount_name + "/foo/bar"))));
121
122  // Virtual mount name should not affect the extracted path.
123  mount_points->RevokeFileSystem(drive_mount_name);
124  mount_points->RegisterRemoteFileSystem(
125      "drive2",
126      fileapi::kFileSystemTypeDrive,
127      NULL,  // RemoteFileSystemProxyInterface
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, EscapeUtf8FileName) {
168  EXPECT_EQ("", EscapeUtf8FileName(""));
169  EXPECT_EQ("foo", EscapeUtf8FileName("foo"));
170  EXPECT_EQ("foo\xE2\x88\x95zzz", EscapeUtf8FileName("foo/zzz"));
171  EXPECT_EQ("\xE2\x88\x95\xE2\x88\x95\xE2\x88\x95", EscapeUtf8FileName("///"));
172}
173
174TEST(FileSystemUtilTest, GetCacheRootPath) {
175  TestingProfile profile;
176  base::FilePath profile_path = profile.GetPath();
177  EXPECT_EQ(profile_path.AppendASCII("GCache/v1"),
178            util::GetCacheRootPath(&profile));
179}
180
181TEST(FileSystemUtilTest, ParseCacheFilePath) {
182  std::string resource_id, md5, extra_extension;
183  ParseCacheFilePath(
184      base::FilePath::FromUTF8Unsafe(
185          "/home/user/GCache/v1/persistent/pdf:a1b2.0123456789abcdef.mounted"),
186      &resource_id,
187      &md5,
188      &extra_extension);
189  EXPECT_EQ(resource_id, "pdf:a1b2");
190  EXPECT_EQ(md5, "0123456789abcdef");
191  EXPECT_EQ(extra_extension, "mounted");
192
193  ParseCacheFilePath(
194      base::FilePath::FromUTF8Unsafe(
195          "/home/user/GCache/v1/tmp/pdf:a1b2.0123456789abcdef"),
196      &resource_id,
197      &md5,
198      &extra_extension);
199  EXPECT_EQ(resource_id, "pdf:a1b2");
200  EXPECT_EQ(md5, "0123456789abcdef");
201  EXPECT_EQ(extra_extension, "");
202
203  ParseCacheFilePath(
204      base::FilePath::FromUTF8Unsafe(
205          "/home/user/GCache/v1/pinned/pdf:a1b2"),
206      &resource_id,
207      &md5,
208      &extra_extension);
209  EXPECT_EQ(resource_id, "pdf:a1b2");
210  EXPECT_EQ(md5, "");
211  EXPECT_EQ(extra_extension, "");
212}
213
214TEST(FileSystemUtilTest, NeedsNamespaceMigration) {
215  // Not Drive cases.
216  EXPECT_FALSE(NeedsNamespaceMigration(
217      base::FilePath::FromUTF8Unsafe("/Downloads")));
218  EXPECT_FALSE(NeedsNamespaceMigration(
219      base::FilePath::FromUTF8Unsafe("/Downloads/x")));
220  EXPECT_FALSE(NeedsNamespaceMigration(
221      base::FilePath::FromUTF8Unsafe("/wherever/foo.txt")));
222  EXPECT_FALSE(NeedsNamespaceMigration(
223      base::FilePath::FromUTF8Unsafe("/special/foo.txt")));
224  EXPECT_FALSE(NeedsNamespaceMigration(
225      base::FilePath::FromUTF8Unsafe("/special/drivex/foo.txt")));
226  EXPECT_FALSE(NeedsNamespaceMigration(
227      base::FilePath::FromUTF8Unsafe("special/drivex/foo.txt")));
228
229  // Before migration.
230  EXPECT_TRUE(NeedsNamespaceMigration(
231      base::FilePath::FromUTF8Unsafe("/special/drive")));
232  EXPECT_TRUE(NeedsNamespaceMigration(
233      base::FilePath::FromUTF8Unsafe("/special/drive/foo.txt")));
234  EXPECT_TRUE(NeedsNamespaceMigration(
235      base::FilePath::FromUTF8Unsafe("/special/drive/subdir/foo.txt")));
236
237  // Already migrated.
238  EXPECT_FALSE(NeedsNamespaceMigration(
239      base::FilePath::FromUTF8Unsafe("/special/drive/root")));
240  EXPECT_FALSE(NeedsNamespaceMigration(
241      base::FilePath::FromUTF8Unsafe("/special/drive/root/dir1")));
242  EXPECT_FALSE(NeedsNamespaceMigration(
243      base::FilePath::FromUTF8Unsafe("/special/drive/root/root")));
244  EXPECT_FALSE(NeedsNamespaceMigration(
245      base::FilePath::FromUTF8Unsafe("/special/drive/root/root/dir1")));
246}
247
248TEST(FileSystemUtilTest, ConvertToMyDriveNamespace) {
249  // Migration cases.
250  EXPECT_EQ(base::FilePath::FromUTF8Unsafe("/special/drive/root"),
251            drive::util::ConvertToMyDriveNamespace(
252                base::FilePath::FromUTF8Unsafe("/special/drive")));
253
254  EXPECT_EQ(base::FilePath::FromUTF8Unsafe("/special/drive/root/dir1"),
255            drive::util::ConvertToMyDriveNamespace(
256                base::FilePath::FromUTF8Unsafe("/special/drive/dir1")));
257}
258
259TEST(FileSystemUtilTest, IsSpecialResourceId) {
260  EXPECT_FALSE(util::IsSpecialResourceId("abc"));
261  EXPECT_FALSE(util::IsSpecialResourceId("file:123"));
262  EXPECT_FALSE(util::IsSpecialResourceId("folder:root"));
263  EXPECT_FALSE(util::IsSpecialResourceId("folder:xyz"));
264
265  EXPECT_TRUE(util::IsSpecialResourceId("<drive>"));
266  EXPECT_TRUE(util::IsSpecialResourceId("<other>"));
267}
268
269TEST(FileSystemUtilTest, GDocFile) {
270  base::ScopedTempDir temp_dir;
271  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
272
273  GURL url("https://docs.google.com/document/d/"
274           "1YsCnrMxxgp7LDdtlFDt-WdtEIth89vA9inrILtvK-Ug/edit");
275  std::string resource_id("1YsCnrMxxgp7LDdtlFDt-WdtEIth89vA9inrILtvK-Ug");
276
277  // Read and write gdoc.
278  base::FilePath file = temp_dir.path().AppendASCII("test.gdoc");
279  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
280  EXPECT_TRUE(HasGDocFileExtension(file));
281  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
282  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
283
284  // Read and write gsheet.
285  file = temp_dir.path().AppendASCII("test.gsheet");
286  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
287  EXPECT_TRUE(HasGDocFileExtension(file));
288  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
289  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
290
291  // Read and write gslides.
292  file = temp_dir.path().AppendASCII("test.gslides");
293  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
294  EXPECT_TRUE(HasGDocFileExtension(file));
295  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
296  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
297
298  // Read and write gdraw.
299  file = temp_dir.path().AppendASCII("test.gdraw");
300  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
301  EXPECT_TRUE(HasGDocFileExtension(file));
302  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
303  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
304
305  // Read and write gtable.
306  file = temp_dir.path().AppendASCII("test.gtable");
307  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
308  EXPECT_TRUE(HasGDocFileExtension(file));
309  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
310  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
311
312  // Read and write glink.
313  file = temp_dir.path().AppendASCII("test.glink");
314  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
315  EXPECT_TRUE(HasGDocFileExtension(file));
316  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
317  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
318
319  // Non GDoc file.
320  file = temp_dir.path().AppendASCII("test.txt");
321  std::string data = "Hello world!";
322  EXPECT_EQ(static_cast<int>(data.size()),
323            file_util::WriteFile(file, data.data(), data.size()));
324  EXPECT_FALSE(HasGDocFileExtension(file));
325  EXPECT_TRUE(ReadUrlFromGDocFile(file).is_empty());
326  EXPECT_TRUE(ReadResourceIdFromGDocFile(file).empty());
327}
328
329}  // namespace util
330}  // namespace drive
331