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/common/extensions/api/file_system_provider_capabilities/file_system_provider_capabilities_handler.h"
19 #include "chrome/test/base/testing_browser_process.h"
20 #include "chrome/test/base/testing_profile.h"
21 #include "chrome/test/base/testing_profile_manager.h"
22 #include "components/keyed_service/core/keyed_service.h"
23 #include "content/public/browser/browser_context.h"
24 #include "content/public/test/test_browser_thread_bundle.h"
25 #include "extensions/browser/extension_registry.h"
26 #include "storage/browser/fileapi/external_mount_points.h"
27 #include "storage/browser/fileapi/isolated_context.h"
28 #include "testing/gtest/include/gtest/gtest.h"
31 namespace file_system_provider
{
36 const char kExtensionId
[] = "mbflcebpggnecokmikipoihdbecnjfoj";
37 const char kFileSystemId
[] = "File/System/Id";
38 const char kDisplayName
[] = "Camera Pictures";
40 // Creates a FileSystemURL for tests.
41 storage::FileSystemURL
CreateFileSystemURL(
43 const ProvidedFileSystemInfo
& file_system_info
,
44 const base::FilePath
& file_path
) {
45 const std::string origin
=
46 std::string("chrome-extension://") + file_system_info
.extension_id();
47 const base::FilePath mount_path
= file_system_info
.mount_path();
48 const storage::ExternalMountPoints
* const mount_points
=
49 storage::ExternalMountPoints::GetSystemInstance();
51 DCHECK(file_path
.IsAbsolute());
52 base::FilePath
relative_path(file_path
.value().substr(1));
53 return mount_points
->CreateCrackedFileSystemURL(
55 storage::kFileSystemTypeExternal
,
56 base::FilePath(mount_path
.BaseName().Append(relative_path
)));
61 class FileSystemProviderMountPathUtilTest
: public testing::Test
{
63 FileSystemProviderMountPathUtilTest() {}
64 ~FileSystemProviderMountPathUtilTest() override
{}
66 void SetUp() override
{
67 profile_manager_
.reset(
68 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
69 ASSERT_TRUE(profile_manager_
->SetUp());
70 profile_
= profile_manager_
->CreateTestingProfile("testing-profile");
71 user_manager_
= new FakeChromeUserManager();
72 user_manager_enabler_
.reset(new ScopedUserManagerEnabler(user_manager_
));
73 user_manager_
->AddUser(profile_
->GetProfileUserName());
74 file_system_provider_service_
= Service::Get(profile_
);
75 file_system_provider_service_
->SetFileSystemFactoryForTesting(
76 base::Bind(&FakeProvidedFileSystem::Create
));
79 content::TestBrowserThreadBundle thread_bundle_
;
80 scoped_ptr
<TestingProfileManager
> profile_manager_
;
81 TestingProfile
* profile_
; // Owned by TestingProfileManager.
82 scoped_ptr
<ScopedUserManagerEnabler
> user_manager_enabler_
;
83 FakeChromeUserManager
* user_manager_
;
84 Service
* file_system_provider_service_
; // Owned by its factory.
87 TEST_F(FileSystemProviderMountPathUtilTest
, GetMountPath
) {
88 const base::FilePath result
=
89 GetMountPath(profile_
, kExtensionId
, kFileSystemId
);
90 const std::string expected
=
91 "/provided/mbflcebpggnecokmikipoihdbecnjfoj:"
92 "File%2FSystem%2FId:testing-profile-hash";
93 EXPECT_EQ(expected
, result
.AsUTF8Unsafe());
96 TEST_F(FileSystemProviderMountPathUtilTest
, IsFileSystemProviderLocalPath
) {
97 const base::FilePath mount_path
=
98 GetMountPath(profile_
, kExtensionId
, kFileSystemId
);
99 const base::FilePath file_path
=
100 base::FilePath(FILE_PATH_LITERAL("/hello/world.txt"));
101 const base::FilePath local_file_path
=
102 mount_path
.Append(base::FilePath(file_path
.value().substr(1)));
104 EXPECT_TRUE(IsFileSystemProviderLocalPath(mount_path
));
105 EXPECT_TRUE(IsFileSystemProviderLocalPath(local_file_path
));
107 EXPECT_FALSE(IsFileSystemProviderLocalPath(
108 base::FilePath(FILE_PATH_LITERAL("provided/hello-world/test.txt"))));
109 EXPECT_FALSE(IsFileSystemProviderLocalPath(
110 base::FilePath(FILE_PATH_LITERAL("/provided"))));
112 IsFileSystemProviderLocalPath(base::FilePath(FILE_PATH_LITERAL("/"))));
113 EXPECT_FALSE(IsFileSystemProviderLocalPath(base::FilePath()));
116 TEST_F(FileSystemProviderMountPathUtilTest
, Parser
) {
117 const base::File::Error result
=
118 file_system_provider_service_
->MountFileSystem(
119 kExtensionId
, MountOptions(kFileSystemId
, kDisplayName
));
120 ASSERT_EQ(base::File::FILE_OK
, result
);
121 const ProvidedFileSystemInfo file_system_info
=
122 file_system_provider_service_
->GetProvidedFileSystem(kExtensionId
,
124 ->GetFileSystemInfo();
126 const base::FilePath kFilePath
=
127 base::FilePath(FILE_PATH_LITERAL("/hello/world.txt"));
128 const storage::FileSystemURL url
=
129 CreateFileSystemURL(profile_
, file_system_info
, kFilePath
);
130 EXPECT_TRUE(url
.is_valid());
132 FileSystemURLParser
parser(url
);
133 EXPECT_TRUE(parser
.Parse());
135 ProvidedFileSystemInterface
* file_system
= parser
.file_system();
136 ASSERT_TRUE(file_system
);
137 EXPECT_EQ(kFileSystemId
, file_system
->GetFileSystemInfo().file_system_id());
138 EXPECT_EQ(kFilePath
.AsUTF8Unsafe(), parser
.file_path().AsUTF8Unsafe());
141 TEST_F(FileSystemProviderMountPathUtilTest
, Parser_RootPath
) {
142 const base::File::Error result
=
143 file_system_provider_service_
->MountFileSystem(
144 kExtensionId
, MountOptions(kFileSystemId
, kDisplayName
));
145 ASSERT_EQ(base::File::FILE_OK
, result
);
146 const ProvidedFileSystemInfo file_system_info
=
147 file_system_provider_service_
->GetProvidedFileSystem(kExtensionId
,
149 ->GetFileSystemInfo();
151 const base::FilePath kFilePath
= base::FilePath(FILE_PATH_LITERAL("/"));
152 const storage::FileSystemURL url
=
153 CreateFileSystemURL(profile_
, file_system_info
, kFilePath
);
154 EXPECT_TRUE(url
.is_valid());
156 FileSystemURLParser
parser(url
);
157 EXPECT_TRUE(parser
.Parse());
159 ProvidedFileSystemInterface
* file_system
= parser
.file_system();
160 ASSERT_TRUE(file_system
);
161 EXPECT_EQ(kFileSystemId
, file_system
->GetFileSystemInfo().file_system_id());
162 EXPECT_EQ(kFilePath
.AsUTF8Unsafe(), parser
.file_path().AsUTF8Unsafe());
165 TEST_F(FileSystemProviderMountPathUtilTest
, Parser_WrongUrl
) {
166 const ProvidedFileSystemInfo
file_system_info(
167 kExtensionId
, MountOptions(kFileSystemId
, kDisplayName
),
168 GetMountPath(profile_
, kExtensionId
, kFileSystemId
),
169 false /* configurable */, true /* watchable */, extensions::SOURCE_FILE
);
171 const base::FilePath kFilePath
= base::FilePath(FILE_PATH_LITERAL("/hello"));
172 const storage::FileSystemURL url
=
173 CreateFileSystemURL(profile_
, file_system_info
, kFilePath
);
174 // It is impossible to create a cracked URL for a mount point which doesn't
175 // exist, therefore is will always be invalid, and empty.
176 EXPECT_FALSE(url
.is_valid());
178 FileSystemURLParser
parser(url
);
179 EXPECT_FALSE(parser
.Parse());
182 TEST_F(FileSystemProviderMountPathUtilTest
, Parser_IsolatedURL
) {
183 const base::File::Error result
=
184 file_system_provider_service_
->MountFileSystem(
185 kExtensionId
, MountOptions(kFileSystemId
, kDisplayName
));
186 ASSERT_EQ(base::File::FILE_OK
, result
);
187 const ProvidedFileSystemInfo file_system_info
=
188 file_system_provider_service_
->GetProvidedFileSystem(kExtensionId
,
190 ->GetFileSystemInfo();
192 const base::FilePath kFilePath
=
193 base::FilePath(FILE_PATH_LITERAL("/hello/world.txt"));
194 const storage::FileSystemURL url
=
195 CreateFileSystemURL(profile_
, file_system_info
, kFilePath
);
196 EXPECT_TRUE(url
.is_valid());
198 // Create an isolated URL for the original one.
199 storage::IsolatedContext
* const isolated_context
=
200 storage::IsolatedContext::GetInstance();
201 const std::string isolated_file_system_id
=
202 isolated_context
->RegisterFileSystemForPath(
203 storage::kFileSystemTypeProvided
,
208 const base::FilePath isolated_virtual_path
=
209 isolated_context
->CreateVirtualRootPath(isolated_file_system_id
)
210 .Append(kFilePath
.BaseName().value());
212 const storage::FileSystemURL isolated_url
=
213 isolated_context
->CreateCrackedFileSystemURL(
215 storage::kFileSystemTypeIsolated
,
216 isolated_virtual_path
);
218 EXPECT_TRUE(isolated_url
.is_valid());
220 FileSystemURLParser
parser(isolated_url
);
221 EXPECT_TRUE(parser
.Parse());
223 ProvidedFileSystemInterface
* file_system
= parser
.file_system();
224 ASSERT_TRUE(file_system
);
225 EXPECT_EQ(kFileSystemId
, file_system
->GetFileSystemInfo().file_system_id());
226 EXPECT_EQ(kFilePath
.AsUTF8Unsafe(), parser
.file_path().AsUTF8Unsafe());
229 TEST_F(FileSystemProviderMountPathUtilTest
, LocalPathParser
) {
230 const base::File::Error result
=
231 file_system_provider_service_
->MountFileSystem(
232 kExtensionId
, MountOptions(kFileSystemId
, kDisplayName
));
233 ASSERT_EQ(base::File::FILE_OK
, result
);
234 const ProvidedFileSystemInfo file_system_info
=
235 file_system_provider_service_
->GetProvidedFileSystem(kExtensionId
,
237 ->GetFileSystemInfo();
239 const base::FilePath kFilePath
=
240 base::FilePath(FILE_PATH_LITERAL("/hello/world.txt"));
241 const base::FilePath kLocalFilePath
= file_system_info
.mount_path().Append(
242 base::FilePath(kFilePath
.value().substr(1)));
244 LOG(ERROR
) << kLocalFilePath
.value();
245 LocalPathParser
parser(profile_
, kLocalFilePath
);
246 EXPECT_TRUE(parser
.Parse());
248 ProvidedFileSystemInterface
* file_system
= parser
.file_system();
249 ASSERT_TRUE(file_system
);
250 EXPECT_EQ(kFileSystemId
, file_system
->GetFileSystemInfo().file_system_id());
251 EXPECT_EQ(kFilePath
.AsUTF8Unsafe(), parser
.file_path().AsUTF8Unsafe());
254 TEST_F(FileSystemProviderMountPathUtilTest
, LocalPathParser_RootPath
) {
255 const base::File::Error result
=
256 file_system_provider_service_
->MountFileSystem(
257 kExtensionId
, MountOptions(kFileSystemId
, kDisplayName
));
258 ASSERT_EQ(base::File::FILE_OK
, result
);
259 const ProvidedFileSystemInfo file_system_info
=
260 file_system_provider_service_
->GetProvidedFileSystem(kExtensionId
,
262 ->GetFileSystemInfo();
264 const base::FilePath kFilePath
= base::FilePath(FILE_PATH_LITERAL("/"));
265 const base::FilePath kLocalFilePath
= file_system_info
.mount_path();
267 LocalPathParser
parser(profile_
, kLocalFilePath
);
268 EXPECT_TRUE(parser
.Parse());
270 ProvidedFileSystemInterface
* file_system
= parser
.file_system();
271 ASSERT_TRUE(file_system
);
272 EXPECT_EQ(kFileSystemId
, file_system
->GetFileSystemInfo().file_system_id());
273 EXPECT_EQ(kFilePath
.AsUTF8Unsafe(), parser
.file_path().AsUTF8Unsafe());
276 TEST_F(FileSystemProviderMountPathUtilTest
, LocalPathParser_WrongPath
) {
278 const base::FilePath kFilePath
=
279 base::FilePath(FILE_PATH_LITERAL("/hello"));
280 LocalPathParser
parser(profile_
, kFilePath
);
281 EXPECT_FALSE(parser
.Parse());
285 const base::FilePath kFilePath
=
286 base::FilePath(FILE_PATH_LITERAL("/provided"));
287 LocalPathParser
parser(profile_
, kFilePath
);
288 EXPECT_FALSE(parser
.Parse());
292 const base::FilePath kFilePath
=
293 base::FilePath(FILE_PATH_LITERAL("provided/hello/world"));
294 LocalPathParser
parser(profile_
, kFilePath
);
295 EXPECT_FALSE(parser
.Parse());
300 } // namespace file_system_provider
301 } // namespace chromeos