|  | // Copyright 2014 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "storage/browser/fileapi/file_system_url.h" | 
|  |  | 
|  | #include <stddef.h> | 
|  |  | 
|  | #include "base/files/file_path.h" | 
|  | #include "base/macros.h" | 
|  | #include "storage/common/fileapi/file_system_types.h" | 
|  | #include "storage/common/fileapi/file_system_util.h" | 
|  | #include "testing/gtest/include/gtest/gtest.h" | 
|  | #include "url/gurl.h" | 
|  |  | 
|  | #define FPL FILE_PATH_LITERAL | 
|  |  | 
|  | #if defined(FILE_PATH_USES_DRIVE_LETTERS) | 
|  | #define DRIVE FPL("C:") | 
|  | #else | 
|  | #define DRIVE FPL("/a/") | 
|  | #endif | 
|  |  | 
|  | using storage::FileSystemURL; | 
|  | using storage::kFileSystemTypeExternal; | 
|  | using storage::kFileSystemTypeIsolated; | 
|  | using storage::kFileSystemTypePersistent; | 
|  | using storage::kFileSystemTypeTemporary; | 
|  | using storage::VirtualPath; | 
|  |  | 
|  | namespace content { | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | FileSystemURL CreateFileSystemURL(const std::string& url_string) { | 
|  | FileSystemURL url = FileSystemURL::CreateForTest(GURL(url_string)); | 
|  | EXPECT_TRUE(url.type() != kFileSystemTypeExternal && | 
|  | url.type() != kFileSystemTypeIsolated); | 
|  | return url; | 
|  | } | 
|  |  | 
|  | std::string NormalizedUTF8Path(const base::FilePath& path) { | 
|  | return path.NormalizePathSeparators().AsUTF8Unsafe(); | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | TEST(FileSystemURLTest, ParsePersistent) { | 
|  | FileSystemURL url = CreateFileSystemURL( | 
|  | "filesystem:http://chromium.org/persistent/directory/file"); | 
|  | ASSERT_TRUE(url.is_valid()); | 
|  | EXPECT_EQ("http://chromium.org/", url.origin().spec()); | 
|  | EXPECT_EQ(kFileSystemTypePersistent, url.type()); | 
|  | EXPECT_EQ(FPL("file"), VirtualPath::BaseName(url.path()).value()); | 
|  | EXPECT_EQ(FPL("directory"), url.path().DirName().value()); | 
|  | } | 
|  |  | 
|  | TEST(FileSystemURLTest, ParseTemporary) { | 
|  | FileSystemURL url = CreateFileSystemURL( | 
|  | "filesystem:http://chromium.org/temporary/directory/file"); | 
|  | ASSERT_TRUE(url.is_valid()); | 
|  | EXPECT_EQ("http://chromium.org/", url.origin().spec()); | 
|  | EXPECT_EQ(kFileSystemTypeTemporary, url.type()); | 
|  | EXPECT_EQ(FPL("file"), VirtualPath::BaseName(url.path()).value()); | 
|  | EXPECT_EQ(FPL("directory"), url.path().DirName().value()); | 
|  | } | 
|  |  | 
|  | TEST(FileSystemURLTest, EnsureFilePathIsRelative) { | 
|  | FileSystemURL url = CreateFileSystemURL( | 
|  | "filesystem:http://chromium.org/temporary/////directory/file"); | 
|  | ASSERT_TRUE(url.is_valid()); | 
|  | EXPECT_EQ("http://chromium.org/", url.origin().spec()); | 
|  | EXPECT_EQ(kFileSystemTypeTemporary, url.type()); | 
|  | EXPECT_EQ(FPL("file"), VirtualPath::BaseName(url.path()).value()); | 
|  | EXPECT_EQ(FPL("directory"), url.path().DirName().value()); | 
|  | EXPECT_FALSE(url.path().IsAbsolute()); | 
|  | } | 
|  |  | 
|  | TEST(FileSystemURLTest, RejectBadSchemes) { | 
|  | EXPECT_FALSE(CreateFileSystemURL("http://chromium.org/").is_valid()); | 
|  | EXPECT_FALSE(CreateFileSystemURL("https://chromium.org/").is_valid()); | 
|  | EXPECT_FALSE(CreateFileSystemURL("file:///foo/bar").is_valid()); | 
|  | EXPECT_FALSE(CreateFileSystemURL("foobar:///foo/bar").is_valid()); | 
|  | } | 
|  |  | 
|  | TEST(FileSystemURLTest, UnescapePath) { | 
|  | FileSystemURL url = CreateFileSystemURL( | 
|  | "filesystem:http://chromium.org/persistent/%7Echromium/space%20bar"); | 
|  | ASSERT_TRUE(url.is_valid()); | 
|  | EXPECT_EQ(FPL("space bar"), VirtualPath::BaseName(url.path()).value()); | 
|  | EXPECT_EQ(FPL("~chromium"), url.path().DirName().value()); | 
|  | } | 
|  |  | 
|  | TEST(FileSystemURLTest, RejectBadType) { | 
|  | EXPECT_FALSE(CreateFileSystemURL( | 
|  | "filesystem:http://c.org/foobar/file").is_valid()); | 
|  | EXPECT_FALSE(CreateFileSystemURL( | 
|  | "filesystem:http://c.org/temporaryfoo/file").is_valid()); | 
|  | } | 
|  |  | 
|  | TEST(FileSystemURLTest, RejectMalformedURL) { | 
|  | EXPECT_FALSE(CreateFileSystemURL("filesystem:///foobar/file").is_valid()); | 
|  | EXPECT_FALSE(CreateFileSystemURL("filesystem:foobar/file").is_valid()); | 
|  | } | 
|  |  | 
|  | TEST(FileSystemURLTest, CompareURLs) { | 
|  | const GURL urls[] = { | 
|  | GURL("filesystem:http://chromium.org/temporary/dir a/file a"), | 
|  | GURL("filesystem:http://chromium.org/temporary/dir a/file a"), | 
|  | GURL("filesystem:http://chromium.org/temporary/dir a/file b"), | 
|  | GURL("filesystem:http://chromium.org/temporary/dir a/file aa"), | 
|  | GURL("filesystem:http://chromium.org/temporary/dir b/file a"), | 
|  | GURL("filesystem:http://chromium.org/temporary/dir aa/file b"), | 
|  | GURL("filesystem:http://chromium.com/temporary/dir a/file a"), | 
|  | GURL("filesystem:https://chromium.org/temporary/dir a/file a") | 
|  | }; | 
|  |  | 
|  | FileSystemURL::Comparator compare; | 
|  | for (size_t i = 0; i < arraysize(urls); ++i) { | 
|  | for (size_t j = 0; j < arraysize(urls); ++j) { | 
|  | SCOPED_TRACE(testing::Message() << i << " < " << j); | 
|  | EXPECT_EQ(urls[i] < urls[j], | 
|  | compare(FileSystemURL::CreateForTest(urls[i]), | 
|  | FileSystemURL::CreateForTest(urls[j]))); | 
|  | } | 
|  | } | 
|  |  | 
|  | const FileSystemURL a = CreateFileSystemURL( | 
|  | "filesystem:http://chromium.org/temporary/dir a/file a"); | 
|  | const FileSystemURL b = CreateFileSystemURL( | 
|  | "filesystem:http://chromium.org/persistent/dir a/file a"); | 
|  | EXPECT_EQ(a.type() < b.type(), compare(a, b)); | 
|  | EXPECT_EQ(b.type() < a.type(), compare(b, a)); | 
|  | } | 
|  |  | 
|  | TEST(FileSystemURLTest, IsParent) { | 
|  | const std::string root1 = GetFileSystemRootURI( | 
|  | GURL("http://example.com"), kFileSystemTypeTemporary).spec(); | 
|  | const std::string root2 = GetFileSystemRootURI( | 
|  | GURL("http://example.com"), kFileSystemTypePersistent).spec(); | 
|  | const std::string root3 = GetFileSystemRootURI( | 
|  | GURL("http://chromium.org"), kFileSystemTypeTemporary).spec(); | 
|  |  | 
|  | const std::string parent("dir"); | 
|  | const std::string child("dir/child"); | 
|  | const std::string other("other"); | 
|  |  | 
|  | // True cases. | 
|  | EXPECT_TRUE(CreateFileSystemURL(root1 + parent).IsParent( | 
|  | CreateFileSystemURL(root1 + child))); | 
|  | EXPECT_TRUE(CreateFileSystemURL(root2 + parent).IsParent( | 
|  | CreateFileSystemURL(root2 + child))); | 
|  |  | 
|  | // False cases: the path is not a child. | 
|  | EXPECT_FALSE(CreateFileSystemURL(root1 + parent).IsParent( | 
|  | CreateFileSystemURL(root1 + other))); | 
|  | EXPECT_FALSE(CreateFileSystemURL(root1 + parent).IsParent( | 
|  | CreateFileSystemURL(root1 + parent))); | 
|  | EXPECT_FALSE(CreateFileSystemURL(root1 + child).IsParent( | 
|  | CreateFileSystemURL(root1 + parent))); | 
|  |  | 
|  | // False case: different types. | 
|  | EXPECT_FALSE(CreateFileSystemURL(root1 + parent).IsParent( | 
|  | CreateFileSystemURL(root2 + child))); | 
|  |  | 
|  | // False case: different origins. | 
|  | EXPECT_FALSE(CreateFileSystemURL(root1 + parent).IsParent( | 
|  | CreateFileSystemURL(root3 + child))); | 
|  | } | 
|  |  | 
|  | TEST(FileSystemURLTest, ToGURL) { | 
|  | EXPECT_TRUE(FileSystemURL().ToGURL().is_empty()); | 
|  | const char* kTestURL[] = { | 
|  | "filesystem:http://chromium.org/persistent/directory/file0", | 
|  | "filesystem:http://chromium.org/temporary/directory/file1", | 
|  | "filesystem:http://chromium.org/isolated/directory/file2", | 
|  | "filesystem:http://chromium.org/external/directory/file2", | 
|  | "filesystem:http://chromium.org/test/directory/file3", | 
|  | "filesystem:http://chromium.org/test/plus%2B/space%20/colon%3A", | 
|  | }; | 
|  |  | 
|  | for (size_t i = 0; i < arraysize(kTestURL); ++i) { | 
|  | EXPECT_EQ( | 
|  | kTestURL[i], | 
|  | FileSystemURL::CreateForTest(GURL(kTestURL[i])).ToGURL().spec()); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST(FileSystemURLTest, DebugString) { | 
|  | const GURL kOrigin("http://example.com"); | 
|  | const base::FilePath kPath(FPL("dir/file")); | 
|  |  | 
|  | const FileSystemURL kURL1 = FileSystemURL::CreateForTest( | 
|  | kOrigin, kFileSystemTypeTemporary, kPath); | 
|  | EXPECT_EQ("filesystem:http://example.com/temporary/" + | 
|  | NormalizedUTF8Path(kPath), | 
|  | kURL1.DebugString()); | 
|  | } | 
|  |  | 
|  | TEST(FileSystemURLTest, IsInSameFileSystem) { | 
|  | FileSystemURL url_foo_temp_a = FileSystemURL::CreateForTest( | 
|  | GURL("http://foo"), kFileSystemTypeTemporary, | 
|  | base::FilePath::FromUTF8Unsafe("a")); | 
|  | FileSystemURL url_foo_temp_b = FileSystemURL::CreateForTest( | 
|  | GURL("http://foo"), kFileSystemTypeTemporary, | 
|  | base::FilePath::FromUTF8Unsafe("b")); | 
|  | FileSystemURL url_foo_perm_a = FileSystemURL::CreateForTest( | 
|  | GURL("http://foo"), kFileSystemTypePersistent, | 
|  | base::FilePath::FromUTF8Unsafe("a")); | 
|  | FileSystemURL url_bar_temp_a = FileSystemURL::CreateForTest( | 
|  | GURL("http://bar"), kFileSystemTypeTemporary, | 
|  | base::FilePath::FromUTF8Unsafe("a")); | 
|  | FileSystemURL url_bar_perm_a = FileSystemURL::CreateForTest( | 
|  | GURL("http://bar"), kFileSystemTypePersistent, | 
|  | base::FilePath::FromUTF8Unsafe("a")); | 
|  |  | 
|  | EXPECT_TRUE(url_foo_temp_a.IsInSameFileSystem(url_foo_temp_a)); | 
|  | EXPECT_TRUE(url_foo_temp_a.IsInSameFileSystem(url_foo_temp_b)); | 
|  | EXPECT_FALSE(url_foo_temp_a.IsInSameFileSystem(url_foo_perm_a)); | 
|  | EXPECT_FALSE(url_foo_temp_a.IsInSameFileSystem(url_bar_temp_a)); | 
|  | EXPECT_FALSE(url_foo_temp_a.IsInSameFileSystem(url_bar_perm_a)); | 
|  | } | 
|  |  | 
|  | }  // namespace content |