file_system_util_unittest.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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/message_loop.h"
11#include "base/strings/utf_string_conversions.h"
12#include "chrome/test/base/testing_profile.h"
13#include "content/public/test/test_file_system_options.h"
14#include "google_apis/drive/test_util.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_url.h"
20#include "webkit/browser/fileapi/isolated_context.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  base::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          base::MessageLoopProxy::current().get(),
101          base::MessageLoopProxy::current().get(),
102          mount_points.get(),
103          NULL,  // special_storage_policy
104          NULL,  // quota_manager_proxy,
105          ScopedVector<fileapi::FileSystemBackend>(),
106          temp_dir_.path(),  // partition_path
107          fileapi::CreateAllowFileAccessOptions()));
108
109  // Type:"external" + virtual_path:"drive/foo/bar" resolves to "drive/foo/bar".
110  const std::string& drive_mount_name =
111      GetDriveMountPointPath().BaseName().AsUTF8Unsafe();
112  mount_points->RegisterFileSystem(
113      drive_mount_name,
114      fileapi::kFileSystemTypeDrive,
115      fileapi::FileSystemMountOption(),
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      fileapi::FileSystemMountOption(),
129      GetDriveMountPointPath());
130  EXPECT_EQ(
131      base::FilePath::FromUTF8Unsafe(drive_mount_name + "/foo/bar"),
132      ExtractDrivePathFromFileSystemUrl(context->CrackURL(GURL(
133          "filesystem:chrome-extension://dummy-id/external/drive2/foo/bar"))));
134
135  // Type:"external" + virtual_path:"Downloads/foo" is not a Drive path.
136  mount_points->RegisterFileSystem(
137      "Downloads",
138      fileapi::kFileSystemTypeNativeLocal,
139      fileapi::FileSystemMountOption(),
140      temp_dir_.path());
141  EXPECT_EQ(
142      base::FilePath(),
143      ExtractDrivePathFromFileSystemUrl(context->CrackURL(GURL(
144          "filesystem:chrome-extension://dummy-id/external/Downloads/foo"))));
145
146  // Type:"isolated" + virtual_path:"isolated_id/name" mapped on a Drive path.
147  std::string isolated_name;
148  std::string isolated_id =
149      fileapi::IsolatedContext::GetInstance()->RegisterFileSystemForPath(
150          fileapi::kFileSystemTypeNativeForPlatformApp,
151          GetDriveMountPointPath().AppendASCII("bar/buz"),
152          &isolated_name);
153  EXPECT_EQ(
154      base::FilePath::FromUTF8Unsafe(drive_mount_name + "/bar/buz"),
155      ExtractDrivePathFromFileSystemUrl(context->CrackURL(GURL(
156          "filesystem:chrome-extension://dummy-id/isolated/" +
157          isolated_id + "/" + isolated_name))));
158}
159
160TEST(FileSystemUtilTest, EscapeUnescapeCacheFileName) {
161  const std::string kUnescapedFileName(
162      "tmp:`~!@#$%^&*()-_=+[{|]}\\\\;\',<.>/?");
163  const std::string kEscapedFileName(
164      "tmp:`~!@#$%25^&*()-_=+[{|]}\\\\;\',<%2E>%2F?");
165  EXPECT_EQ(kEscapedFileName, EscapeCacheFileName(kUnescapedFileName));
166  EXPECT_EQ(kUnescapedFileName, UnescapeCacheFileName(kEscapedFileName));
167}
168
169TEST(FileSystemUtilTest, NormalizeFileName) {
170  EXPECT_EQ("", NormalizeFileName(""));
171  EXPECT_EQ("foo", NormalizeFileName("foo"));
172  // Slash
173  EXPECT_EQ("foo_zzz", NormalizeFileName("foo/zzz"));
174  EXPECT_EQ("___", NormalizeFileName("///"));
175  // Japanese hiragana "hi" + semi-voiced-mark is normalized to "pi".
176  EXPECT_EQ("\xE3\x81\xB4", NormalizeFileName("\xE3\x81\xB2\xE3\x82\x9A"));
177  // Dot
178  EXPECT_EQ("_", NormalizeFileName("."));
179  EXPECT_EQ("_", NormalizeFileName(".."));
180  EXPECT_EQ("_", NormalizeFileName("..."));
181  EXPECT_EQ(".bashrc", NormalizeFileName(".bashrc"));
182  EXPECT_EQ("._", NormalizeFileName("./"));
183}
184
185TEST(FileSystemUtilTest, GetCacheRootPath) {
186  TestingProfile profile;
187  base::FilePath profile_path = profile.GetPath();
188  EXPECT_EQ(profile_path.AppendASCII("GCache/v1"),
189            util::GetCacheRootPath(&profile));
190}
191
192TEST(FileSystemUtilTest, NeedsNamespaceMigration) {
193  // Not Drive cases.
194  EXPECT_FALSE(NeedsNamespaceMigration(
195      base::FilePath::FromUTF8Unsafe("/Downloads")));
196  EXPECT_FALSE(NeedsNamespaceMigration(
197      base::FilePath::FromUTF8Unsafe("/Downloads/x")));
198  EXPECT_FALSE(NeedsNamespaceMigration(
199      base::FilePath::FromUTF8Unsafe("/wherever/foo.txt")));
200  EXPECT_FALSE(NeedsNamespaceMigration(
201      base::FilePath::FromUTF8Unsafe("/special/foo.txt")));
202  EXPECT_FALSE(NeedsNamespaceMigration(
203      base::FilePath::FromUTF8Unsafe("/special/drivex/foo.txt")));
204  EXPECT_FALSE(NeedsNamespaceMigration(
205      base::FilePath::FromUTF8Unsafe("special/drivex/foo.txt")));
206
207  // Before migration.
208  EXPECT_TRUE(NeedsNamespaceMigration(
209      base::FilePath::FromUTF8Unsafe("/special/drive")));
210  EXPECT_TRUE(NeedsNamespaceMigration(
211      base::FilePath::FromUTF8Unsafe("/special/drive/foo.txt")));
212  EXPECT_TRUE(NeedsNamespaceMigration(
213      base::FilePath::FromUTF8Unsafe("/special/drive/subdir/foo.txt")));
214
215  // Already migrated.
216  EXPECT_FALSE(NeedsNamespaceMigration(
217      base::FilePath::FromUTF8Unsafe("/special/drive/root")));
218  EXPECT_FALSE(NeedsNamespaceMigration(
219      base::FilePath::FromUTF8Unsafe("/special/drive/root/dir1")));
220  EXPECT_FALSE(NeedsNamespaceMigration(
221      base::FilePath::FromUTF8Unsafe("/special/drive/root/root")));
222  EXPECT_FALSE(NeedsNamespaceMigration(
223      base::FilePath::FromUTF8Unsafe("/special/drive/root/root/dir1")));
224}
225
226TEST(FileSystemUtilTest, ConvertToMyDriveNamespace) {
227  // Migration cases.
228  EXPECT_EQ(base::FilePath::FromUTF8Unsafe("/special/drive/root"),
229            drive::util::ConvertToMyDriveNamespace(
230                base::FilePath::FromUTF8Unsafe("/special/drive")));
231
232  EXPECT_EQ(base::FilePath::FromUTF8Unsafe("/special/drive/root/dir1"),
233            drive::util::ConvertToMyDriveNamespace(
234                base::FilePath::FromUTF8Unsafe("/special/drive/dir1")));
235}
236
237TEST(FileSystemUtilTest, IsSpecialResourceId) {
238  EXPECT_FALSE(util::IsSpecialResourceId("abc"));
239  EXPECT_FALSE(util::IsSpecialResourceId("file:123"));
240  EXPECT_FALSE(util::IsSpecialResourceId("folder:root"));
241  EXPECT_FALSE(util::IsSpecialResourceId("folder:xyz"));
242
243  EXPECT_TRUE(util::IsSpecialResourceId("<drive>"));
244  EXPECT_TRUE(util::IsSpecialResourceId("<other>"));
245}
246
247TEST(FileSystemUtilTest, GDocFile) {
248  base::ScopedTempDir temp_dir;
249  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
250
251  GURL url("https://docs.google.com/document/d/"
252           "1YsCnrMxxgp7LDdtlFDt-WdtEIth89vA9inrILtvK-Ug/edit");
253  std::string resource_id("1YsCnrMxxgp7LDdtlFDt-WdtEIth89vA9inrILtvK-Ug");
254
255  // Read and write gdoc.
256  base::FilePath file = temp_dir.path().AppendASCII("test.gdoc");
257  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
258  EXPECT_TRUE(HasGDocFileExtension(file));
259  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
260  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
261
262  // Read and write gsheet.
263  file = temp_dir.path().AppendASCII("test.gsheet");
264  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
265  EXPECT_TRUE(HasGDocFileExtension(file));
266  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
267  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
268
269  // Read and write gslides.
270  file = temp_dir.path().AppendASCII("test.gslides");
271  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
272  EXPECT_TRUE(HasGDocFileExtension(file));
273  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
274  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
275
276  // Read and write gdraw.
277  file = temp_dir.path().AppendASCII("test.gdraw");
278  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
279  EXPECT_TRUE(HasGDocFileExtension(file));
280  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
281  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
282
283  // Read and write gtable.
284  file = temp_dir.path().AppendASCII("test.gtable");
285  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
286  EXPECT_TRUE(HasGDocFileExtension(file));
287  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
288  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
289
290  // Read and write glink.
291  file = temp_dir.path().AppendASCII("test.glink");
292  EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
293  EXPECT_TRUE(HasGDocFileExtension(file));
294  EXPECT_EQ(url, ReadUrlFromGDocFile(file));
295  EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
296
297  // Non GDoc file.
298  file = temp_dir.path().AppendASCII("test.txt");
299  std::string data = "Hello world!";
300  EXPECT_TRUE(google_apis::test_util::WriteStringToFile(file, data));
301  EXPECT_FALSE(HasGDocFileExtension(file));
302  EXPECT_TRUE(ReadUrlFromGDocFile(file).is_empty());
303  EXPECT_TRUE(ReadResourceIdFromGDocFile(file).empty());
304}
305
306}  // namespace util
307}  // namespace drive
308