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/registry.h"
10 #include "base/files/file_path.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
13 #include "chrome/common/pref_names.h"
14 #include "chrome/test/base/testing_browser_process.h"
15 #include "chrome/test/base/testing_pref_service_syncable.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "chrome/test/base/testing_profile_manager.h"
18 #include "components/user_prefs/user_prefs.h"
19 #include "content/public/test/test_browser_thread_bundle.h"
20 #include "testing/gtest/include/gtest/gtest.h"
23 namespace file_system_provider
{
26 const char kTemporaryOrigin
[] =
27 "chrome-extension://abcabcabcabcabcabcabcabcabcabcabcabca/";
28 const char kPersistentOrigin
[] =
29 "chrome-extension://efgefgefgefgefgefgefgefgefgefgefgefge/";
30 const char kExtensionId
[] = "mbflcebpggnecokmikipoihdbecnjfoj";
31 const char kDisplayName
[] = "Camera Pictures";
33 // The dot in the file system ID is there in order to check that saving to
34 // preferences works correctly. File System ID is used as a key in
35 // a base::DictionaryValue, so it has to be stored without path expansion.
36 const char kFileSystemId
[] = "camera/pictures/id .!@#$%^&*()_+";
38 const int kOpenedFilesLimit
= 5;
40 // Stores a provided file system information in preferences together with a
42 void RememberFakeFileSystem(TestingProfile
* profile
,
43 const std::string
& extension_id
,
44 const std::string
& file_system_id
,
45 const std::string
& display_name
,
47 bool supports_notify_tag
,
48 int opened_files_limit
,
49 const Watcher
& watcher
) {
50 // Warning. Updating this code means that backward compatibility may be
51 // broken, what is unexpected and should be avoided.
52 TestingPrefServiceSyncable
* const pref_service
=
53 profile
->GetTestingPrefService();
54 ASSERT_TRUE(pref_service
);
56 base::DictionaryValue extensions
;
57 base::DictionaryValue
* const file_systems
= new base::DictionaryValue();
58 base::DictionaryValue
* const file_system
= new base::DictionaryValue();
59 file_system
->SetStringWithoutPathExpansion(kPrefKeyFileSystemId
,
61 file_system
->SetStringWithoutPathExpansion(kPrefKeyDisplayName
, kDisplayName
);
62 file_system
->SetBooleanWithoutPathExpansion(kPrefKeyWritable
, writable
);
63 file_system
->SetBooleanWithoutPathExpansion(kPrefKeySupportsNotifyTag
,
65 file_system
->SetIntegerWithoutPathExpansion(kPrefKeyOpenedFilesLimit
,
67 file_systems
->SetWithoutPathExpansion(kFileSystemId
, file_system
);
68 extensions
.SetWithoutPathExpansion(kExtensionId
, file_systems
);
71 base::DictionaryValue
* const watchers
= new base::DictionaryValue();
72 file_system
->SetWithoutPathExpansion(kPrefKeyWatchers
, watchers
);
73 base::DictionaryValue
* const watcher_value
= new base::DictionaryValue();
74 watchers
->SetWithoutPathExpansion(watcher
.entry_path
.value(), watcher_value
);
75 watcher_value
->SetStringWithoutPathExpansion(kPrefKeyWatcherEntryPath
,
76 watcher
.entry_path
.value());
77 watcher_value
->SetBooleanWithoutPathExpansion(kPrefKeyWatcherRecursive
,
79 watcher_value
->SetStringWithoutPathExpansion(kPrefKeyWatcherLastTag
,
81 base::ListValue
* const persistent_origins_value
= new base::ListValue();
82 watcher_value
->SetWithoutPathExpansion(kPrefKeyWatcherPersistentOrigins
,
83 persistent_origins_value
);
84 for (const auto& subscriber_it
: watcher
.subscribers
) {
85 if (subscriber_it
.second
.persistent
)
86 persistent_origins_value
->AppendString(subscriber_it
.first
.spec());
89 pref_service
->Set(prefs::kFileSystemProviderMounted
, extensions
);
94 class FileSystemProviderRegistryTest
: public testing::Test
{
96 FileSystemProviderRegistryTest() : profile_(NULL
) {}
98 ~FileSystemProviderRegistryTest() override
{}
100 void SetUp() override
{
101 profile_manager_
.reset(
102 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
103 ASSERT_TRUE(profile_manager_
->SetUp());
104 profile_
= profile_manager_
->CreateTestingProfile("test-user@example.com");
105 registry_
.reset(new Registry(profile_
));
106 fake_watcher_
.entry_path
= base::FilePath(FILE_PATH_LITERAL("/a/b/c"));
107 fake_watcher_
.recursive
= true;
108 fake_watcher_
.subscribers
[GURL(kTemporaryOrigin
)].origin
=
109 GURL(kTemporaryOrigin
);
110 fake_watcher_
.subscribers
[GURL(kTemporaryOrigin
)].persistent
= false;
111 fake_watcher_
.subscribers
[GURL(kPersistentOrigin
)].origin
=
112 GURL(kPersistentOrigin
);
113 fake_watcher_
.subscribers
[GURL(kPersistentOrigin
)].persistent
= true;
114 fake_watcher_
.last_tag
= "hello-world";
117 content::TestBrowserThreadBundle thread_bundle_
;
118 scoped_ptr
<TestingProfileManager
> profile_manager_
;
119 TestingProfile
* profile_
;
120 scoped_ptr
<RegistryInterface
> registry_
;
121 Watcher fake_watcher_
;
124 TEST_F(FileSystemProviderRegistryTest
, RestoreFileSystems
) {
125 // Create a fake entry in the preferences.
126 RememberFakeFileSystem(profile_
, kExtensionId
, kFileSystemId
, kDisplayName
,
127 true /* writable */, true /* supports_notify_tag */,
128 kOpenedFilesLimit
, fake_watcher_
);
130 scoped_ptr
<RegistryInterface::RestoredFileSystems
> restored_file_systems
=
131 registry_
->RestoreFileSystems(kExtensionId
);
133 ASSERT_EQ(1u, restored_file_systems
->size());
134 const RegistryInterface::RestoredFileSystem
& restored_file_system
=
135 restored_file_systems
->at(0);
136 EXPECT_EQ(kExtensionId
, restored_file_system
.extension_id
);
137 EXPECT_EQ(kFileSystemId
, restored_file_system
.options
.file_system_id
);
138 EXPECT_EQ(kDisplayName
, restored_file_system
.options
.display_name
);
139 EXPECT_TRUE(restored_file_system
.options
.writable
);
140 EXPECT_TRUE(restored_file_system
.options
.supports_notify_tag
);
141 EXPECT_EQ(kOpenedFilesLimit
, restored_file_system
.options
.opened_files_limit
);
143 ASSERT_EQ(1u, restored_file_system
.watchers
.size());
144 const auto& restored_watcher_it
= restored_file_system
.watchers
.find(
145 WatcherKey(fake_watcher_
.entry_path
, fake_watcher_
.recursive
));
146 ASSERT_NE(restored_file_system
.watchers
.end(), restored_watcher_it
);
148 EXPECT_EQ(fake_watcher_
.entry_path
, restored_watcher_it
->second
.entry_path
);
149 EXPECT_EQ(fake_watcher_
.recursive
, restored_watcher_it
->second
.recursive
);
150 EXPECT_EQ(fake_watcher_
.last_tag
, restored_watcher_it
->second
.last_tag
);
153 TEST_F(FileSystemProviderRegistryTest
, RememberFileSystem
) {
154 MountOptions
options(kFileSystemId
, kDisplayName
);
155 options
.writable
= true;
156 options
.supports_notify_tag
= true;
157 options
.opened_files_limit
= kOpenedFilesLimit
;
159 ProvidedFileSystemInfo
file_system_info(
160 kExtensionId
, options
, base::FilePath(FILE_PATH_LITERAL("/a/b/c")));
163 watchers
[WatcherKey(fake_watcher_
.entry_path
, fake_watcher_
.recursive
)] =
166 registry_
->RememberFileSystem(file_system_info
, watchers
);
168 TestingPrefServiceSyncable
* const pref_service
=
169 profile_
->GetTestingPrefService();
170 ASSERT_TRUE(pref_service
);
172 const base::DictionaryValue
* const extensions
=
173 pref_service
->GetDictionary(prefs::kFileSystemProviderMounted
);
174 ASSERT_TRUE(extensions
);
176 const base::DictionaryValue
* file_systems
= NULL
;
177 ASSERT_TRUE(extensions
->GetDictionaryWithoutPathExpansion(kExtensionId
,
179 EXPECT_EQ(1u, file_systems
->size());
181 const base::Value
* file_system_value
= NULL
;
182 const base::DictionaryValue
* file_system
= NULL
;
184 file_systems
->GetWithoutPathExpansion(kFileSystemId
, &file_system_value
));
185 ASSERT_TRUE(file_system_value
->GetAsDictionary(&file_system
));
187 std::string file_system_id
;
188 EXPECT_TRUE(file_system
->GetStringWithoutPathExpansion(kPrefKeyFileSystemId
,
190 EXPECT_EQ(kFileSystemId
, file_system_id
);
192 std::string display_name
;
193 EXPECT_TRUE(file_system
->GetStringWithoutPathExpansion(kPrefKeyDisplayName
,
195 EXPECT_EQ(kDisplayName
, display_name
);
197 bool writable
= false;
199 file_system
->GetBooleanWithoutPathExpansion(kPrefKeyWritable
, &writable
));
200 EXPECT_TRUE(writable
);
202 bool supports_notify_tag
= false;
203 EXPECT_TRUE(file_system
->GetBooleanWithoutPathExpansion(
204 kPrefKeySupportsNotifyTag
, &supports_notify_tag
));
205 EXPECT_TRUE(supports_notify_tag
);
207 int opened_files_limit
= 0;
208 EXPECT_TRUE(file_system
->GetIntegerWithoutPathExpansion(
209 kPrefKeyOpenedFilesLimit
, &opened_files_limit
));
210 EXPECT_EQ(kOpenedFilesLimit
, opened_files_limit
);
212 const base::DictionaryValue
* watchers_value
= NULL
;
213 ASSERT_TRUE(file_system
->GetDictionaryWithoutPathExpansion(kPrefKeyWatchers
,
216 const base::DictionaryValue
* watcher
= NULL
;
217 ASSERT_TRUE(watchers_value
->GetDictionaryWithoutPathExpansion(
218 fake_watcher_
.entry_path
.value(), &watcher
));
220 std::string entry_path
;
221 EXPECT_TRUE(watcher
->GetStringWithoutPathExpansion(kPrefKeyWatcherEntryPath
,
223 EXPECT_EQ(fake_watcher_
.entry_path
.value(), entry_path
);
225 bool recursive
= false;
226 EXPECT_TRUE(watcher
->GetBooleanWithoutPathExpansion(kPrefKeyWatcherRecursive
,
228 EXPECT_EQ(fake_watcher_
.recursive
, recursive
);
230 std::string last_tag
;
231 EXPECT_TRUE(watcher
->GetStringWithoutPathExpansion(kPrefKeyWatcherLastTag
,
233 EXPECT_EQ(fake_watcher_
.last_tag
, last_tag
);
235 const base::ListValue
* persistent_origins
= NULL
;
236 ASSERT_TRUE(watcher
->GetListWithoutPathExpansion(
237 kPrefKeyWatcherPersistentOrigins
, &persistent_origins
));
238 ASSERT_GT(fake_watcher_
.subscribers
.size(), persistent_origins
->GetSize());
239 ASSERT_EQ(1u, persistent_origins
->GetSize());
240 std::string persistent_origin
;
241 EXPECT_TRUE(persistent_origins
->GetString(0, &persistent_origin
));
242 const auto& fake_subscriber_it
=
243 fake_watcher_
.subscribers
.find(GURL(persistent_origin
));
244 ASSERT_NE(fake_watcher_
.subscribers
.end(), fake_subscriber_it
);
245 EXPECT_TRUE(fake_subscriber_it
->second
.persistent
);
248 TEST_F(FileSystemProviderRegistryTest
, ForgetFileSystem
) {
249 // Create a fake file systems in the preferences.
250 RememberFakeFileSystem(profile_
, kExtensionId
, kFileSystemId
, kDisplayName
,
251 true /* writable */, true /* supports_notify_tag */,
252 kOpenedFilesLimit
, fake_watcher_
);
254 registry_
->ForgetFileSystem(kExtensionId
, kFileSystemId
);
256 TestingPrefServiceSyncable
* const pref_service
=
257 profile_
->GetTestingPrefService();
258 ASSERT_TRUE(pref_service
);
260 const base::DictionaryValue
* const extensions
=
261 pref_service
->GetDictionary(prefs::kFileSystemProviderMounted
);
262 ASSERT_TRUE(extensions
);
264 const base::DictionaryValue
* file_systems
= NULL
;
265 EXPECT_FALSE(extensions
->GetDictionaryWithoutPathExpansion(kExtensionId
,
269 TEST_F(FileSystemProviderRegistryTest
, UpdateWatcherTag
) {
270 MountOptions
options(kFileSystemId
, kDisplayName
);
271 options
.writable
= true;
272 options
.supports_notify_tag
= true;
274 ProvidedFileSystemInfo
file_system_info(
275 kExtensionId
, options
, base::FilePath(FILE_PATH_LITERAL("/a/b/c")));
278 watchers
[WatcherKey(fake_watcher_
.entry_path
, fake_watcher_
.recursive
)] =
281 registry_
->RememberFileSystem(file_system_info
, watchers
);
283 fake_watcher_
.last_tag
= "updated-tag";
284 registry_
->UpdateWatcherTag(file_system_info
, fake_watcher_
);
286 TestingPrefServiceSyncable
* const pref_service
=
287 profile_
->GetTestingPrefService();
288 ASSERT_TRUE(pref_service
);
290 const base::DictionaryValue
* const extensions
=
291 pref_service
->GetDictionary(prefs::kFileSystemProviderMounted
);
292 ASSERT_TRUE(extensions
);
294 const base::DictionaryValue
* file_systems
= NULL
;
295 ASSERT_TRUE(extensions
->GetDictionaryWithoutPathExpansion(kExtensionId
,
297 EXPECT_EQ(1u, file_systems
->size());
299 const base::Value
* file_system_value
= NULL
;
300 const base::DictionaryValue
* file_system
= NULL
;
302 file_systems
->GetWithoutPathExpansion(kFileSystemId
, &file_system_value
));
303 ASSERT_TRUE(file_system_value
->GetAsDictionary(&file_system
));
305 const base::DictionaryValue
* watchers_value
= NULL
;
306 ASSERT_TRUE(file_system
->GetDictionaryWithoutPathExpansion(kPrefKeyWatchers
,
309 const base::DictionaryValue
* watcher
= NULL
;
310 ASSERT_TRUE(watchers_value
->GetDictionaryWithoutPathExpansion(
311 fake_watcher_
.entry_path
.value(), &watcher
));
313 std::string last_tag
;
314 EXPECT_TRUE(watcher
->GetStringWithoutPathExpansion(kPrefKeyWatcherLastTag
,
316 EXPECT_EQ(fake_watcher_
.last_tag
, last_tag
);
319 } // namespace file_system_provider
320 } // namespace chromeos