- add sources.
[platform/framework/web/crosswalk.git] / src / webkit / browser / fileapi / external_mount_points_unittest.cc
1 // Copyright (c) 2013 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 "webkit/browser/fileapi/external_mount_points.h"
6
7 #include <string>
8
9 #include "base/files/file_path.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "webkit/browser/fileapi/file_system_url.h"
12
13 #define FPL FILE_PATH_LITERAL
14
15 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
16 #define DRIVE FPL("C:")
17 #else
18 #define DRIVE
19 #endif
20
21 using fileapi::FileSystemURL;
22
23 namespace {
24
25 TEST(ExternalMountPointsTest, AddMountPoint) {
26   scoped_refptr<fileapi::ExternalMountPoints> mount_points(
27       fileapi::ExternalMountPoints::CreateRefCounted());
28
29   struct TestCase {
30     // The mount point's name.
31     const char* const name;
32     // The mount point's path.
33     const base::FilePath::CharType* const path;
34     // Whether the mount point registration should succeed.
35     bool success;
36     // Path returned by GetRegisteredPath. NULL if the method is expected to
37     // fail.
38     const base::FilePath::CharType* const registered_path;
39   };
40
41   const TestCase kTestCases[] = {
42     // Valid mount point.
43     { "test", DRIVE FPL("/foo/test"), true, DRIVE FPL("/foo/test") },
44     // Valid mount point with only one path component.
45     { "bbb", DRIVE FPL("/bbb"), true, DRIVE FPL("/bbb") },
46     // Existing mount point path is substring of the mount points path.
47     { "test11", DRIVE FPL("/foo/test11"), true, DRIVE FPL("/foo/test11") },
48     // Path substring of an existing path.
49     { "test1", DRIVE FPL("/foo/test1"), true, DRIVE FPL("/foo/test1") },
50     // Empty mount point name and path.
51     { "", DRIVE FPL(""), false, NULL },
52     // Empty mount point name.
53     { "", DRIVE FPL("/ddd"), false, NULL },
54     // Empty mount point path.
55     { "empty_path", FPL(""), true, FPL("") },
56     // Name different from path's base name.
57     { "not_base_name", DRIVE FPL("/x/y/z"), true, DRIVE FPL("/x/y/z") },
58     // References parent.
59     { "invalid", DRIVE FPL("../foo/invalid"), false, NULL },
60     // Relative path.
61     { "relative", DRIVE FPL("foo/relative"), false, NULL },
62     // Existing mount point path.
63     { "path_exists", DRIVE FPL("/foo/test"), false, NULL },
64     // Mount point with the same name exists.
65     { "test", DRIVE FPL("/foo/a/test_name_exists"), false,
66       DRIVE FPL("/foo/test") },
67     // Child of an existing mount point.
68     { "a1", DRIVE FPL("/foo/test/a"), false, NULL },
69     // Parent of an existing mount point.
70     { "foo1", DRIVE FPL("/foo"), false, NULL },
71     // Bit bigger depth.
72     { "g", DRIVE FPL("/foo/a/b/c/d/e/f/g"), true,
73       DRIVE FPL("/foo/a/b/c/d/e/f/g") },
74     // Sibling mount point (with similar name) exists.
75     { "ff", DRIVE FPL("/foo/a/b/c/d/e/ff"), true,
76        DRIVE FPL("/foo/a/b/c/d/e/ff") },
77     // Lexicographically last among existing mount points.
78     { "yyy", DRIVE FPL("/zzz/yyy"), true, DRIVE FPL("/zzz/yyy") },
79     // Parent of the lexicographically last mount point.
80     { "zzz1", DRIVE FPL("/zzz"), false, NULL },
81     // Child of the lexicographically last mount point.
82     { "xxx1", DRIVE FPL("/zzz/yyy/xxx"), false, NULL },
83     // Lexicographically first among existing mount points.
84     { "b", DRIVE FPL("/a/b"), true, DRIVE FPL("/a/b") },
85     // Parent of lexicographically first mount point.
86     { "a2", DRIVE FPL("/a"), false, NULL },
87     // Child of lexicographically last mount point.
88     { "c1", DRIVE FPL("/a/b/c"), false, NULL },
89     // Parent to all of the mount points.
90     { "root", DRIVE FPL("/"), false, NULL },
91     // Path contains .. component.
92     { "funky", DRIVE FPL("/tt/fun/../funky"), false, NULL },
93     // Windows separators.
94 #if defined(FILE_PATH_USES_WIN_SEPARATORS)
95     { "win", DRIVE FPL("\\try\\separators\\win"), true,
96       DRIVE FPL("\\try\\separators\\win") },
97     { "win1", DRIVE FPL("\\try/separators\\win1"), true,
98       DRIVE FPL("\\try/separators\\win1") },
99     { "win2", DRIVE FPL("\\try/separators\\win"), false, NULL },
100 #else
101     { "win", DRIVE FPL("\\separators\\win"), false, NULL },
102     { "win1", DRIVE FPL("\\try/separators\\win1"), false, NULL },
103 #endif
104     // Win separators, but relative path.
105     { "win2", DRIVE FPL("try\\separators\\win2"), false, NULL },
106   };
107
108   // Test adding mount points.
109   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
110     EXPECT_EQ(kTestCases[i].success,
111               mount_points->RegisterFileSystem(
112                   kTestCases[i].name,
113                   fileapi::kFileSystemTypeNativeLocal,
114                   base::FilePath(kTestCases[i].path)))
115         << "Adding mount point: " << kTestCases[i].name << " with path "
116         << kTestCases[i].path;
117   }
118
119   // Test that final mount point presence state is as expected.
120   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
121     base::FilePath found_path;
122     EXPECT_EQ(kTestCases[i].registered_path != NULL,
123               mount_points->GetRegisteredPath(kTestCases[i].name, &found_path))
124         << "Test case: " << i;
125
126     if (kTestCases[i].registered_path) {
127       base::FilePath expected_path(kTestCases[i].registered_path);
128       EXPECT_EQ(expected_path.NormalizePathSeparators(), found_path);
129     }
130   }
131 }
132
133 TEST(ExternalMountPointsTest, GetVirtualPath) {
134   scoped_refptr<fileapi::ExternalMountPoints> mount_points(
135       fileapi::ExternalMountPoints::CreateRefCounted());
136
137   mount_points->RegisterFileSystem("c",
138                                    fileapi::kFileSystemTypeNativeLocal,
139                                    base::FilePath(DRIVE FPL("/a/b/c")));
140   // Note that "/a/b/c" < "/a/b/c(1)" < "/a/b/c/".
141   mount_points->RegisterFileSystem("c(1)",
142                                    fileapi::kFileSystemTypeNativeLocal,
143                                    base::FilePath(DRIVE FPL("/a/b/c(1)")));
144   mount_points->RegisterFileSystem("x",
145                                    fileapi::kFileSystemTypeNativeLocal,
146                                    base::FilePath(DRIVE FPL("/z/y/x")));
147   mount_points->RegisterFileSystem("o",
148                                    fileapi::kFileSystemTypeNativeLocal,
149                                    base::FilePath(DRIVE FPL("/m/n/o")));
150   // A mount point whose name does not match its path base name.
151   mount_points->RegisterFileSystem("mount",
152                                    fileapi::kFileSystemTypeNativeLocal,
153                                    base::FilePath(DRIVE FPL("/root/foo")));
154   // A mount point with an empty path.
155   mount_points->RegisterFileSystem("empty_path",
156                                    fileapi::kFileSystemTypeNativeLocal,
157                                    base::FilePath());
158
159   struct TestCase {
160     const base::FilePath::CharType* const local_path;
161     bool success;
162     const base::FilePath::CharType* const virtual_path;
163   };
164
165   const TestCase kTestCases[] = {
166     // Empty path.
167     { FPL(""), false, FPL("") },
168     // No registered mount point (but is parent to a mount point).
169     { DRIVE FPL("/a/b"), false, FPL("") },
170     // No registered mount point (but is parent to a mount point).
171     { DRIVE FPL("/z/y"), false, FPL("") },
172     // No registered mount point (but is parent to a mount point).
173     { DRIVE FPL("/m/n"), false, FPL("") },
174     // No registered mount point.
175     { DRIVE FPL("/foo/mount"), false, FPL("") },
176     // An existing mount point path is substring.
177     { DRIVE FPL("/a/b/c1"), false, FPL("") },
178     // No leading /.
179     { DRIVE FPL("a/b/c"), false, FPL("") },
180     // Sibling to a root path.
181     { DRIVE FPL("/a/b/d/e"), false, FPL("") },
182     // Sibling to a root path.
183     { DRIVE FPL("/z/y/v/u"), false, FPL("") },
184     // Sibling to a root path.
185     { DRIVE FPL("/m/n/p/q"), false, FPL("") },
186     // Mount point root path.
187     { DRIVE FPL("/a/b/c"), true, FPL("c") },
188     // Mount point root path.
189     { DRIVE FPL("/z/y/x"), true, FPL("x") },
190     // Mount point root path.
191     { DRIVE FPL("/m/n/o"), true, FPL("o") },
192     // Mount point child path.
193     { DRIVE FPL("/a/b/c/d/e"), true, FPL("c/d/e") },
194     // Mount point child path.
195     { DRIVE FPL("/z/y/x/v/u"), true, FPL("x/v/u") },
196     // Mount point child path.
197     { DRIVE FPL("/m/n/o/p/q"), true, FPL("o/p/q") },
198     // Name doesn't match mount point path base name.
199     { DRIVE FPL("/root/foo/a/b/c"), true, FPL("mount/a/b/c") },
200     { DRIVE FPL("/root/foo"), true, FPL("mount") },
201     // Mount point contains character whose ASCII code is smaller than file path
202     // separator's.
203     { DRIVE FPL("/a/b/c(1)/d/e"), true, FPL("c(1)/d/e") },
204 #if defined(FILE_PATH_USES_WIN_SEPARATORS)
205     // Path with win separators mixed in.
206     { DRIVE FPL("/a\\b\\c/d"), true, FPL("c/d") },
207 #endif
208   };
209
210   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
211     // Initialize virtual path with a value.
212     base::FilePath virtual_path(DRIVE FPL("/mount"));
213     base::FilePath local_path(kTestCases[i].local_path);
214     EXPECT_EQ(kTestCases[i].success,
215               mount_points->GetVirtualPath(local_path, &virtual_path))
216         << "Resolving " << kTestCases[i].local_path;
217
218     // There are no guarantees for |virtual_path| value if |GetVirtualPath|
219     // fails.
220     if (!kTestCases[i].success)
221       continue;
222
223     base::FilePath expected_virtual_path(kTestCases[i].virtual_path);
224     EXPECT_EQ(expected_virtual_path.NormalizePathSeparators(), virtual_path)
225         << "Resolving " << kTestCases[i].local_path;
226   }
227 }
228
229 TEST(ExternalMountPointsTest, HandlesFileSystemMountType) {
230   scoped_refptr<fileapi::ExternalMountPoints> mount_points(
231       fileapi::ExternalMountPoints::CreateRefCounted());
232
233   const GURL test_origin("http://chromium.org");
234   const base::FilePath test_path(FPL("/mount"));
235
236   // Should handle External File System.
237   EXPECT_TRUE(mount_points->HandlesFileSystemMountType(
238       fileapi::kFileSystemTypeExternal));
239
240   // Shouldn't handle the rest.
241   EXPECT_FALSE(mount_points->HandlesFileSystemMountType(
242       fileapi::kFileSystemTypeIsolated));
243   EXPECT_FALSE(mount_points->HandlesFileSystemMountType(
244       fileapi::kFileSystemTypeTemporary));
245   EXPECT_FALSE(mount_points->HandlesFileSystemMountType(
246       fileapi::kFileSystemTypePersistent));
247   EXPECT_FALSE(mount_points->HandlesFileSystemMountType(
248       fileapi::kFileSystemTypeTest));
249   // Not even if it's external subtype.
250   EXPECT_FALSE(mount_points->HandlesFileSystemMountType(
251       fileapi::kFileSystemTypeNativeLocal));
252   EXPECT_FALSE(mount_points->HandlesFileSystemMountType(
253       fileapi::kFileSystemTypeRestrictedNativeLocal));
254   EXPECT_FALSE(mount_points->HandlesFileSystemMountType(
255       fileapi::kFileSystemTypeDrive));
256   EXPECT_FALSE(mount_points->HandlesFileSystemMountType(
257       fileapi::kFileSystemTypeSyncable));
258 }
259
260 TEST(ExternalMountPointsTest, CreateCrackedFileSystemURL) {
261   scoped_refptr<fileapi::ExternalMountPoints> mount_points(
262       fileapi::ExternalMountPoints::CreateRefCounted());
263
264   const GURL kTestOrigin("http://chromium.org");
265
266   mount_points->RegisterFileSystem("c",
267                                    fileapi::kFileSystemTypeNativeLocal,
268                                    base::FilePath(DRIVE FPL("/a/b/c")));
269   mount_points->RegisterFileSystem("c(1)",
270                                    fileapi::kFileSystemTypeDrive,
271                                    base::FilePath(DRIVE FPL("/a/b/c(1)")));
272   mount_points->RegisterFileSystem("empty_path",
273                                    fileapi::kFileSystemTypeSyncable,
274                                    base::FilePath());
275   mount_points->RegisterFileSystem("mount",
276                                    fileapi::kFileSystemTypeDrive,
277                                    base::FilePath(DRIVE FPL("/root")));
278
279   // Try cracking invalid GURL.
280   FileSystemURL invalid = mount_points->CrackURL(GURL("http://chromium.og"));
281   EXPECT_FALSE(invalid.is_valid());
282
283   // Try cracking isolated path.
284   FileSystemURL isolated = mount_points->CreateCrackedFileSystemURL(
285       kTestOrigin, fileapi::kFileSystemTypeIsolated, base::FilePath(FPL("c")));
286   EXPECT_FALSE(isolated.is_valid());
287
288   // Try native local which is not cracked.
289   FileSystemURL native_local = mount_points->CreateCrackedFileSystemURL(
290       kTestOrigin,
291       fileapi::kFileSystemTypeNativeLocal,
292       base::FilePath(FPL("c")));
293   EXPECT_FALSE(native_local.is_valid());
294
295   struct TestCase {
296     const base::FilePath::CharType* const path;
297     bool expect_valid;
298     fileapi::FileSystemType expect_type;
299     const base::FilePath::CharType* const expect_path;
300     const char* const expect_fs_id;
301   };
302
303   const TestCase kTestCases[] = {
304     { FPL("c/d/e"),
305       true, fileapi::kFileSystemTypeNativeLocal, DRIVE FPL("/a/b/c/d/e"), "c" },
306     { FPL("c(1)/d/e"),
307       true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/a/b/c(1)/d/e"), "c(1)" },
308     { FPL("c(1)"),
309       true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/a/b/c(1)"), "c(1)" },
310     { FPL("empty_path/a"),
311       true, fileapi::kFileSystemTypeSyncable, FPL("a"), "empty_path" },
312     { FPL("empty_path"),
313       true, fileapi::kFileSystemTypeSyncable, FPL(""), "empty_path" },
314     { FPL("mount/a/b"),
315       true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/root/a/b"), "mount" },
316     { FPL("mount"),
317       true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/root"), "mount" },
318     { FPL("cc"),
319       false, fileapi::kFileSystemTypeUnknown, FPL(""), "" },
320     { FPL(""),
321       false, fileapi::kFileSystemTypeUnknown, FPL(""), "" },
322     { FPL(".."),
323       false, fileapi::kFileSystemTypeUnknown, FPL(""), "" },
324     // Absolte paths.
325     { FPL("/c/d/e"),
326       false, fileapi::kFileSystemTypeUnknown, FPL(""), "" },
327     { FPL("/c(1)/d/e"),
328       false, fileapi::kFileSystemTypeUnknown, FPL(""), "" },
329     { FPL("/empty_path"),
330       false, fileapi::kFileSystemTypeUnknown, FPL(""), "" },
331     // PAth references parent.
332     { FPL("c/d/../e"),
333       false, fileapi::kFileSystemTypeUnknown, FPL(""), "" },
334     { FPL("/empty_path/a/../b"),
335       false, fileapi::kFileSystemTypeUnknown, FPL(""), "" },
336 #if defined(FILE_PATH_USES_WIN_SEPARATORS)
337     { FPL("c/d\\e"),
338       true, fileapi::kFileSystemTypeNativeLocal, DRIVE FPL("/a/b/c/d/e"), "c" },
339     { FPL("mount\\a\\b"),
340       true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/root/a/b"), "mount" },
341 #endif
342   };
343
344   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
345     FileSystemURL cracked = mount_points->CreateCrackedFileSystemURL(
346         kTestOrigin,
347         fileapi::kFileSystemTypeExternal,
348         base::FilePath(kTestCases[i].path));
349
350     EXPECT_EQ(kTestCases[i].expect_valid, cracked.is_valid())
351         << "Test case index: " << i;
352
353     if (!kTestCases[i].expect_valid)
354       continue;
355
356     EXPECT_EQ(kTestOrigin, cracked.origin())
357         << "Test case index: " << i;
358     EXPECT_EQ(kTestCases[i].expect_type, cracked.type())
359         << "Test case index: " << i;
360     EXPECT_EQ(base::FilePath(
361         kTestCases[i].expect_path).NormalizePathSeparators(), cracked.path())
362         << "Test case index: " << i;
363     EXPECT_EQ(base::FilePath(kTestCases[i].path).NormalizePathSeparators(),
364                        cracked.virtual_path())
365         << "Test case index: " << i;
366     EXPECT_EQ(kTestCases[i].expect_fs_id, cracked.filesystem_id())
367         << "Test case index: " << i;
368     EXPECT_EQ(fileapi::kFileSystemTypeExternal, cracked.mount_type())
369         << "Test case index: " << i;
370   }
371 }
372
373 TEST(ExternalMountPointsTest, CrackVirtualPath) {
374   scoped_refptr<fileapi::ExternalMountPoints> mount_points(
375       fileapi::ExternalMountPoints::CreateRefCounted());
376
377   const GURL kTestOrigin("http://chromium.org");
378
379   mount_points->RegisterFileSystem("c",
380                                    fileapi::kFileSystemTypeNativeLocal,
381                                    base::FilePath(DRIVE FPL("/a/b/c")));
382   mount_points->RegisterFileSystem("c(1)",
383                                    fileapi::kFileSystemTypeDrive,
384                                    base::FilePath(DRIVE FPL("/a/b/c(1)")));
385   mount_points->RegisterFileSystem("empty_path",
386                                    fileapi::kFileSystemTypeSyncable,
387                                    base::FilePath());
388   mount_points->RegisterFileSystem("mount",
389                                    fileapi::kFileSystemTypeDrive,
390                                    base::FilePath(DRIVE FPL("/root")));
391
392   struct TestCase {
393     const base::FilePath::CharType* const path;
394     bool expect_valid;
395     fileapi::FileSystemType expect_type;
396     const base::FilePath::CharType* const expect_path;
397     const char* const expect_name;
398   };
399
400   const TestCase kTestCases[] = {
401     { FPL("c/d/e"),
402       true, fileapi::kFileSystemTypeNativeLocal, DRIVE FPL("/a/b/c/d/e"), "c" },
403     { FPL("c(1)/d/e"),
404       true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/a/b/c(1)/d/e"), "c(1)" },
405     { FPL("c(1)"),
406       true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/a/b/c(1)"), "c(1)" },
407     { FPL("empty_path/a"),
408       true, fileapi::kFileSystemTypeSyncable, FPL("a"), "empty_path" },
409     { FPL("empty_path"),
410       true, fileapi::kFileSystemTypeSyncable, FPL(""), "empty_path" },
411     { FPL("mount/a/b"),
412       true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/root/a/b"), "mount" },
413     { FPL("mount"),
414       true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/root"), "mount" },
415     { FPL("cc"),
416       false, fileapi::kFileSystemTypeUnknown, FPL(""), "" },
417     { FPL(""),
418       false, fileapi::kFileSystemTypeUnknown, FPL(""), "" },
419     { FPL(".."),
420       false, fileapi::kFileSystemTypeUnknown, FPL(""), "" },
421     // Absolte paths.
422     { FPL("/c/d/e"),
423       false, fileapi::kFileSystemTypeUnknown, FPL(""), "" },
424     { FPL("/c(1)/d/e"),
425       false, fileapi::kFileSystemTypeUnknown, FPL(""), "" },
426     { FPL("/empty_path"),
427       false, fileapi::kFileSystemTypeUnknown, FPL(""), "" },
428     // PAth references parent.
429     { FPL("c/d/../e"),
430       false, fileapi::kFileSystemTypeUnknown, FPL(""), "" },
431     { FPL("/empty_path/a/../b"),
432       false, fileapi::kFileSystemTypeUnknown, FPL(""), "" },
433 #if defined(FILE_PATH_USES_WIN_SEPARATORS)
434     { FPL("c/d\\e"),
435       true, fileapi::kFileSystemTypeNativeLocal, DRIVE FPL("/a/b/c/d/e"), "c" },
436     { FPL("mount\\a\\b"),
437       true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/root/a/b"), "mount" },
438 #endif
439   };
440
441   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
442     std::string cracked_name;
443     fileapi::FileSystemType cracked_type;
444     base::FilePath cracked_path;
445     EXPECT_EQ(kTestCases[i].expect_valid,
446               mount_points->CrackVirtualPath(base::FilePath(kTestCases[i].path),
447                   &cracked_name, &cracked_type, &cracked_path))
448         << "Test case index: " << i;
449
450     if (!kTestCases[i].expect_valid)
451       continue;
452
453     EXPECT_EQ(kTestCases[i].expect_type, cracked_type)
454         << "Test case index: " << i;
455     EXPECT_EQ(base::FilePath(
456         kTestCases[i].expect_path).NormalizePathSeparators(), cracked_path)
457         << "Test case index: " << i;
458     EXPECT_EQ(kTestCases[i].expect_name, cracked_name)
459         << "Test case index: " << i;
460   }
461 }
462
463 }  // namespace
464