blob: cc2bf5d949097d220f3103a2c62d4ac7bc24f853 [file] [log] [blame]
// 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 "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
#include <string>
#include "base/files/file.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h"
#include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h"
#include "chrome/browser/chromeos/file_system_provider/service.h"
#include "chrome/browser/chromeos/file_system_provider/service_factory.h"
#include "chrome/browser/chromeos/login/users/fake_user_manager.h"
#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/browser/extension_registry.h"
#include "storage/browser/fileapi/external_mount_points.h"
#include "storage/browser/fileapi/isolated_context.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace file_system_provider {
namespace util {
namespace {
const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
const char kFileSystemId[] = "File/System/Id";
const char kDisplayName[] = "Camera Pictures";
// Creates a FileSystemURL for tests.
storage::FileSystemURL CreateFileSystemURL(
Profile* profile,
const ProvidedFileSystemInfo& file_system_info,
const base::FilePath& file_path) {
const std::string origin =
std::string("chrome-extension://") + file_system_info.extension_id();
const base::FilePath mount_path = file_system_info.mount_path();
const storage::ExternalMountPoints* const mount_points =
storage::ExternalMountPoints::GetSystemInstance();
DCHECK(mount_points);
DCHECK(file_path.IsAbsolute());
base::FilePath relative_path(file_path.value().substr(1));
return mount_points->CreateCrackedFileSystemURL(
GURL(origin),
storage::kFileSystemTypeExternal,
base::FilePath(mount_path.BaseName().Append(relative_path)));
}
// Creates a Service instance. Used to be able to destroy the service in
// TearDown().
KeyedService* CreateService(content::BrowserContext* context) {
return new Service(Profile::FromBrowserContext(context),
extensions::ExtensionRegistry::Get(context));
}
} // namespace
class FileSystemProviderMountPathUtilTest : public testing::Test {
protected:
FileSystemProviderMountPathUtilTest() {}
virtual ~FileSystemProviderMountPathUtilTest() {}
virtual void SetUp() override {
profile_manager_.reset(
new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
ASSERT_TRUE(profile_manager_->SetUp());
profile_ = profile_manager_->CreateTestingProfile("testing-profile");
user_manager_ = new FakeUserManager();
user_manager_enabler_.reset(new ScopedUserManagerEnabler(user_manager_));
user_manager_->AddUser(profile_->GetProfileName());
ServiceFactory::GetInstance()->SetTestingFactory(profile_, &CreateService);
file_system_provider_service_ = Service::Get(profile_);
file_system_provider_service_->SetFileSystemFactoryForTesting(
base::Bind(&FakeProvidedFileSystem::Create));
}
virtual void TearDown() override {
// Setting the testing factory to NULL will destroy the created service
// associated with the testing profile.
ServiceFactory::GetInstance()->SetTestingFactory(profile_, NULL);
}
content::TestBrowserThreadBundle thread_bundle_;
scoped_ptr<TestingProfileManager> profile_manager_;
TestingProfile* profile_; // Owned by TestingProfileManager.
scoped_ptr<ScopedUserManagerEnabler> user_manager_enabler_;
FakeUserManager* user_manager_;
Service* file_system_provider_service_; // Owned by its factory.
};
TEST_F(FileSystemProviderMountPathUtilTest, GetMountPath) {
const base::FilePath result =
GetMountPath(profile_, kExtensionId, kFileSystemId);
const std::string expected =
"/provided/mbflcebpggnecokmikipoihdbecnjfoj:"
"File%2FSystem%2FId:testing-profile-hash";
EXPECT_EQ(expected, result.AsUTF8Unsafe());
}
TEST_F(FileSystemProviderMountPathUtilTest, IsFileSystemProviderLocalPath) {
const base::FilePath mount_path =
GetMountPath(profile_, kExtensionId, kFileSystemId);
const base::FilePath file_path =
base::FilePath::FromUTF8Unsafe("/hello/world.txt");
const base::FilePath local_file_path =
mount_path.Append(base::FilePath(file_path.value().substr(1)));
EXPECT_TRUE(IsFileSystemProviderLocalPath(mount_path));
EXPECT_TRUE(IsFileSystemProviderLocalPath(local_file_path));
EXPECT_FALSE(IsFileSystemProviderLocalPath(
base::FilePath::FromUTF8Unsafe("provided/hello-world/test.txt")));
EXPECT_FALSE(IsFileSystemProviderLocalPath(
base::FilePath::FromUTF8Unsafe("/provided")));
EXPECT_FALSE(
IsFileSystemProviderLocalPath(base::FilePath::FromUTF8Unsafe("/")));
EXPECT_FALSE(IsFileSystemProviderLocalPath(base::FilePath()));
}
TEST_F(FileSystemProviderMountPathUtilTest, Parser) {
const bool result = file_system_provider_service_->MountFileSystem(
kExtensionId, MountOptions(kFileSystemId, kDisplayName));
ASSERT_TRUE(result);
const ProvidedFileSystemInfo file_system_info =
file_system_provider_service_->GetProvidedFileSystem(kExtensionId,
kFileSystemId)
->GetFileSystemInfo();
const base::FilePath kFilePath =
base::FilePath::FromUTF8Unsafe("/hello/world.txt");
const storage::FileSystemURL url =
CreateFileSystemURL(profile_, file_system_info, kFilePath);
EXPECT_TRUE(url.is_valid());
FileSystemURLParser parser(url);
EXPECT_TRUE(parser.Parse());
ProvidedFileSystemInterface* file_system = parser.file_system();
ASSERT_TRUE(file_system);
EXPECT_EQ(kFileSystemId, file_system->GetFileSystemInfo().file_system_id());
EXPECT_EQ(kFilePath.AsUTF8Unsafe(), parser.file_path().AsUTF8Unsafe());
}
TEST_F(FileSystemProviderMountPathUtilTest, Parser_RootPath) {
const bool result = file_system_provider_service_->MountFileSystem(
kExtensionId, MountOptions(kFileSystemId, kDisplayName));
ASSERT_TRUE(result);
const ProvidedFileSystemInfo file_system_info =
file_system_provider_service_->GetProvidedFileSystem(kExtensionId,
kFileSystemId)
->GetFileSystemInfo();
const base::FilePath kFilePath = base::FilePath::FromUTF8Unsafe("/");
const storage::FileSystemURL url =
CreateFileSystemURL(profile_, file_system_info, kFilePath);
EXPECT_TRUE(url.is_valid());
FileSystemURLParser parser(url);
EXPECT_TRUE(parser.Parse());
ProvidedFileSystemInterface* file_system = parser.file_system();
ASSERT_TRUE(file_system);
EXPECT_EQ(kFileSystemId, file_system->GetFileSystemInfo().file_system_id());
EXPECT_EQ(kFilePath.AsUTF8Unsafe(), parser.file_path().AsUTF8Unsafe());
}
TEST_F(FileSystemProviderMountPathUtilTest, Parser_WrongUrl) {
const ProvidedFileSystemInfo file_system_info(
kExtensionId,
MountOptions(kFileSystemId, kDisplayName),
GetMountPath(profile_, kExtensionId, kFileSystemId));
const base::FilePath kFilePath = base::FilePath::FromUTF8Unsafe("/hello");
const storage::FileSystemURL url =
CreateFileSystemURL(profile_, file_system_info, kFilePath);
// It is impossible to create a cracked URL for a mount point which doesn't
// exist, therefore is will always be invalid, and empty.
EXPECT_FALSE(url.is_valid());
FileSystemURLParser parser(url);
EXPECT_FALSE(parser.Parse());
}
TEST_F(FileSystemProviderMountPathUtilTest, Parser_IsolatedURL) {
const bool result = file_system_provider_service_->MountFileSystem(
kExtensionId, MountOptions(kFileSystemId, kDisplayName));
ASSERT_TRUE(result);
const ProvidedFileSystemInfo file_system_info =
file_system_provider_service_->GetProvidedFileSystem(kExtensionId,
kFileSystemId)
->GetFileSystemInfo();
const base::FilePath kFilePath =
base::FilePath::FromUTF8Unsafe("/hello/world.txt");
const storage::FileSystemURL url =
CreateFileSystemURL(profile_, file_system_info, kFilePath);
EXPECT_TRUE(url.is_valid());
// Create an isolated URL for the original one.
storage::IsolatedContext* const isolated_context =
storage::IsolatedContext::GetInstance();
const std::string isolated_file_system_id =
isolated_context->RegisterFileSystemForPath(
storage::kFileSystemTypeProvided,
url.filesystem_id(),
url.path(),
NULL);
const base::FilePath isolated_virtual_path =
isolated_context->CreateVirtualRootPath(isolated_file_system_id)
.Append(kFilePath.BaseName().value());
const storage::FileSystemURL isolated_url =
isolated_context->CreateCrackedFileSystemURL(
url.origin(),
storage::kFileSystemTypeIsolated,
isolated_virtual_path);
EXPECT_TRUE(isolated_url.is_valid());
FileSystemURLParser parser(isolated_url);
EXPECT_TRUE(parser.Parse());
ProvidedFileSystemInterface* file_system = parser.file_system();
ASSERT_TRUE(file_system);
EXPECT_EQ(kFileSystemId, file_system->GetFileSystemInfo().file_system_id());
EXPECT_EQ(kFilePath.AsUTF8Unsafe(), parser.file_path().AsUTF8Unsafe());
}
TEST_F(FileSystemProviderMountPathUtilTest, LocalPathParser) {
const bool result = file_system_provider_service_->MountFileSystem(
kExtensionId, MountOptions(kFileSystemId, kDisplayName));
ASSERT_TRUE(result);
const ProvidedFileSystemInfo file_system_info =
file_system_provider_service_->GetProvidedFileSystem(kExtensionId,
kFileSystemId)
->GetFileSystemInfo();
const base::FilePath kFilePath =
base::FilePath::FromUTF8Unsafe("/hello/world.txt");
const base::FilePath kLocalFilePath = file_system_info.mount_path().Append(
base::FilePath(kFilePath.value().substr(1)));
LOG(ERROR) << kLocalFilePath.value();
LocalPathParser parser(profile_, kLocalFilePath);
EXPECT_TRUE(parser.Parse());
ProvidedFileSystemInterface* file_system = parser.file_system();
ASSERT_TRUE(file_system);
EXPECT_EQ(kFileSystemId, file_system->GetFileSystemInfo().file_system_id());
EXPECT_EQ(kFilePath.AsUTF8Unsafe(), parser.file_path().AsUTF8Unsafe());
}
TEST_F(FileSystemProviderMountPathUtilTest, LocalPathParser_RootPath) {
const bool result = file_system_provider_service_->MountFileSystem(
kExtensionId, MountOptions(kFileSystemId, kDisplayName));
ASSERT_TRUE(result);
const ProvidedFileSystemInfo file_system_info =
file_system_provider_service_->GetProvidedFileSystem(kExtensionId,
kFileSystemId)
->GetFileSystemInfo();
const base::FilePath kFilePath = base::FilePath::FromUTF8Unsafe("/");
const base::FilePath kLocalFilePath = file_system_info.mount_path();
LocalPathParser parser(profile_, kLocalFilePath);
EXPECT_TRUE(parser.Parse());
ProvidedFileSystemInterface* file_system = parser.file_system();
ASSERT_TRUE(file_system);
EXPECT_EQ(kFileSystemId, file_system->GetFileSystemInfo().file_system_id());
EXPECT_EQ(kFilePath.AsUTF8Unsafe(), parser.file_path().AsUTF8Unsafe());
}
TEST_F(FileSystemProviderMountPathUtilTest, LocalPathParser_WrongPath) {
{
const base::FilePath kFilePath = base::FilePath::FromUTF8Unsafe("/hello");
LocalPathParser parser(profile_, kFilePath);
EXPECT_FALSE(parser.Parse());
}
{
const base::FilePath kFilePath =
base::FilePath::FromUTF8Unsafe("/provided");
LocalPathParser parser(profile_, kFilePath);
EXPECT_FALSE(parser.Parse());
}
{
const base::FilePath kFilePath =
base::FilePath::FromUTF8Unsafe("provided/hello/world");
LocalPathParser parser(profile_, kFilePath);
EXPECT_FALSE(parser.Parse());
}
}
} // namespace util
} // namespace file_system_provider
} // namespace chromeos