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.
6 #include "base/command_line.h"
7 #include "base/files/file_path.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/run_loop.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/time/time.h"
14 #include "chrome/browser/extensions/test_extension_system.h"
15 #include "chrome/browser/media_galleries/media_galleries_dialog_controller_test_util.h"
16 #include "chrome/browser/media_galleries/media_galleries_preferences.h"
17 #include "chrome/browser/media_galleries/media_galleries_scan_result_controller.h"
18 #include "chrome/browser/media_galleries/media_galleries_test_util.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "components/storage_monitor/test_storage_monitor.h"
21 #include "content/public/test/test_browser_thread_bundle.h"
22 #include "extensions/browser/extension_system.h"
23 #include "extensions/common/extension.h"
24 #include "extensions/common/permissions/media_galleries_permission.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 #if defined(OS_CHROMEOS)
28 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
29 #include "chrome/browser/chromeos/settings/cros_settings.h"
30 #include "chrome/browser/chromeos/settings/device_settings_service.h"
33 class MediaGalleriesScanResultControllerTest
: public testing::Test
{
35 MediaGalleriesScanResultControllerTest()
37 dialog_update_count_at_destruction_(0),
39 profile_(new TestingProfile()),
43 virtual ~MediaGalleriesScanResultControllerTest() {
44 EXPECT_FALSE(controller_
);
45 EXPECT_FALSE(dialog_
);
48 virtual void SetUp() override
{
49 ASSERT_TRUE(storage_monitor::TestStorageMonitor::CreateAndInstall());
51 extensions::TestExtensionSystem
* extension_system(
52 static_cast<extensions::TestExtensionSystem
*>(
53 extensions::ExtensionSystem::Get(profile_
.get())));
54 extension_system
->CreateExtensionService(
55 CommandLine::ForCurrentProcess(), base::FilePath(), false);
57 gallery_prefs_
.reset(new MediaGalleriesPreferences(profile_
.get()));
59 gallery_prefs_
->EnsureInitialized(loop
.QuitClosure());
62 std::vector
<std::string
> read_permissions
;
63 read_permissions
.push_back(
64 extensions::MediaGalleriesPermission::kReadPermission
);
65 extension_
= AddMediaGalleriesApp("read", read_permissions
, profile_
.get());
68 virtual void TearDown() override
{
69 storage_monitor::TestStorageMonitor::Destroy();
73 ASSERT_FALSE(controller_
);
74 controller_
= new MediaGalleriesScanResultController(
78 &MediaGalleriesScanResultControllerTest::CreateMockDialog
,
79 base::Unretained(this)),
81 &MediaGalleriesScanResultControllerTest::OnControllerDone
,
82 base::Unretained(this)));
85 size_t GetFirstSectionSize() const {
86 return controller()->GetSectionEntries(0).size();
89 MediaGalleriesScanResultController
* controller() const {
93 MockMediaGalleriesDialog
* dialog() {
97 int dialog_update_count_at_destruction() {
98 EXPECT_FALSE(dialog_
);
99 return dialog_update_count_at_destruction_
;
102 extensions::Extension
* extension() {
103 return extension_
.get();
106 MediaGalleriesPreferences
* gallery_prefs() {
107 return gallery_prefs_
.get();
110 MediaGalleryPrefId
AddGallery(const std::string
& path
,
111 MediaGalleryPrefInfo::Type type
,
112 int audio_count
, int image_count
,
114 MediaGalleryPrefInfo gallery_info
;
115 gallery_prefs_
->LookUpGalleryByPath(MakeMediaGalleriesTestingPath(path
),
117 return gallery_prefs_
->AddGallery(
118 gallery_info
.device_id
,
121 gallery_info
.volume_label
,
122 gallery_info
.vendor_name
,
123 gallery_info
.model_name
,
124 gallery_info
.total_size_in_bytes
,
125 gallery_info
.last_attach_time
,
126 audio_count
, image_count
, video_count
);
129 MediaGalleryPrefId
AddScanResult(const std::string
& path
, int audio_count
,
130 int image_count
, int video_count
) {
131 return AddGallery(path
, MediaGalleryPrefInfo::kScanResult
, audio_count
,
132 image_count
, video_count
);
136 MediaGalleriesDialog
* CreateMockDialog(
137 MediaGalleriesDialogController
* controller
) {
138 EXPECT_FALSE(dialog_
);
139 dialog_update_count_at_destruction_
= 0;
140 dialog_
= new MockMediaGalleriesDialog(base::Bind(
141 &MediaGalleriesScanResultControllerTest::OnDialogDestroyed
,
142 weak_factory_
.GetWeakPtr()));
146 void OnDialogDestroyed(int update_count
) {
147 EXPECT_TRUE(dialog_
);
148 dialog_update_count_at_destruction_
= update_count
;
152 void OnControllerDone() {
156 // Needed for extension service & friends to work.
157 content::TestBrowserThreadBundle thread_bundle_
;
159 // The dialog is owned by the controller, but this pointer should only be
160 // valid while the dialog is live within the controller.
161 MockMediaGalleriesDialog
* dialog_
;
162 int dialog_update_count_at_destruction_
;
164 // The controller owns itself.
165 MediaGalleriesScanResultController
* controller_
;
167 scoped_refptr
<extensions::Extension
> extension_
;
169 EnsureMediaDirectoriesExists mock_gallery_locations_
;
171 #if defined OS_CHROMEOS
172 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_
;
173 chromeos::ScopedTestCrosSettings test_cros_settings_
;
174 chromeos::ScopedTestUserManager test_user_manager_
;
177 storage_monitor::TestStorageMonitor monitor_
;
178 scoped_ptr
<TestingProfile
> profile_
;
179 scoped_ptr
<MediaGalleriesPreferences
> gallery_prefs_
;
181 base::WeakPtrFactory
<MediaGalleriesScanResultControllerTest
> weak_factory_
;
183 DISALLOW_COPY_AND_ASSIGN(MediaGalleriesScanResultControllerTest
);
186 TEST_F(MediaGalleriesScanResultControllerTest
, EmptyDialog
) {
188 EXPECT_TRUE(controller());
189 EXPECT_TRUE(dialog());
190 EXPECT_EQ(0U, GetFirstSectionSize());
192 controller()->DialogFinished(true);
193 EXPECT_FALSE(controller());
194 EXPECT_FALSE(dialog());
195 EXPECT_EQ(0, dialog_update_count_at_destruction());
198 TEST_F(MediaGalleriesScanResultControllerTest
, AddScanResults
) {
199 // Start with two scan results.
200 MediaGalleryPrefId scan_id
= AddScanResult("scan_id", 1, 0, 0);
201 MediaGalleryPrefId auto_id
=
202 AddGallery("auto_id", MediaGalleryPrefInfo::kAutoDetected
, 2, 0, 0);
203 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
205 // Show the dialog, but cancel it.
207 EXPECT_EQ(2U, GetFirstSectionSize());
208 controller()->DialogFinished(false);
209 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
211 // Show the dialog, unselect both and accept it.
213 EXPECT_EQ(2U, GetFirstSectionSize());
214 controller()->DidToggleEntry(scan_id
, false);
215 controller()->DidToggleEntry(auto_id
, false);
216 controller()->DialogFinished(true);
217 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
219 // Show the dialog, leave one selected and accept it.
221 EXPECT_EQ(2U, GetFirstSectionSize());
222 controller()->DidToggleEntry(scan_id
, false);
223 controller()->DialogFinished(true);
224 MediaGalleryPrefIdSet permitted
=
225 gallery_prefs()->GalleriesForExtension(*extension());
226 ASSERT_EQ(1U, permitted
.size());
227 EXPECT_EQ(auto_id
, *permitted
.begin());
229 // Show the dialog, toggle the remaining entry twice and then accept it.
231 EXPECT_EQ(1U, GetFirstSectionSize());
232 controller()->DidToggleEntry(scan_id
, false);
233 controller()->DidToggleEntry(scan_id
, true);
234 controller()->DialogFinished(true);
235 EXPECT_EQ(2U, gallery_prefs()->GalleriesForExtension(*extension()).size());
238 TEST_F(MediaGalleriesScanResultControllerTest
, Blacklisted
) {
239 // Start with two scan results.
240 MediaGalleryPrefId scan_id
= AddScanResult("scan_id", 1, 0, 0);
241 MediaGalleryPrefId auto_id
=
242 AddGallery("auto_id", MediaGalleryPrefInfo::kAutoDetected
, 2, 0, 0);
243 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
245 // Show the dialog, but cancel it.
247 EXPECT_EQ(2U, GetFirstSectionSize());
248 controller()->DialogFinished(false);
249 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
251 // Blacklist one and try again.
252 gallery_prefs()->ForgetGalleryById(scan_id
);
254 EXPECT_EQ(1U, GetFirstSectionSize());
255 controller()->DialogFinished(false);
257 // Adding it as a user gallery should change its type.
258 AddGallery("scan_id", MediaGalleryPrefInfo::kUserAdded
, 1, 0, 0);
260 EXPECT_EQ(2U, GetFirstSectionSize());
262 // Blacklisting the other while the dialog is open should remove it.
263 gallery_prefs()->ForgetGalleryById(auto_id
);
264 EXPECT_EQ(1U, GetFirstSectionSize());
265 controller()->DialogFinished(false);
266 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
267 EXPECT_EQ(1, dialog_update_count_at_destruction());
270 TEST_F(MediaGalleriesScanResultControllerTest
, PrefUpdates
) {
271 MediaGalleryPrefId selected
= AddScanResult("selected", 1, 0, 0);
272 MediaGalleryPrefId unselected
= AddScanResult("unselected", 1, 0, 0);
273 MediaGalleryPrefId selected_add_permission
=
274 AddScanResult("selected_add_permission", 1, 0, 0);
275 MediaGalleryPrefId unselected_add_permission
=
276 AddScanResult("unselected_add_permission", 1, 0, 0);
277 MediaGalleryPrefId selected_removed
=
278 AddScanResult("selected_removed", 1, 0, 0);
279 MediaGalleryPrefId unselected_removed
=
280 AddScanResult("unselected_removed", 1, 0, 0);
281 MediaGalleryPrefId selected_update
=
282 AddScanResult("selected_update", 1, 0, 0);
283 MediaGalleryPrefId unselected_update
=
284 AddScanResult("unselected_update", 1, 0, 0);
286 gallery_prefs()->AddGalleryByPath(MakeMediaGalleriesTestingPath("user"),
287 MediaGalleryPrefInfo::kUserAdded
);
288 gallery_prefs()->AddGalleryByPath(
289 MakeMediaGalleriesTestingPath("auto_detected"),
290 MediaGalleryPrefInfo::kAutoDetected
);
291 MediaGalleryPrefId blacklisted
= gallery_prefs()->AddGalleryByPath(
292 MakeMediaGalleriesTestingPath("blacklisted"),
293 MediaGalleryPrefInfo::kAutoDetected
);
294 gallery_prefs()->ForgetGalleryById(blacklisted
);
295 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
298 EXPECT_EQ(8U, GetFirstSectionSize());
299 controller()->DidToggleEntry(unselected
, false);
300 controller()->DidToggleEntry(unselected_add_permission
, false);
301 controller()->DidToggleEntry(unselected_removed
, false);
302 controller()->DidToggleEntry(unselected_update
, false);
303 EXPECT_EQ(0, dialog()->update_count());
304 EXPECT_EQ(8U, GetFirstSectionSize());
307 gallery_prefs()->SetGalleryPermissionForExtension(*extension(),
308 unselected_add_permission
,
310 EXPECT_EQ(1, dialog()->update_count());
311 EXPECT_EQ(7U, GetFirstSectionSize());
312 gallery_prefs()->SetGalleryPermissionForExtension(*extension(),
313 selected_add_permission
,
315 EXPECT_EQ(2, dialog()->update_count());
316 EXPECT_EQ(6U, GetFirstSectionSize());
318 // Blacklist scan results.
319 gallery_prefs()->ForgetGalleryById(unselected_removed
);
320 EXPECT_EQ(3, dialog()->update_count());
321 EXPECT_EQ(5U, GetFirstSectionSize());
322 gallery_prefs()->ForgetGalleryById(selected_removed
);
323 EXPECT_EQ(4, dialog()->update_count());
324 EXPECT_EQ(4U, GetFirstSectionSize());
327 const MediaGalleryPrefInfo
& unselected_update_info
=
328 gallery_prefs()->known_galleries().find(unselected_update
)->second
;
329 gallery_prefs()->AddGallery(
330 unselected_update_info
.device_id
, base::FilePath(),
331 MediaGalleryPrefInfo::kScanResult
,
332 base::ASCIIToUTF16("Updated & Unselected"),
333 base::string16(), base::string16(), 0, base::Time(), 1, 0, 0);
334 EXPECT_EQ(5, dialog()->update_count());
335 EXPECT_EQ(4U, GetFirstSectionSize());
336 const MediaGalleryPrefInfo
& selected_update_info
=
337 gallery_prefs()->known_galleries().find(selected_update
)->second
;
338 gallery_prefs()->AddGallery(
339 selected_update_info
.device_id
, base::FilePath(),
340 MediaGalleryPrefInfo::kScanResult
,
341 base::ASCIIToUTF16("Updated & Selected"),
342 base::string16(), base::string16(), 0, base::Time(), 1, 0, 0);
343 EXPECT_EQ(6, dialog()->update_count());
344 EXPECT_EQ(4U, GetFirstSectionSize());
346 MediaGalleriesDialogController::Entries results
=
347 controller()->GetSectionEntries(0);
348 EXPECT_EQ(selected
, results
[0].pref_info
.pref_id
);
349 EXPECT_TRUE(results
[0].selected
);
350 EXPECT_EQ(selected_update
, results
[1].pref_info
.pref_id
);
351 EXPECT_TRUE(results
[1].selected
);
352 EXPECT_EQ(base::ASCIIToUTF16("Updated & Selected"),
353 results
[1].pref_info
.volume_label
);
354 EXPECT_EQ(unselected
, results
[2].pref_info
.pref_id
);
355 EXPECT_FALSE(results
[2].selected
);
356 EXPECT_EQ(unselected_update
, results
[3].pref_info
.pref_id
);
357 EXPECT_FALSE(results
[3].selected
);
358 EXPECT_EQ(base::ASCIIToUTF16("Updated & Unselected"),
359 results
[3].pref_info
.volume_label
);
361 controller()->DialogFinished(true);
362 EXPECT_EQ(4U, gallery_prefs()->GalleriesForExtension(*extension()).size());
364 EXPECT_EQ(2U, GetFirstSectionSize());
365 controller()->DialogFinished(false);
368 TEST_F(MediaGalleriesScanResultControllerTest
, ForgetGallery
) {
369 // Start with two scan results.
370 MediaGalleryPrefId scan1
= AddScanResult("scan1", 1, 0, 0);
371 MediaGalleryPrefId scan2
= AddScanResult("scan2", 2, 0, 0);
372 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
374 // Remove one and then cancel.
376 EXPECT_EQ(2U, GetFirstSectionSize());
377 controller()->DidForgetEntry(scan1
);
378 controller()->DialogFinished(false);
379 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
381 // Remove one and then have it blacklisted from prefs.
383 EXPECT_EQ(2U, GetFirstSectionSize());
384 controller()->DidForgetEntry(scan1
);
385 EXPECT_EQ(1, dialog()->update_count());
386 controller()->DidToggleEntry(scan2
, false); // Uncheck the second.
387 gallery_prefs()->ForgetGalleryById(scan1
);
388 controller()->DialogFinished(true);
389 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
390 EXPECT_EQ(2, dialog_update_count_at_destruction());
394 EXPECT_EQ(1U, GetFirstSectionSize());
395 controller()->DidForgetEntry(scan2
);
396 controller()->DialogFinished(true);
397 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
399 // Check that nothing shows up.
401 EXPECT_EQ(0U, GetFirstSectionSize());
402 controller()->DialogFinished(false);
405 TEST_F(MediaGalleriesScanResultControllerTest
, SortOrder
) {
406 // Intentionally out of order numerically and alphabetically.
407 MediaGalleryPrefId third
= AddScanResult("third", 2, 2, 2);
408 MediaGalleryPrefId second
=
409 AddGallery("second", MediaGalleryPrefInfo::kAutoDetected
, 9, 0, 0);
410 MediaGalleryPrefId first
= AddScanResult("first", 8, 2, 3);
411 MediaGalleryPrefId fifth
= AddScanResult("abb", 3, 0, 0);
412 MediaGalleryPrefId fourth
= AddScanResult("aaa", 3, 0, 0);
415 MediaGalleriesDialogController::Entries results
=
416 controller()->GetSectionEntries(0);
417 ASSERT_EQ(5U, results
.size());
418 EXPECT_EQ(first
, results
[0].pref_info
.pref_id
);
419 EXPECT_EQ(second
, results
[1].pref_info
.pref_id
);
420 EXPECT_EQ(third
, results
[2].pref_info
.pref_id
);
421 EXPECT_EQ(fourth
, results
[3].pref_info
.pref_id
);
422 EXPECT_EQ(fifth
, results
[4].pref_info
.pref_id
);
423 controller()->DialogFinished(false);