blob: f78865ebd3a8a041e8c749c0e6ca2ac08935ca1f [file] [log] [blame]
// Copyright (c) 2012 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 "chrome/browser/chromeos/drive/file_system_util.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/test_file_system_options.h"
#include "google_apis/drive/test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/browser/fileapi/external_mount_points.h"
#include "webkit/browser/fileapi/file_system_backend.h"
#include "webkit/browser/fileapi/file_system_context.h"
#include "webkit/browser/fileapi/file_system_url.h"
#include "webkit/browser/fileapi/isolated_context.h"
namespace drive {
namespace util {
TEST(FileSystemUtilTest, FilePathToDriveURL) {
base::FilePath path;
// Path with alphabets and numbers.
path = GetDriveMyDriveRootPath().AppendASCII("foo/bar012.txt");
EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
// Path with symbols.
path = GetDriveMyDriveRootPath().AppendASCII(
" !\"#$%&'()*+,-.:;<=>?@[\\]^_`{|}~");
EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
// Path with '%'.
path = GetDriveMyDriveRootPath().AppendASCII("%19%20%21.txt");
EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
// Path with multi byte characters.
base::string16 utf16_string;
utf16_string.push_back(0x307b); // HIRAGANA_LETTER_HO
utf16_string.push_back(0x3052); // HIRAGANA_LETTER_GE
path = GetDriveMyDriveRootPath().Append(
base::FilePath::FromUTF8Unsafe(UTF16ToUTF8(utf16_string) + ".txt"));
EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
}
TEST(FileSystemUtilTest, IsUnderDriveMountPoint) {
EXPECT_FALSE(IsUnderDriveMountPoint(
base::FilePath::FromUTF8Unsafe("/wherever/foo.txt")));
EXPECT_FALSE(IsUnderDriveMountPoint(
base::FilePath::FromUTF8Unsafe("/special/foo.txt")));
EXPECT_FALSE(IsUnderDriveMountPoint(
base::FilePath::FromUTF8Unsafe("/special/drivex/foo.txt")));
EXPECT_FALSE(IsUnderDriveMountPoint(
base::FilePath::FromUTF8Unsafe("special/drivex/foo.txt")));
EXPECT_TRUE(IsUnderDriveMountPoint(
base::FilePath::FromUTF8Unsafe("/special/drive")));
EXPECT_TRUE(IsUnderDriveMountPoint(
base::FilePath::FromUTF8Unsafe("/special/drive/foo.txt")));
EXPECT_TRUE(IsUnderDriveMountPoint(
base::FilePath::FromUTF8Unsafe("/special/drive/subdir/foo.txt")));
}
TEST(FileSystemUtilTest, ExtractDrivePath) {
EXPECT_EQ(base::FilePath(),
ExtractDrivePath(
base::FilePath::FromUTF8Unsafe("/wherever/foo.txt")));
EXPECT_EQ(base::FilePath(),
ExtractDrivePath(
base::FilePath::FromUTF8Unsafe("/special/foo.txt")));
EXPECT_EQ(base::FilePath(),
ExtractDrivePath(
base::FilePath::FromUTF8Unsafe("/special/drivex/foo.txt")));
EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive"),
ExtractDrivePath(
base::FilePath::FromUTF8Unsafe("/special/drive")));
EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/foo.txt"),
ExtractDrivePath(
base::FilePath::FromUTF8Unsafe("/special/drive/foo.txt")));
EXPECT_EQ(base::FilePath::FromUTF8Unsafe("drive/subdir/foo.txt"),
ExtractDrivePath(base::FilePath::FromUTF8Unsafe(
"/special/drive/subdir/foo.txt")));
}
TEST(FileSystemUtilTest, ExtractDrivePathFromFileSystemUrl) {
// Set up file system context for testing.
base::ScopedTempDir temp_dir_;
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base::MessageLoop message_loop;
scoped_refptr<fileapi::ExternalMountPoints> mount_points =
fileapi::ExternalMountPoints::CreateRefCounted();
scoped_refptr<fileapi::FileSystemContext> context(
new fileapi::FileSystemContext(
base::MessageLoopProxy::current().get(),
base::MessageLoopProxy::current().get(),
mount_points.get(),
NULL, // special_storage_policy
NULL, // quota_manager_proxy,
ScopedVector<fileapi::FileSystemBackend>(),
temp_dir_.path(), // partition_path
fileapi::CreateAllowFileAccessOptions()));
// Type:"external" + virtual_path:"drive/foo/bar" resolves to "drive/foo/bar".
const std::string& drive_mount_name =
GetDriveMountPointPath().BaseName().AsUTF8Unsafe();
mount_points->RegisterFileSystem(
drive_mount_name,
fileapi::kFileSystemTypeDrive,
fileapi::FileSystemMountOption(),
GetDriveMountPointPath());
EXPECT_EQ(
base::FilePath::FromUTF8Unsafe(drive_mount_name + "/foo/bar"),
ExtractDrivePathFromFileSystemUrl(context->CrackURL(GURL(
"filesystem:chrome-extension://dummy-id/external/" +
drive_mount_name + "/foo/bar"))));
// Virtual mount name should not affect the extracted path.
mount_points->RevokeFileSystem(drive_mount_name);
mount_points->RegisterFileSystem(
"drive2",
fileapi::kFileSystemTypeDrive,
fileapi::FileSystemMountOption(),
GetDriveMountPointPath());
EXPECT_EQ(
base::FilePath::FromUTF8Unsafe(drive_mount_name + "/foo/bar"),
ExtractDrivePathFromFileSystemUrl(context->CrackURL(GURL(
"filesystem:chrome-extension://dummy-id/external/drive2/foo/bar"))));
// Type:"external" + virtual_path:"Downloads/foo" is not a Drive path.
mount_points->RegisterFileSystem(
"Downloads",
fileapi::kFileSystemTypeNativeLocal,
fileapi::FileSystemMountOption(),
temp_dir_.path());
EXPECT_EQ(
base::FilePath(),
ExtractDrivePathFromFileSystemUrl(context->CrackURL(GURL(
"filesystem:chrome-extension://dummy-id/external/Downloads/foo"))));
// Type:"isolated" + virtual_path:"isolated_id/name" mapped on a Drive path.
std::string isolated_name;
std::string isolated_id =
fileapi::IsolatedContext::GetInstance()->RegisterFileSystemForPath(
fileapi::kFileSystemTypeNativeForPlatformApp,
GetDriveMountPointPath().AppendASCII("bar/buz"),
&isolated_name);
EXPECT_EQ(
base::FilePath::FromUTF8Unsafe(drive_mount_name + "/bar/buz"),
ExtractDrivePathFromFileSystemUrl(context->CrackURL(GURL(
"filesystem:chrome-extension://dummy-id/isolated/" +
isolated_id + "/" + isolated_name))));
}
TEST(FileSystemUtilTest, EscapeUnescapeCacheFileName) {
const std::string kUnescapedFileName(
"tmp:`~!@#$%^&*()-_=+[{|]}\\\\;\',<.>/?");
const std::string kEscapedFileName(
"tmp:`~!@#$%25^&*()-_=+[{|]}\\\\;\',<%2E>%2F?");
EXPECT_EQ(kEscapedFileName, EscapeCacheFileName(kUnescapedFileName));
EXPECT_EQ(kUnescapedFileName, UnescapeCacheFileName(kEscapedFileName));
}
TEST(FileSystemUtilTest, NormalizeFileName) {
EXPECT_EQ("", NormalizeFileName(""));
EXPECT_EQ("foo", NormalizeFileName("foo"));
// Slash
EXPECT_EQ("foo_zzz", NormalizeFileName("foo/zzz"));
EXPECT_EQ("___", NormalizeFileName("///"));
// Japanese hiragana "hi" + semi-voiced-mark is normalized to "pi".
EXPECT_EQ("\xE3\x81\xB4", NormalizeFileName("\xE3\x81\xB2\xE3\x82\x9A"));
// Dot
EXPECT_EQ("_", NormalizeFileName("."));
EXPECT_EQ("_", NormalizeFileName(".."));
EXPECT_EQ("_", NormalizeFileName("..."));
EXPECT_EQ(".bashrc", NormalizeFileName(".bashrc"));
EXPECT_EQ("._", NormalizeFileName("./"));
}
TEST(FileSystemUtilTest, GetCacheRootPath) {
TestingProfile profile;
base::FilePath profile_path = profile.GetPath();
EXPECT_EQ(profile_path.AppendASCII("GCache/v1"),
util::GetCacheRootPath(&profile));
}
TEST(FileSystemUtilTest, NeedsNamespaceMigration) {
// Not Drive cases.
EXPECT_FALSE(NeedsNamespaceMigration(
base::FilePath::FromUTF8Unsafe("/Downloads")));
EXPECT_FALSE(NeedsNamespaceMigration(
base::FilePath::FromUTF8Unsafe("/Downloads/x")));
EXPECT_FALSE(NeedsNamespaceMigration(
base::FilePath::FromUTF8Unsafe("/wherever/foo.txt")));
EXPECT_FALSE(NeedsNamespaceMigration(
base::FilePath::FromUTF8Unsafe("/special/foo.txt")));
EXPECT_FALSE(NeedsNamespaceMigration(
base::FilePath::FromUTF8Unsafe("/special/drivex/foo.txt")));
EXPECT_FALSE(NeedsNamespaceMigration(
base::FilePath::FromUTF8Unsafe("special/drivex/foo.txt")));
// Before migration.
EXPECT_TRUE(NeedsNamespaceMigration(
base::FilePath::FromUTF8Unsafe("/special/drive")));
EXPECT_TRUE(NeedsNamespaceMigration(
base::FilePath::FromUTF8Unsafe("/special/drive/foo.txt")));
EXPECT_TRUE(NeedsNamespaceMigration(
base::FilePath::FromUTF8Unsafe("/special/drive/subdir/foo.txt")));
// Already migrated.
EXPECT_FALSE(NeedsNamespaceMigration(
base::FilePath::FromUTF8Unsafe("/special/drive/root")));
EXPECT_FALSE(NeedsNamespaceMigration(
base::FilePath::FromUTF8Unsafe("/special/drive/root/dir1")));
EXPECT_FALSE(NeedsNamespaceMigration(
base::FilePath::FromUTF8Unsafe("/special/drive/root/root")));
EXPECT_FALSE(NeedsNamespaceMigration(
base::FilePath::FromUTF8Unsafe("/special/drive/root/root/dir1")));
}
TEST(FileSystemUtilTest, ConvertToMyDriveNamespace) {
// Migration cases.
EXPECT_EQ(base::FilePath::FromUTF8Unsafe("/special/drive/root"),
drive::util::ConvertToMyDriveNamespace(
base::FilePath::FromUTF8Unsafe("/special/drive")));
EXPECT_EQ(base::FilePath::FromUTF8Unsafe("/special/drive/root/dir1"),
drive::util::ConvertToMyDriveNamespace(
base::FilePath::FromUTF8Unsafe("/special/drive/dir1")));
}
TEST(FileSystemUtilTest, IsSpecialResourceId) {
EXPECT_FALSE(util::IsSpecialResourceId("abc"));
EXPECT_FALSE(util::IsSpecialResourceId("file:123"));
EXPECT_FALSE(util::IsSpecialResourceId("folder:root"));
EXPECT_FALSE(util::IsSpecialResourceId("folder:xyz"));
EXPECT_TRUE(util::IsSpecialResourceId("<drive>"));
EXPECT_TRUE(util::IsSpecialResourceId("<other>"));
}
TEST(FileSystemUtilTest, GDocFile) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
GURL url("https://docs.google.com/document/d/"
"1YsCnrMxxgp7LDdtlFDt-WdtEIth89vA9inrILtvK-Ug/edit");
std::string resource_id("1YsCnrMxxgp7LDdtlFDt-WdtEIth89vA9inrILtvK-Ug");
// Read and write gdoc.
base::FilePath file = temp_dir.path().AppendASCII("test.gdoc");
EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
EXPECT_TRUE(HasGDocFileExtension(file));
EXPECT_EQ(url, ReadUrlFromGDocFile(file));
EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
// Read and write gsheet.
file = temp_dir.path().AppendASCII("test.gsheet");
EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
EXPECT_TRUE(HasGDocFileExtension(file));
EXPECT_EQ(url, ReadUrlFromGDocFile(file));
EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
// Read and write gslides.
file = temp_dir.path().AppendASCII("test.gslides");
EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
EXPECT_TRUE(HasGDocFileExtension(file));
EXPECT_EQ(url, ReadUrlFromGDocFile(file));
EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
// Read and write gdraw.
file = temp_dir.path().AppendASCII("test.gdraw");
EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
EXPECT_TRUE(HasGDocFileExtension(file));
EXPECT_EQ(url, ReadUrlFromGDocFile(file));
EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
// Read and write gtable.
file = temp_dir.path().AppendASCII("test.gtable");
EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
EXPECT_TRUE(HasGDocFileExtension(file));
EXPECT_EQ(url, ReadUrlFromGDocFile(file));
EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
// Read and write glink.
file = temp_dir.path().AppendASCII("test.glink");
EXPECT_TRUE(CreateGDocFile(file, url, resource_id));
EXPECT_TRUE(HasGDocFileExtension(file));
EXPECT_EQ(url, ReadUrlFromGDocFile(file));
EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file));
// Non GDoc file.
file = temp_dir.path().AppendASCII("test.txt");
std::string data = "Hello world!";
EXPECT_TRUE(google_apis::test_util::WriteStringToFile(file, data));
EXPECT_FALSE(HasGDocFileExtension(file));
EXPECT_TRUE(ReadUrlFromGDocFile(file).is_empty());
EXPECT_TRUE(ReadResourceIdFromGDocFile(file).empty());
}
} // namespace util
} // namespace drive