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_chrome_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 ~FileSystemProviderMountPathUtilTest() override
{}
72 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 FakeChromeUserManager();
78 user_manager_enabler_
.reset(new ScopedUserManagerEnabler(user_manager_
));
79 user_manager_
->AddUser(profile_
->GetProfileUserName());
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 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 FakeChromeUserManager
* 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(FILE_PATH_LITERAL("/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(FILE_PATH_LITERAL("provided/hello-world/test.txt"))));
122 EXPECT_FALSE(IsFileSystemProviderLocalPath(
123 base::FilePath(FILE_PATH_LITERAL("/provided"))));
125 IsFileSystemProviderLocalPath(base::FilePath(FILE_PATH_LITERAL("/"))));
126 EXPECT_FALSE(IsFileSystemProviderLocalPath(base::FilePath()));
129 TEST_F(FileSystemProviderMountPathUtilTest
, Parser
) {
130 const base::File::Error result
=
131 file_system_provider_service_
->MountFileSystem(
132 kExtensionId
, MountOptions(kFileSystemId
, kDisplayName
));
133 ASSERT_EQ(base::File::FILE_OK
, result
);
134 const ProvidedFileSystemInfo file_system_info
=
135 file_system_provider_service_
->GetProvidedFileSystem(kExtensionId
,
137 ->GetFileSystemInfo();
139 const base::FilePath kFilePath
=
140 base::FilePath(FILE_PATH_LITERAL("/hello/world.txt"));
141 const storage::FileSystemURL url
=
142 CreateFileSystemURL(profile_
, file_system_info
, kFilePath
);
143 EXPECT_TRUE(url
.is_valid());
145 FileSystemURLParser
parser(url
);
146 EXPECT_TRUE(parser
.Parse());
148 ProvidedFileSystemInterface
* file_system
= parser
.file_system();
149 ASSERT_TRUE(file_system
);
150 EXPECT_EQ(kFileSystemId
, file_system
->GetFileSystemInfo().file_system_id());
151 EXPECT_EQ(kFilePath
.AsUTF8Unsafe(), parser
.file_path().AsUTF8Unsafe());
154 TEST_F(FileSystemProviderMountPathUtilTest
, Parser_RootPath
) {
155 const base::File::Error result
=
156 file_system_provider_service_
->MountFileSystem(
157 kExtensionId
, MountOptions(kFileSystemId
, kDisplayName
));
158 ASSERT_EQ(base::File::FILE_OK
, result
);
159 const ProvidedFileSystemInfo file_system_info
=
160 file_system_provider_service_
->GetProvidedFileSystem(kExtensionId
,
162 ->GetFileSystemInfo();
164 const base::FilePath kFilePath
= base::FilePath(FILE_PATH_LITERAL("/"));
165 const storage::FileSystemURL url
=
166 CreateFileSystemURL(profile_
, file_system_info
, kFilePath
);
167 EXPECT_TRUE(url
.is_valid());
169 FileSystemURLParser
parser(url
);
170 EXPECT_TRUE(parser
.Parse());
172 ProvidedFileSystemInterface
* file_system
= parser
.file_system();
173 ASSERT_TRUE(file_system
);
174 EXPECT_EQ(kFileSystemId
, file_system
->GetFileSystemInfo().file_system_id());
175 EXPECT_EQ(kFilePath
.AsUTF8Unsafe(), parser
.file_path().AsUTF8Unsafe());
178 TEST_F(FileSystemProviderMountPathUtilTest
, Parser_WrongUrl
) {
179 const ProvidedFileSystemInfo
file_system_info(
181 MountOptions(kFileSystemId
, kDisplayName
),
182 GetMountPath(profile_
, kExtensionId
, kFileSystemId
));
184 const base::FilePath kFilePath
= base::FilePath(FILE_PATH_LITERAL("/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 base::File::Error result
=
197 file_system_provider_service_
->MountFileSystem(
198 kExtensionId
, MountOptions(kFileSystemId
, kDisplayName
));
199 ASSERT_EQ(base::File::FILE_OK
, result
);
200 const ProvidedFileSystemInfo file_system_info
=
201 file_system_provider_service_
->GetProvidedFileSystem(kExtensionId
,
203 ->GetFileSystemInfo();
205 const base::FilePath kFilePath
=
206 base::FilePath(FILE_PATH_LITERAL("/hello/world.txt"));
207 const storage::FileSystemURL url
=
208 CreateFileSystemURL(profile_
, file_system_info
, kFilePath
);
209 EXPECT_TRUE(url
.is_valid());
211 // Create an isolated URL for the original one.
212 storage::IsolatedContext
* const isolated_context
=
213 storage::IsolatedContext::GetInstance();
214 const std::string isolated_file_system_id
=
215 isolated_context
->RegisterFileSystemForPath(
216 storage::kFileSystemTypeProvided
,
221 const base::FilePath isolated_virtual_path
=
222 isolated_context
->CreateVirtualRootPath(isolated_file_system_id
)
223 .Append(kFilePath
.BaseName().value());
225 const storage::FileSystemURL isolated_url
=
226 isolated_context
->CreateCrackedFileSystemURL(
228 storage::kFileSystemTypeIsolated
,
229 isolated_virtual_path
);
231 EXPECT_TRUE(isolated_url
.is_valid());
233 FileSystemURLParser
parser(isolated_url
);
234 EXPECT_TRUE(parser
.Parse());
236 ProvidedFileSystemInterface
* file_system
= parser
.file_system();
237 ASSERT_TRUE(file_system
);
238 EXPECT_EQ(kFileSystemId
, file_system
->GetFileSystemInfo().file_system_id());
239 EXPECT_EQ(kFilePath
.AsUTF8Unsafe(), parser
.file_path().AsUTF8Unsafe());
242 TEST_F(FileSystemProviderMountPathUtilTest
, LocalPathParser
) {
243 const base::File::Error result
=
244 file_system_provider_service_
->MountFileSystem(
245 kExtensionId
, MountOptions(kFileSystemId
, kDisplayName
));
246 ASSERT_EQ(base::File::FILE_OK
, result
);
247 const ProvidedFileSystemInfo file_system_info
=
248 file_system_provider_service_
->GetProvidedFileSystem(kExtensionId
,
250 ->GetFileSystemInfo();
252 const base::FilePath kFilePath
=
253 base::FilePath(FILE_PATH_LITERAL("/hello/world.txt"));
254 const base::FilePath kLocalFilePath
= file_system_info
.mount_path().Append(
255 base::FilePath(kFilePath
.value().substr(1)));
257 LOG(ERROR
) << kLocalFilePath
.value();
258 LocalPathParser
parser(profile_
, kLocalFilePath
);
259 EXPECT_TRUE(parser
.Parse());
261 ProvidedFileSystemInterface
* file_system
= parser
.file_system();
262 ASSERT_TRUE(file_system
);
263 EXPECT_EQ(kFileSystemId
, file_system
->GetFileSystemInfo().file_system_id());
264 EXPECT_EQ(kFilePath
.AsUTF8Unsafe(), parser
.file_path().AsUTF8Unsafe());
267 TEST_F(FileSystemProviderMountPathUtilTest
, LocalPathParser_RootPath
) {
268 const base::File::Error result
=
269 file_system_provider_service_
->MountFileSystem(
270 kExtensionId
, MountOptions(kFileSystemId
, kDisplayName
));
271 ASSERT_EQ(base::File::FILE_OK
, result
);
272 const ProvidedFileSystemInfo file_system_info
=
273 file_system_provider_service_
->GetProvidedFileSystem(kExtensionId
,
275 ->GetFileSystemInfo();
277 const base::FilePath kFilePath
= base::FilePath(FILE_PATH_LITERAL("/"));
278 const base::FilePath kLocalFilePath
= file_system_info
.mount_path();
280 LocalPathParser
parser(profile_
, kLocalFilePath
);
281 EXPECT_TRUE(parser
.Parse());
283 ProvidedFileSystemInterface
* file_system
= parser
.file_system();
284 ASSERT_TRUE(file_system
);
285 EXPECT_EQ(kFileSystemId
, file_system
->GetFileSystemInfo().file_system_id());
286 EXPECT_EQ(kFilePath
.AsUTF8Unsafe(), parser
.file_path().AsUTF8Unsafe());
289 TEST_F(FileSystemProviderMountPathUtilTest
, LocalPathParser_WrongPath
) {
291 const base::FilePath kFilePath
=
292 base::FilePath(FILE_PATH_LITERAL("/hello"));
293 LocalPathParser
parser(profile_
, kFilePath
);
294 EXPECT_FALSE(parser
.Parse());
298 const base::FilePath kFilePath
=
299 base::FilePath(FILE_PATH_LITERAL("/provided"));
300 LocalPathParser
parser(profile_
, kFilePath
);
301 EXPECT_FALSE(parser
.Parse());
305 const base::FilePath kFilePath
=
306 base::FilePath(FILE_PATH_LITERAL("provided/hello/world"));
307 LocalPathParser
parser(profile_
, kFilePath
);
308 EXPECT_FALSE(parser
.Parse());
313 } // namespace file_system_provider
314 } // namespace chromeos