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.
5 #include "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
9 #include "base/files/file.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h"
12 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h"
13 #include "chrome/browser/chromeos/file_system_provider/service.h"
14 #include "chrome/browser/chromeos/file_system_provider/service_factory.h"
15 #include "chrome/browser/chromeos/login/users/fake_user_manager.h"
16 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/test/base/testing_browser_process.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "chrome/test/base/testing_profile_manager.h"
21 #include "components/keyed_service/core/keyed_service.h"
22 #include "content/public/browser/browser_context.h"
23 #include "content/public/test/test_browser_thread_bundle.h"
24 #include "extensions/browser/extension_registry.h"
25 #include "storage/browser/fileapi/external_mount_points.h"
26 #include "storage/browser/fileapi/isolated_context.h"
27 #include "testing/gtest/include/gtest/gtest.h"
30 namespace file_system_provider {
35 const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
36 const char kFileSystemId[] = "File/System/Id";
37 const char kDisplayName[] = "Camera Pictures";
39 // Creates a FileSystemURL for tests.
40 storage::FileSystemURL CreateFileSystemURL(
42 const ProvidedFileSystemInfo& file_system_info,
43 const base::FilePath& file_path) {
44 const std::string origin =
45 std::string("chrome-extension://") + file_system_info.extension_id();
46 const base::FilePath mount_path = file_system_info.mount_path();
47 const storage::ExternalMountPoints* const mount_points =
48 storage::ExternalMountPoints::GetSystemInstance();
50 DCHECK(file_path.IsAbsolute());
51 base::FilePath relative_path(file_path.value().substr(1));
52 return mount_points->CreateCrackedFileSystemURL(
54 storage::kFileSystemTypeExternal,
55 base::FilePath(mount_path.BaseName().Append(relative_path)));
58 // Creates a Service instance. Used to be able to destroy the service in
60 KeyedService* CreateService(content::BrowserContext* context) {
61 return new Service(Profile::FromBrowserContext(context),
62 extensions::ExtensionRegistry::Get(context));
67 class FileSystemProviderMountPathUtilTest : public testing::Test {
69 FileSystemProviderMountPathUtilTest() {}
70 virtual ~FileSystemProviderMountPathUtilTest() {}
72 virtual void SetUp() OVERRIDE {
73 profile_manager_.reset(
74 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
75 ASSERT_TRUE(profile_manager_->SetUp());
76 profile_ = profile_manager_->CreateTestingProfile("testing-profile");
77 user_manager_ = new FakeUserManager();
78 user_manager_enabler_.reset(new ScopedUserManagerEnabler(user_manager_));
79 user_manager_->AddUser(profile_->GetProfileName());
80 ServiceFactory::GetInstance()->SetTestingFactory(profile_, &CreateService);
81 file_system_provider_service_ = Service::Get(profile_);
82 file_system_provider_service_->SetFileSystemFactoryForTesting(
83 base::Bind(&FakeProvidedFileSystem::Create));
86 virtual void TearDown() OVERRIDE {
87 // Setting the testing factory to NULL will destroy the created service
88 // associated with the testing profile.
89 ServiceFactory::GetInstance()->SetTestingFactory(profile_, NULL);
92 content::TestBrowserThreadBundle thread_bundle_;
93 scoped_ptr<TestingProfileManager> profile_manager_;
94 TestingProfile* profile_; // Owned by TestingProfileManager.
95 scoped_ptr<ScopedUserManagerEnabler> user_manager_enabler_;
96 FakeUserManager* user_manager_;
97 Service* file_system_provider_service_; // Owned by its factory.
100 TEST_F(FileSystemProviderMountPathUtilTest, GetMountPath) {
101 const base::FilePath result =
102 GetMountPath(profile_, kExtensionId, kFileSystemId);
103 const std::string expected =
104 "/provided/mbflcebpggnecokmikipoihdbecnjfoj:"
105 "File%2FSystem%2FId:testing-profile-hash";
106 EXPECT_EQ(expected, result.AsUTF8Unsafe());
109 TEST_F(FileSystemProviderMountPathUtilTest, IsFileSystemProviderLocalPath) {
110 const base::FilePath mount_path =
111 GetMountPath(profile_, kExtensionId, kFileSystemId);
112 const base::FilePath file_path =
113 base::FilePath::FromUTF8Unsafe("/hello/world.txt");
114 const base::FilePath local_file_path =
115 mount_path.Append(base::FilePath(file_path.value().substr(1)));
117 EXPECT_TRUE(IsFileSystemProviderLocalPath(mount_path));
118 EXPECT_TRUE(IsFileSystemProviderLocalPath(local_file_path));
120 EXPECT_FALSE(IsFileSystemProviderLocalPath(
121 base::FilePath::FromUTF8Unsafe("provided/hello-world/test.txt")));
122 EXPECT_FALSE(IsFileSystemProviderLocalPath(
123 base::FilePath::FromUTF8Unsafe("/provided")));
125 IsFileSystemProviderLocalPath(base::FilePath::FromUTF8Unsafe("/")));
126 EXPECT_FALSE(IsFileSystemProviderLocalPath(base::FilePath()));
129 TEST_F(FileSystemProviderMountPathUtilTest, Parser) {
130 const bool result = file_system_provider_service_->MountFileSystem(
131 kExtensionId, kFileSystemId, kDisplayName, false /* writable */);
133 const ProvidedFileSystemInfo file_system_info =
134 file_system_provider_service_->GetProvidedFileSystem(kExtensionId,
136 ->GetFileSystemInfo();
138 const base::FilePath kFilePath =
139 base::FilePath::FromUTF8Unsafe("/hello/world.txt");
140 const storage::FileSystemURL url =
141 CreateFileSystemURL(profile_, file_system_info, kFilePath);
142 EXPECT_TRUE(url.is_valid());
144 FileSystemURLParser parser(url);
145 EXPECT_TRUE(parser.Parse());
147 ProvidedFileSystemInterface* file_system = parser.file_system();
148 ASSERT_TRUE(file_system);
149 EXPECT_EQ(kFileSystemId, file_system->GetFileSystemInfo().file_system_id());
150 EXPECT_EQ(kFilePath.AsUTF8Unsafe(), parser.file_path().AsUTF8Unsafe());
153 TEST_F(FileSystemProviderMountPathUtilTest, Parser_RootPath) {
154 const bool result = file_system_provider_service_->MountFileSystem(
155 kExtensionId, kFileSystemId, kDisplayName, false /* writable */);
157 const ProvidedFileSystemInfo file_system_info =
158 file_system_provider_service_->GetProvidedFileSystem(kExtensionId,
160 ->GetFileSystemInfo();
162 const base::FilePath kFilePath = base::FilePath::FromUTF8Unsafe("/");
163 const storage::FileSystemURL url =
164 CreateFileSystemURL(profile_, file_system_info, kFilePath);
165 EXPECT_TRUE(url.is_valid());
167 FileSystemURLParser parser(url);
168 EXPECT_TRUE(parser.Parse());
170 ProvidedFileSystemInterface* file_system = parser.file_system();
171 ASSERT_TRUE(file_system);
172 EXPECT_EQ(kFileSystemId, file_system->GetFileSystemInfo().file_system_id());
173 EXPECT_EQ(kFilePath.AsUTF8Unsafe(), parser.file_path().AsUTF8Unsafe());
176 TEST_F(FileSystemProviderMountPathUtilTest, Parser_WrongUrl) {
177 const ProvidedFileSystemInfo file_system_info(
181 false /* writable */,
182 GetMountPath(profile_, kExtensionId, kFileSystemId));
184 const base::FilePath kFilePath = base::FilePath::FromUTF8Unsafe("/hello");
185 const storage::FileSystemURL url =
186 CreateFileSystemURL(profile_, file_system_info, kFilePath);
187 // It is impossible to create a cracked URL for a mount point which doesn't
188 // exist, therefore is will always be invalid, and empty.
189 EXPECT_FALSE(url.is_valid());
191 FileSystemURLParser parser(url);
192 EXPECT_FALSE(parser.Parse());
195 TEST_F(FileSystemProviderMountPathUtilTest, Parser_IsolatedURL) {
196 const bool result = file_system_provider_service_->MountFileSystem(
197 kExtensionId, kFileSystemId, kDisplayName, false /* writable */);
199 const ProvidedFileSystemInfo file_system_info =
200 file_system_provider_service_->GetProvidedFileSystem(kExtensionId,
202 ->GetFileSystemInfo();
204 const base::FilePath kFilePath =
205 base::FilePath::FromUTF8Unsafe("/hello/world.txt");
206 const storage::FileSystemURL url =
207 CreateFileSystemURL(profile_, file_system_info, kFilePath);
208 EXPECT_TRUE(url.is_valid());
210 // Create an isolated URL for the original one.
211 storage::IsolatedContext* const isolated_context =
212 storage::IsolatedContext::GetInstance();
213 const std::string isolated_file_system_id =
214 isolated_context->RegisterFileSystemForPath(
215 storage::kFileSystemTypeProvided,
220 const base::FilePath isolated_virtual_path =
221 isolated_context->CreateVirtualRootPath(isolated_file_system_id)
222 .Append(kFilePath.BaseName().value());
224 const storage::FileSystemURL isolated_url =
225 isolated_context->CreateCrackedFileSystemURL(
227 storage::kFileSystemTypeIsolated,
228 isolated_virtual_path);
230 EXPECT_TRUE(isolated_url.is_valid());
232 FileSystemURLParser parser(isolated_url);
233 EXPECT_TRUE(parser.Parse());
235 ProvidedFileSystemInterface* file_system = parser.file_system();
236 ASSERT_TRUE(file_system);
237 EXPECT_EQ(kFileSystemId, file_system->GetFileSystemInfo().file_system_id());
238 EXPECT_EQ(kFilePath.AsUTF8Unsafe(), parser.file_path().AsUTF8Unsafe());
241 TEST_F(FileSystemProviderMountPathUtilTest, LocalPathParser) {
242 const bool result = file_system_provider_service_->MountFileSystem(
243 kExtensionId, kFileSystemId, kDisplayName, false /* writable */);
245 const ProvidedFileSystemInfo file_system_info =
246 file_system_provider_service_->GetProvidedFileSystem(kExtensionId,
248 ->GetFileSystemInfo();
250 const base::FilePath kFilePath =
251 base::FilePath::FromUTF8Unsafe("/hello/world.txt");
252 const base::FilePath kLocalFilePath = file_system_info.mount_path().Append(
253 base::FilePath(kFilePath.value().substr(1)));
255 LOG(ERROR) << kLocalFilePath.value();
256 LocalPathParser parser(profile_, kLocalFilePath);
257 EXPECT_TRUE(parser.Parse());
259 ProvidedFileSystemInterface* file_system = parser.file_system();
260 ASSERT_TRUE(file_system);
261 EXPECT_EQ(kFileSystemId, file_system->GetFileSystemInfo().file_system_id());
262 EXPECT_EQ(kFilePath.AsUTF8Unsafe(), parser.file_path().AsUTF8Unsafe());
265 TEST_F(FileSystemProviderMountPathUtilTest, LocalPathParser_RootPath) {
266 const bool result = file_system_provider_service_->MountFileSystem(
267 kExtensionId, kFileSystemId, kDisplayName, false /* writable */);
269 const ProvidedFileSystemInfo file_system_info =
270 file_system_provider_service_->GetProvidedFileSystem(kExtensionId,
272 ->GetFileSystemInfo();
274 const base::FilePath kFilePath = base::FilePath::FromUTF8Unsafe("/");
275 const base::FilePath kLocalFilePath = file_system_info.mount_path();
277 LocalPathParser parser(profile_, kLocalFilePath);
278 EXPECT_TRUE(parser.Parse());
280 ProvidedFileSystemInterface* file_system = parser.file_system();
281 ASSERT_TRUE(file_system);
282 EXPECT_EQ(kFileSystemId, file_system->GetFileSystemInfo().file_system_id());
283 EXPECT_EQ(kFilePath.AsUTF8Unsafe(), parser.file_path().AsUTF8Unsafe());
286 TEST_F(FileSystemProviderMountPathUtilTest, LocalPathParser_WrongPath) {
288 const base::FilePath kFilePath = base::FilePath::FromUTF8Unsafe("/hello");
289 LocalPathParser parser(profile_, kFilePath);
290 EXPECT_FALSE(parser.Parse());
294 const base::FilePath kFilePath =
295 base::FilePath::FromUTF8Unsafe("/provided");
296 LocalPathParser parser(profile_, kFilePath);
297 EXPECT_FALSE(parser.Parse());
301 const base::FilePath kFilePath =
302 base::FilePath::FromUTF8Unsafe("provided/hello/world");
303 LocalPathParser parser(profile_, kFilePath);
304 EXPECT_FALSE(parser.Parse());
309 } // namespace file_system_provider
310 } // namespace chromeos