file_system_url_unittest.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. // Copyright 2014 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. #include "storage/browser/file_system/file_system_url.h"
  5. #include <stddef.h>
  6. #include <utility>
  7. #include "base/files/file_path.h"
  8. #include "base/strings/string_number_conversions.h"
  9. #include "storage/common/file_system/file_system_types.h"
  10. #include "storage/common/file_system/file_system_util.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. #include "third_party/blink/public/common/storage_key/storage_key.h"
  13. #include "url/gurl.h"
  14. #define FPL FILE_PATH_LITERAL
  15. #if defined(FILE_PATH_USES_DRIVE_LETTERS)
  16. #define DRIVE FPL("C:")
  17. #else
  18. #define DRIVE FPL("/a/")
  19. #endif
  20. constexpr int kBucketId = 1;
  21. namespace storage {
  22. namespace {
  23. FileSystemURL CreateFileSystemURL(const std::string& url_string) {
  24. FileSystemURL url = FileSystemURL::CreateForTest(GURL(url_string));
  25. EXPECT_TRUE(url.type() != kFileSystemTypeExternal &&
  26. url.type() != kFileSystemTypeIsolated);
  27. return url;
  28. }
  29. std::string NormalizedUTF8Path(const base::FilePath& path) {
  30. return path.NormalizePathSeparators().AsUTF8Unsafe();
  31. }
  32. BucketLocator CreateNonDefaultBucket() {
  33. return BucketLocator(
  34. BucketId::FromUnsafeValue(kBucketId),
  35. blink::StorageKey::CreateFromStringForTesting("http://www.example.com/"),
  36. blink::mojom::StorageType::kTemporary, /*is_default=*/false);
  37. }
  38. } // namespace
  39. TEST(FileSystemURLTest, ParsePersistent) {
  40. FileSystemURL url = CreateFileSystemURL(
  41. "filesystem:http://chromium.org/persistent/directory/file");
  42. ASSERT_TRUE(url.is_valid());
  43. EXPECT_EQ("http://chromium.org/", url.origin().GetURL().spec());
  44. EXPECT_EQ(kFileSystemTypePersistent, url.type());
  45. EXPECT_EQ(FPL("file"), VirtualPath::BaseName(url.path()).value());
  46. EXPECT_EQ(FPL("directory"), url.path().DirName().value());
  47. }
  48. TEST(FileSystemURLTest, ParseTemporary) {
  49. FileSystemURL url = CreateFileSystemURL(
  50. "filesystem:http://chromium.org/temporary/directory/file");
  51. ASSERT_TRUE(url.is_valid());
  52. EXPECT_EQ("http://chromium.org/", url.origin().GetURL().spec());
  53. EXPECT_EQ(kFileSystemTypeTemporary, url.type());
  54. EXPECT_EQ(FPL("file"), VirtualPath::BaseName(url.path()).value());
  55. EXPECT_EQ(FPL("directory"), url.path().DirName().value());
  56. }
  57. TEST(FileSystemURLTest, EnsureFilePathIsRelative) {
  58. FileSystemURL url = CreateFileSystemURL(
  59. "filesystem:http://chromium.org/temporary/////directory/file");
  60. ASSERT_TRUE(url.is_valid());
  61. EXPECT_EQ("http://chromium.org/", url.origin().GetURL().spec());
  62. EXPECT_EQ(kFileSystemTypeTemporary, url.type());
  63. EXPECT_EQ(FPL("file"), VirtualPath::BaseName(url.path()).value());
  64. EXPECT_EQ(FPL("directory"), url.path().DirName().value());
  65. EXPECT_FALSE(url.path().IsAbsolute());
  66. }
  67. TEST(FileSystemURLTest, RejectBadSchemes) {
  68. EXPECT_FALSE(CreateFileSystemURL("http://chromium.org/").is_valid());
  69. EXPECT_FALSE(CreateFileSystemURL("https://chromium.org/").is_valid());
  70. EXPECT_FALSE(CreateFileSystemURL("file:///foo/bar").is_valid());
  71. EXPECT_FALSE(CreateFileSystemURL("foobar:///foo/bar").is_valid());
  72. }
  73. TEST(FileSystemURLTest, UnescapePath) {
  74. FileSystemURL url = CreateFileSystemURL(
  75. "filesystem:http://chromium.org/persistent/%7Echromium/space%20bar");
  76. ASSERT_TRUE(url.is_valid());
  77. EXPECT_EQ(FPL("space bar"), VirtualPath::BaseName(url.path()).value());
  78. EXPECT_EQ(FPL("~chromium"), url.path().DirName().value());
  79. }
  80. TEST(FileSystemURLTest, RejectBadType) {
  81. EXPECT_FALSE(
  82. CreateFileSystemURL("filesystem:http://c.org/foobar/file").is_valid());
  83. EXPECT_FALSE(CreateFileSystemURL("filesystem:http://c.org/temporaryfoo/file")
  84. .is_valid());
  85. }
  86. TEST(FileSystemURLTest, RejectMalformedURL) {
  87. EXPECT_FALSE(CreateFileSystemURL("filesystem:///foobar/file").is_valid());
  88. EXPECT_FALSE(CreateFileSystemURL("filesystem:foobar/file").is_valid());
  89. }
  90. TEST(FileSystemURLTest, CompareURLs) {
  91. const GURL urls[] = {
  92. GURL("filesystem:http://chromium.org/temporary/dir a/file a"),
  93. GURL("filesystem:http://chromium.org/temporary/dir a/file a"),
  94. GURL("filesystem:http://chromium.org/temporary/dir a/file b"),
  95. GURL("filesystem:http://chromium.org/temporary/dir a/file aa"),
  96. GURL("filesystem:http://chromium.org/temporary/dir b/file a"),
  97. GURL("filesystem:http://chromium.org/temporary/dir aa/file b"),
  98. GURL("filesystem:http://chromium.com/temporary/dir a/file a"),
  99. GURL("filesystem:https://chromium.org/temporary/dir a/file a")};
  100. FileSystemURL::Comparator compare;
  101. for (size_t i = 0; i < std::size(urls); ++i) {
  102. for (size_t j = 0; j < std::size(urls); ++j) {
  103. SCOPED_TRACE(testing::Message() << i << " < " << j);
  104. EXPECT_EQ(urls[i] < urls[j],
  105. compare(FileSystemURL::CreateForTest(urls[i]),
  106. FileSystemURL::CreateForTest(urls[j])));
  107. }
  108. }
  109. FileSystemURL a = CreateFileSystemURL(
  110. "filesystem:http://chromium.org/temporary/dir a/file a");
  111. FileSystemURL b = CreateFileSystemURL(
  112. "filesystem:http://chromium.org/persistent/dir a/file a");
  113. EXPECT_EQ(a.type() < b.type(), compare(a, b));
  114. EXPECT_EQ(b.type() < a.type(), compare(b, a));
  115. // Testing comparison between FileSystemURLs that have a non-empty,
  116. // non-default bucket value set.
  117. BucketLocator bucket = CreateNonDefaultBucket();
  118. a.SetBucket(bucket);
  119. b.SetBucket(bucket);
  120. // An identical bucket added to each URL does not alter type mismatch.
  121. EXPECT_EQ(a.type() < b.type(), compare(a, b));
  122. // c is a copy of a, just without a bucket value set.
  123. const FileSystemURL c = CreateFileSystemURL(
  124. "filesystem:http://chromium.org/temporary/dir a/file a");
  125. // Ensure that buckets are taken into consideration for comparison.
  126. EXPECT_EQ(a.bucket() < c.bucket(), compare(a, c));
  127. }
  128. TEST(FileSystemURLTest, IsParent) {
  129. const std::string root1 =
  130. GetFileSystemRootURI(GURL("http://example.com"), kFileSystemTypeTemporary)
  131. .spec();
  132. const std::string root2 = GetFileSystemRootURI(GURL("http://example.com"),
  133. kFileSystemTypePersistent)
  134. .spec();
  135. const std::string root3 = GetFileSystemRootURI(GURL("http://chromium.org"),
  136. kFileSystemTypeTemporary)
  137. .spec();
  138. const std::string parent("dir");
  139. const std::string child("dir/child");
  140. const std::string other("other");
  141. // True cases.
  142. EXPECT_TRUE(CreateFileSystemURL(root1 + parent)
  143. .IsParent(CreateFileSystemURL(root1 + child)));
  144. EXPECT_TRUE(CreateFileSystemURL(root2 + parent)
  145. .IsParent(CreateFileSystemURL(root2 + child)));
  146. // False cases: the path is not a child.
  147. EXPECT_FALSE(CreateFileSystemURL(root1 + parent)
  148. .IsParent(CreateFileSystemURL(root1 + other)));
  149. EXPECT_FALSE(CreateFileSystemURL(root1 + parent)
  150. .IsParent(CreateFileSystemURL(root1 + parent)));
  151. EXPECT_FALSE(CreateFileSystemURL(root1 + child)
  152. .IsParent(CreateFileSystemURL(root1 + parent)));
  153. // False case: different types.
  154. EXPECT_FALSE(CreateFileSystemURL(root1 + parent)
  155. .IsParent(CreateFileSystemURL(root2 + child)));
  156. // False case: different origins.
  157. EXPECT_FALSE(CreateFileSystemURL(root1 + parent)
  158. .IsParent(CreateFileSystemURL(root3 + child)));
  159. }
  160. TEST(FileSystemURLTest, ToGURL) {
  161. EXPECT_TRUE(FileSystemURL().ToGURL().is_empty());
  162. const char* kTestURL[] = {
  163. "filesystem:http://chromium.org/persistent/directory/file0",
  164. "filesystem:http://chromium.org/temporary/directory/file1",
  165. "filesystem:http://chromium.org/isolated/directory/file2",
  166. "filesystem:http://chromium.org/external/directory/file2",
  167. "filesystem:http://chromium.org/test/directory/file3",
  168. "filesystem:http://chromium.org/test/plus%2B/space%20/colon%3A",
  169. };
  170. for (const char* url : kTestURL)
  171. EXPECT_EQ(url, FileSystemURL::CreateForTest(GURL(url)).ToGURL().spec());
  172. }
  173. TEST(FileSystemURLTest, DebugString) {
  174. const base::FilePath kPath(FPL("dir/file"));
  175. const FileSystemURL kURL1 = FileSystemURL::CreateForTest(
  176. blink::StorageKey::CreateFromStringForTesting("http://example.com"),
  177. kFileSystemTypeTemporary, kPath);
  178. EXPECT_EQ("{ uri: filesystem:http://example.com/temporary/" +
  179. NormalizedUTF8Path(kPath) +
  180. ", storage key: " + kURL1.storage_key().GetDebugString() + " }",
  181. kURL1.DebugString());
  182. const FileSystemURL kURL2 = FileSystemURL::CreateForTest(
  183. blink::StorageKey::CreateFromStringForTesting("http://example.com"),
  184. kFileSystemTypeLocal, kPath);
  185. EXPECT_EQ("{ path: " + NormalizedUTF8Path(kPath) +
  186. ", storage key: " + kURL1.storage_key().GetDebugString() + " }",
  187. kURL2.DebugString());
  188. FileSystemURL kURL3 = FileSystemURL::CreateForTest(
  189. blink::StorageKey::CreateFromStringForTesting("http://example.com"),
  190. kFileSystemTypeTemporary, kPath);
  191. kURL3.SetBucket(CreateNonDefaultBucket());
  192. EXPECT_EQ("{ uri: filesystem:http://example.com/temporary/" +
  193. NormalizedUTF8Path(kPath) +
  194. ", storage key: " + kURL3.storage_key().GetDebugString() +
  195. ", bucket id: " + base::NumberToString(kBucketId) + " }",
  196. kURL3.DebugString());
  197. }
  198. TEST(FileSystemURLTest, IsInSameFileSystem) {
  199. FileSystemURL url_foo_temp_a = FileSystemURL::CreateForTest(
  200. blink::StorageKey::CreateFromStringForTesting("http://foo"),
  201. kFileSystemTypeTemporary, base::FilePath::FromUTF8Unsafe("a"));
  202. FileSystemURL url_foo_temp_b = FileSystemURL::CreateForTest(
  203. blink::StorageKey::CreateFromStringForTesting("http://foo"),
  204. kFileSystemTypeTemporary, base::FilePath::FromUTF8Unsafe("b"));
  205. FileSystemURL url_foo_perm_a = FileSystemURL::CreateForTest(
  206. blink::StorageKey::CreateFromStringForTesting("http://foo"),
  207. kFileSystemTypePersistent, base::FilePath::FromUTF8Unsafe("a"));
  208. FileSystemURL url_bar_temp_a = FileSystemURL::CreateForTest(
  209. blink::StorageKey::CreateFromStringForTesting("http://bar"),
  210. kFileSystemTypeTemporary, base::FilePath::FromUTF8Unsafe("a"));
  211. FileSystemURL url_bar_perm_a = FileSystemURL::CreateForTest(
  212. blink::StorageKey::CreateFromStringForTesting("http://bar"),
  213. kFileSystemTypePersistent, base::FilePath::FromUTF8Unsafe("a"));
  214. EXPECT_TRUE(url_foo_temp_a.IsInSameFileSystem(url_foo_temp_a));
  215. EXPECT_TRUE(url_foo_temp_a.IsInSameFileSystem(url_foo_temp_b));
  216. EXPECT_FALSE(url_foo_temp_a.IsInSameFileSystem(url_foo_perm_a));
  217. EXPECT_FALSE(url_foo_temp_a.IsInSameFileSystem(url_bar_temp_a));
  218. EXPECT_FALSE(url_foo_temp_a.IsInSameFileSystem(url_bar_perm_a));
  219. // Test that non-empty, non-default bucket values are taken into account when
  220. // determining of two URLs are in the same FileSystem.
  221. BucketLocator bucket = CreateNonDefaultBucket();
  222. url_foo_temp_a.SetBucket(bucket);
  223. url_foo_temp_b.SetBucket(bucket);
  224. EXPECT_TRUE(url_foo_temp_a.IsInSameFileSystem(url_foo_temp_b));
  225. // url_foo_temp_c is identical to url_foo_temp_a but without a bucket value.
  226. FileSystemURL url_foo_temp_c = FileSystemURL::CreateForTest(
  227. blink::StorageKey::CreateFromStringForTesting("http://foo"),
  228. kFileSystemTypeTemporary, base::FilePath::FromUTF8Unsafe("a"));
  229. EXPECT_FALSE(url_foo_temp_a.IsInSameFileSystem(url_foo_temp_c));
  230. }
  231. TEST(FileSystemURLTest, ValidAfterMoves) {
  232. // Move constructor.
  233. {
  234. FileSystemURL original = FileSystemURL::CreateForTest(
  235. blink::StorageKey::CreateFromStringForTesting("http://foo"),
  236. kFileSystemTypeTemporary, base::FilePath::FromUTF8Unsafe("a"));
  237. EXPECT_TRUE(original.is_valid());
  238. FileSystemURL new_url(std::move(original));
  239. EXPECT_TRUE(new_url.is_valid());
  240. EXPECT_TRUE(original.is_valid());
  241. }
  242. // Move operator.
  243. {
  244. FileSystemURL original = FileSystemURL::CreateForTest(
  245. blink::StorageKey::CreateFromStringForTesting("http://foo"),
  246. kFileSystemTypeTemporary, base::FilePath::FromUTF8Unsafe("a"));
  247. EXPECT_TRUE(original.is_valid());
  248. FileSystemURL new_url;
  249. new_url = std::move(std::move(original));
  250. EXPECT_TRUE(new_url.is_valid());
  251. EXPECT_TRUE(original.is_valid());
  252. }
  253. }
  254. } // namespace storage