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 // Stores a provided file system information in preferences together with a
40 void RememberFakeFileSystem(TestingProfile
* profile
,
41 const std::string
& extension_id
,
42 const std::string
& file_system_id
,
43 const std::string
& display_name
,
45 bool supports_notify_tag
,
46 const Watcher
& watcher
) {
47 // Warning. Updating this code means that backward compatibility may be
48 // broken, what is unexpected and should be avoided.
49 TestingPrefServiceSyncable
* const pref_service
=
50 profile
->GetTestingPrefService();
51 ASSERT_TRUE(pref_service
);
53 base::DictionaryValue extensions
;
54 base::DictionaryValue
* const file_systems
= new base::DictionaryValue();
55 base::DictionaryValue
* const file_system
= new base::DictionaryValue();
56 file_system
->SetStringWithoutPathExpansion(kPrefKeyFileSystemId
,
58 file_system
->SetStringWithoutPathExpansion(kPrefKeyDisplayName
, kDisplayName
);
59 file_system
->SetBooleanWithoutPathExpansion(kPrefKeyWritable
, writable
);
60 file_system
->SetBooleanWithoutPathExpansion(kPrefKeySupportsNotifyTag
,
62 file_systems
->SetWithoutPathExpansion(kFileSystemId
, file_system
);
63 extensions
.SetWithoutPathExpansion(kExtensionId
, file_systems
);
66 base::DictionaryValue
* const watchers
= new base::DictionaryValue();
67 file_system
->SetWithoutPathExpansion(kPrefKeyWatchers
, watchers
);
68 base::DictionaryValue
* const watcher_value
= new base::DictionaryValue();
69 watchers
->SetWithoutPathExpansion(watcher
.entry_path
.value(), watcher_value
);
70 watcher_value
->SetStringWithoutPathExpansion(kPrefKeyWatcherEntryPath
,
71 watcher
.entry_path
.value());
72 watcher_value
->SetBooleanWithoutPathExpansion(kPrefKeyWatcherRecursive
,
74 watcher_value
->SetStringWithoutPathExpansion(kPrefKeyWatcherLastTag
,
76 base::ListValue
* const persistent_origins_value
= new base::ListValue();
77 watcher_value
->SetWithoutPathExpansion(kPrefKeyWatcherPersistentOrigins
,
78 persistent_origins_value
);
79 for (const auto& subscriber_it
: watcher
.subscribers
) {
80 if (subscriber_it
.second
.persistent
)
81 persistent_origins_value
->AppendString(subscriber_it
.first
.spec());
84 pref_service
->Set(prefs::kFileSystemProviderMounted
, extensions
);
89 class FileSystemProviderRegistryTest
: public testing::Test
{
91 FileSystemProviderRegistryTest() : profile_(NULL
) {}
93 virtual ~FileSystemProviderRegistryTest() {}
95 virtual void SetUp() override
{
96 profile_manager_
.reset(
97 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
98 ASSERT_TRUE(profile_manager_
->SetUp());
99 profile_
= profile_manager_
->CreateTestingProfile("test-user@example.com");
100 registry_
.reset(new Registry(profile_
));
101 fake_watcher_
.entry_path
= base::FilePath(FILE_PATH_LITERAL("/a/b/c"));
102 fake_watcher_
.recursive
= true;
103 fake_watcher_
.subscribers
[GURL(kTemporaryOrigin
)].origin
=
104 GURL(kTemporaryOrigin
);
105 fake_watcher_
.subscribers
[GURL(kTemporaryOrigin
)].persistent
= false;
106 fake_watcher_
.subscribers
[GURL(kPersistentOrigin
)].origin
=
107 GURL(kPersistentOrigin
);
108 fake_watcher_
.subscribers
[GURL(kPersistentOrigin
)].persistent
= true;
109 fake_watcher_
.last_tag
= "hello-world";
112 content::TestBrowserThreadBundle thread_bundle_
;
113 scoped_ptr
<TestingProfileManager
> profile_manager_
;
114 TestingProfile
* profile_
;
115 scoped_ptr
<RegistryInterface
> registry_
;
116 Watcher fake_watcher_
;
119 TEST_F(FileSystemProviderRegistryTest
, RestoreFileSystems
) {
120 // Create a fake entry in the preferences.
121 RememberFakeFileSystem(profile_
,
126 true /* supports_notify_tag */,
129 scoped_ptr
<RegistryInterface::RestoredFileSystems
> restored_file_systems
=
130 registry_
->RestoreFileSystems(kExtensionId
);
132 ASSERT_EQ(1u, restored_file_systems
->size());
133 const RegistryInterface::RestoredFileSystem
& restored_file_system
=
134 restored_file_systems
->at(0);
135 EXPECT_EQ(kExtensionId
, restored_file_system
.extension_id
);
136 EXPECT_EQ(kFileSystemId
, restored_file_system
.options
.file_system_id
);
137 EXPECT_EQ(kDisplayName
, restored_file_system
.options
.display_name
);
138 EXPECT_TRUE(restored_file_system
.options
.writable
);
139 EXPECT_TRUE(restored_file_system
.options
.supports_notify_tag
);
141 ASSERT_EQ(1u, restored_file_system
.watchers
.size());
142 const auto& restored_watcher_it
= restored_file_system
.watchers
.find(
143 WatcherKey(fake_watcher_
.entry_path
, fake_watcher_
.recursive
));
144 ASSERT_NE(restored_file_system
.watchers
.end(), restored_watcher_it
);
146 EXPECT_EQ(fake_watcher_
.entry_path
, restored_watcher_it
->second
.entry_path
);
147 EXPECT_EQ(fake_watcher_
.recursive
, restored_watcher_it
->second
.recursive
);
148 EXPECT_EQ(fake_watcher_
.last_tag
, restored_watcher_it
->second
.last_tag
);
151 TEST_F(FileSystemProviderRegistryTest
, RememberFileSystem
) {
152 MountOptions
options(kFileSystemId
, kDisplayName
);
153 options
.writable
= true;
154 options
.supports_notify_tag
= true;
156 ProvidedFileSystemInfo
file_system_info(
157 kExtensionId
, options
, base::FilePath(FILE_PATH_LITERAL("/a/b/c")));
160 watchers
[WatcherKey(fake_watcher_
.entry_path
, fake_watcher_
.recursive
)] =
163 registry_
->RememberFileSystem(file_system_info
, watchers
);
165 TestingPrefServiceSyncable
* const pref_service
=
166 profile_
->GetTestingPrefService();
167 ASSERT_TRUE(pref_service
);
169 const base::DictionaryValue
* const extensions
=
170 pref_service
->GetDictionary(prefs::kFileSystemProviderMounted
);
171 ASSERT_TRUE(extensions
);
173 const base::DictionaryValue
* file_systems
= NULL
;
174 ASSERT_TRUE(extensions
->GetDictionaryWithoutPathExpansion(kExtensionId
,
176 EXPECT_EQ(1u, file_systems
->size());
178 const base::Value
* file_system_value
= NULL
;
179 const base::DictionaryValue
* file_system
= NULL
;
181 file_systems
->GetWithoutPathExpansion(kFileSystemId
, &file_system_value
));
182 ASSERT_TRUE(file_system_value
->GetAsDictionary(&file_system
));
184 std::string file_system_id
;
185 EXPECT_TRUE(file_system
->GetStringWithoutPathExpansion(kPrefKeyFileSystemId
,
187 EXPECT_EQ(kFileSystemId
, file_system_id
);
189 std::string display_name
;
190 EXPECT_TRUE(file_system
->GetStringWithoutPathExpansion(kPrefKeyDisplayName
,
192 EXPECT_EQ(kDisplayName
, display_name
);
194 bool writable
= false;
196 file_system
->GetBooleanWithoutPathExpansion(kPrefKeyWritable
, &writable
));
197 EXPECT_TRUE(writable
);
199 bool supports_notify_tag
= false;
200 EXPECT_TRUE(file_system
->GetBooleanWithoutPathExpansion(
201 kPrefKeySupportsNotifyTag
, &supports_notify_tag
));
202 EXPECT_TRUE(supports_notify_tag
);
204 const base::DictionaryValue
* watchers_value
= NULL
;
205 ASSERT_TRUE(file_system
->GetDictionaryWithoutPathExpansion(kPrefKeyWatchers
,
208 const base::DictionaryValue
* watcher
= NULL
;
209 ASSERT_TRUE(watchers_value
->GetDictionaryWithoutPathExpansion(
210 fake_watcher_
.entry_path
.value(), &watcher
));
212 std::string entry_path
;
213 EXPECT_TRUE(watcher
->GetStringWithoutPathExpansion(kPrefKeyWatcherEntryPath
,
215 EXPECT_EQ(fake_watcher_
.entry_path
.value(), entry_path
);
217 bool recursive
= false;
218 EXPECT_TRUE(watcher
->GetBooleanWithoutPathExpansion(kPrefKeyWatcherRecursive
,
220 EXPECT_EQ(fake_watcher_
.recursive
, recursive
);
222 std::string last_tag
;
223 EXPECT_TRUE(watcher
->GetStringWithoutPathExpansion(kPrefKeyWatcherLastTag
,
225 EXPECT_EQ(fake_watcher_
.last_tag
, last_tag
);
227 const base::ListValue
* persistent_origins
= NULL
;
228 ASSERT_TRUE(watcher
->GetListWithoutPathExpansion(
229 kPrefKeyWatcherPersistentOrigins
, &persistent_origins
));
230 ASSERT_GT(fake_watcher_
.subscribers
.size(), persistent_origins
->GetSize());
231 ASSERT_EQ(1u, persistent_origins
->GetSize());
232 std::string persistent_origin
;
233 EXPECT_TRUE(persistent_origins
->GetString(0, &persistent_origin
));
234 const auto& fake_subscriber_it
=
235 fake_watcher_
.subscribers
.find(GURL(persistent_origin
));
236 ASSERT_NE(fake_watcher_
.subscribers
.end(), fake_subscriber_it
);
237 EXPECT_TRUE(fake_subscriber_it
->second
.persistent
);
240 TEST_F(FileSystemProviderRegistryTest
, ForgetFileSystem
) {
241 // Create a fake file systems in the preferences.
242 RememberFakeFileSystem(profile_
,
247 true /* supports_notify_tag */,
250 registry_
->ForgetFileSystem(kExtensionId
, kFileSystemId
);
252 TestingPrefServiceSyncable
* const pref_service
=
253 profile_
->GetTestingPrefService();
254 ASSERT_TRUE(pref_service
);
256 const base::DictionaryValue
* const extensions
=
257 pref_service
->GetDictionary(prefs::kFileSystemProviderMounted
);
258 ASSERT_TRUE(extensions
);
260 const base::DictionaryValue
* file_systems
= NULL
;
261 EXPECT_FALSE(extensions
->GetDictionaryWithoutPathExpansion(kExtensionId
,
265 TEST_F(FileSystemProviderRegistryTest
, UpdateWatcherTag
) {
266 MountOptions
options(kFileSystemId
, kDisplayName
);
267 options
.writable
= true;
268 options
.supports_notify_tag
= true;
270 ProvidedFileSystemInfo
file_system_info(
271 kExtensionId
, options
, base::FilePath(FILE_PATH_LITERAL("/a/b/c")));
274 watchers
[WatcherKey(fake_watcher_
.entry_path
, fake_watcher_
.recursive
)] =
277 registry_
->RememberFileSystem(file_system_info
, watchers
);
279 fake_watcher_
.last_tag
= "updated-tag";
280 registry_
->UpdateWatcherTag(file_system_info
, fake_watcher_
);
282 TestingPrefServiceSyncable
* const pref_service
=
283 profile_
->GetTestingPrefService();
284 ASSERT_TRUE(pref_service
);
286 const base::DictionaryValue
* const extensions
=
287 pref_service
->GetDictionary(prefs::kFileSystemProviderMounted
);
288 ASSERT_TRUE(extensions
);
290 const base::DictionaryValue
* file_systems
= NULL
;
291 ASSERT_TRUE(extensions
->GetDictionaryWithoutPathExpansion(kExtensionId
,
293 EXPECT_EQ(1u, file_systems
->size());
295 const base::Value
* file_system_value
= NULL
;
296 const base::DictionaryValue
* file_system
= NULL
;
298 file_systems
->GetWithoutPathExpansion(kFileSystemId
, &file_system_value
));
299 ASSERT_TRUE(file_system_value
->GetAsDictionary(&file_system
));
301 const base::DictionaryValue
* watchers_value
= NULL
;
302 ASSERT_TRUE(file_system
->GetDictionaryWithoutPathExpansion(kPrefKeyWatchers
,
305 const base::DictionaryValue
* watcher
= NULL
;
306 ASSERT_TRUE(watchers_value
->GetDictionaryWithoutPathExpansion(
307 fake_watcher_
.entry_path
.value(), &watcher
));
309 std::string last_tag
;
310 EXPECT_TRUE(watcher
->GetStringWithoutPathExpansion(kPrefKeyWatcherLastTag
,
312 EXPECT_EQ(fake_watcher_
.last_tag
, last_tag
);
315 } // namespace file_system_provider
316 } // namespace chromeos