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 ~MediaGalleriesScanResultControllerTest() override
{
44 EXPECT_FALSE(controller_
);
45 EXPECT_FALSE(dialog_
);
48 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 base::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 void TearDown() override
{ storage_monitor::TestStorageMonitor::Destroy(); }
71 ASSERT_FALSE(controller_
);
72 controller_
= new MediaGalleriesScanResultController(
76 &MediaGalleriesScanResultControllerTest::CreateMockDialog
,
77 base::Unretained(this)),
79 &MediaGalleriesScanResultControllerTest::OnControllerDone
,
80 base::Unretained(this)));
83 size_t GetFirstSectionSize() const {
84 return controller()->GetSectionEntries(0).size();
87 MediaGalleriesScanResultController
* controller() const {
91 MockMediaGalleriesDialog
* dialog() {
95 int dialog_update_count_at_destruction() {
96 EXPECT_FALSE(dialog_
);
97 return dialog_update_count_at_destruction_
;
100 extensions::Extension
* extension() {
101 return extension_
.get();
104 MediaGalleriesPreferences
* gallery_prefs() {
105 return gallery_prefs_
.get();
108 MediaGalleryPrefId
AddGallery(const std::string
& path
,
109 MediaGalleryPrefInfo::Type type
,
110 int audio_count
, int image_count
,
112 MediaGalleryPrefInfo gallery_info
;
113 gallery_prefs_
->LookUpGalleryByPath(MakeMediaGalleriesTestingPath(path
),
115 return gallery_prefs_
->AddGallery(
116 gallery_info
.device_id
,
119 gallery_info
.volume_label
,
120 gallery_info
.vendor_name
,
121 gallery_info
.model_name
,
122 gallery_info
.total_size_in_bytes
,
123 gallery_info
.last_attach_time
,
124 audio_count
, image_count
, video_count
);
127 MediaGalleryPrefId
AddScanResult(const std::string
& path
, int audio_count
,
128 int image_count
, int video_count
) {
129 return AddGallery(path
, MediaGalleryPrefInfo::kScanResult
, audio_count
,
130 image_count
, video_count
);
134 MediaGalleriesDialog
* CreateMockDialog(
135 MediaGalleriesDialogController
* controller
) {
136 EXPECT_FALSE(dialog_
);
137 dialog_update_count_at_destruction_
= 0;
138 dialog_
= new MockMediaGalleriesDialog(base::Bind(
139 &MediaGalleriesScanResultControllerTest::OnDialogDestroyed
,
140 weak_factory_
.GetWeakPtr()));
144 void OnDialogDestroyed(int update_count
) {
145 EXPECT_TRUE(dialog_
);
146 dialog_update_count_at_destruction_
= update_count
;
150 void OnControllerDone() {
154 // Needed for extension service & friends to work.
155 content::TestBrowserThreadBundle thread_bundle_
;
157 // The dialog is owned by the controller, but this pointer should only be
158 // valid while the dialog is live within the controller.
159 MockMediaGalleriesDialog
* dialog_
;
160 int dialog_update_count_at_destruction_
;
162 // The controller owns itself.
163 MediaGalleriesScanResultController
* controller_
;
165 scoped_refptr
<extensions::Extension
> extension_
;
167 EnsureMediaDirectoriesExists mock_gallery_locations_
;
169 #if defined OS_CHROMEOS
170 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_
;
171 chromeos::ScopedTestCrosSettings test_cros_settings_
;
172 chromeos::ScopedTestUserManager test_user_manager_
;
175 storage_monitor::TestStorageMonitor monitor_
;
176 scoped_ptr
<TestingProfile
> profile_
;
177 scoped_ptr
<MediaGalleriesPreferences
> gallery_prefs_
;
179 base::WeakPtrFactory
<MediaGalleriesScanResultControllerTest
> weak_factory_
;
181 DISALLOW_COPY_AND_ASSIGN(MediaGalleriesScanResultControllerTest
);
184 TEST_F(MediaGalleriesScanResultControllerTest
, EmptyDialog
) {
186 EXPECT_TRUE(controller());
187 EXPECT_TRUE(dialog());
188 EXPECT_EQ(0U, GetFirstSectionSize());
190 controller()->DialogFinished(true);
191 EXPECT_FALSE(controller());
192 EXPECT_FALSE(dialog());
193 EXPECT_EQ(0, dialog_update_count_at_destruction());
196 TEST_F(MediaGalleriesScanResultControllerTest
, AddScanResults
) {
197 // Start with two scan results.
198 MediaGalleryPrefId scan_id
= AddScanResult("scan_id", 1, 0, 0);
199 MediaGalleryPrefId auto_id
=
200 AddGallery("auto_id", MediaGalleryPrefInfo::kAutoDetected
, 2, 0, 0);
201 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
203 // Show the dialog, but cancel it.
205 EXPECT_EQ(2U, GetFirstSectionSize());
206 controller()->DialogFinished(false);
207 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
209 // Show the dialog, unselect both and accept it.
211 EXPECT_EQ(2U, GetFirstSectionSize());
212 controller()->DidToggleEntry(scan_id
, false);
213 controller()->DidToggleEntry(auto_id
, false);
214 controller()->DialogFinished(true);
215 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
217 // Show the dialog, leave one selected and accept it.
219 EXPECT_EQ(2U, GetFirstSectionSize());
220 controller()->DidToggleEntry(scan_id
, false);
221 controller()->DialogFinished(true);
222 MediaGalleryPrefIdSet permitted
=
223 gallery_prefs()->GalleriesForExtension(*extension());
224 ASSERT_EQ(1U, permitted
.size());
225 EXPECT_EQ(auto_id
, *permitted
.begin());
227 // Show the dialog, toggle the remaining entry twice and then accept it.
229 EXPECT_EQ(1U, GetFirstSectionSize());
230 controller()->DidToggleEntry(scan_id
, false);
231 controller()->DidToggleEntry(scan_id
, true);
232 controller()->DialogFinished(true);
233 EXPECT_EQ(2U, gallery_prefs()->GalleriesForExtension(*extension()).size());
236 TEST_F(MediaGalleriesScanResultControllerTest
, Blacklisted
) {
237 // Start with two scan results.
238 MediaGalleryPrefId scan_id
= AddScanResult("scan_id", 1, 0, 0);
239 MediaGalleryPrefId auto_id
=
240 AddGallery("auto_id", MediaGalleryPrefInfo::kAutoDetected
, 2, 0, 0);
241 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
243 // Show the dialog, but cancel it.
245 EXPECT_EQ(2U, GetFirstSectionSize());
246 controller()->DialogFinished(false);
247 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
249 // Blacklist one and try again.
250 gallery_prefs()->ForgetGalleryById(scan_id
);
252 EXPECT_EQ(1U, GetFirstSectionSize());
253 controller()->DialogFinished(false);
255 // Adding it as a user gallery should change its type.
256 AddGallery("scan_id", MediaGalleryPrefInfo::kUserAdded
, 1, 0, 0);
258 EXPECT_EQ(2U, GetFirstSectionSize());
260 // Blacklisting the other while the dialog is open should remove it.
261 gallery_prefs()->ForgetGalleryById(auto_id
);
262 EXPECT_EQ(1U, GetFirstSectionSize());
263 controller()->DialogFinished(false);
264 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
265 EXPECT_EQ(1, dialog_update_count_at_destruction());
268 TEST_F(MediaGalleriesScanResultControllerTest
, PrefUpdates
) {
269 MediaGalleryPrefId selected
= AddScanResult("selected", 1, 0, 0);
270 MediaGalleryPrefId unselected
= AddScanResult("unselected", 1, 0, 0);
271 MediaGalleryPrefId selected_add_permission
=
272 AddScanResult("selected_add_permission", 1, 0, 0);
273 MediaGalleryPrefId unselected_add_permission
=
274 AddScanResult("unselected_add_permission", 1, 0, 0);
275 MediaGalleryPrefId selected_removed
=
276 AddScanResult("selected_removed", 1, 0, 0);
277 MediaGalleryPrefId unselected_removed
=
278 AddScanResult("unselected_removed", 1, 0, 0);
279 MediaGalleryPrefId selected_update
=
280 AddScanResult("selected_update", 1, 0, 0);
281 MediaGalleryPrefId unselected_update
=
282 AddScanResult("unselected_update", 1, 0, 0);
284 gallery_prefs()->AddGalleryByPath(MakeMediaGalleriesTestingPath("user"),
285 MediaGalleryPrefInfo::kUserAdded
);
286 gallery_prefs()->AddGalleryByPath(
287 MakeMediaGalleriesTestingPath("auto_detected"),
288 MediaGalleryPrefInfo::kAutoDetected
);
289 MediaGalleryPrefId blacklisted
= gallery_prefs()->AddGalleryByPath(
290 MakeMediaGalleriesTestingPath("blacklisted"),
291 MediaGalleryPrefInfo::kAutoDetected
);
292 gallery_prefs()->ForgetGalleryById(blacklisted
);
293 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
296 EXPECT_EQ(8U, GetFirstSectionSize());
297 controller()->DidToggleEntry(unselected
, false);
298 controller()->DidToggleEntry(unselected_add_permission
, false);
299 controller()->DidToggleEntry(unselected_removed
, false);
300 controller()->DidToggleEntry(unselected_update
, false);
301 EXPECT_EQ(0, dialog()->update_count());
302 EXPECT_EQ(8U, GetFirstSectionSize());
305 gallery_prefs()->SetGalleryPermissionForExtension(*extension(),
306 unselected_add_permission
,
308 EXPECT_EQ(1, dialog()->update_count());
309 EXPECT_EQ(7U, GetFirstSectionSize());
310 gallery_prefs()->SetGalleryPermissionForExtension(*extension(),
311 selected_add_permission
,
313 EXPECT_EQ(2, dialog()->update_count());
314 EXPECT_EQ(6U, GetFirstSectionSize());
316 // Blacklist scan results.
317 gallery_prefs()->ForgetGalleryById(unselected_removed
);
318 EXPECT_EQ(3, dialog()->update_count());
319 EXPECT_EQ(5U, GetFirstSectionSize());
320 gallery_prefs()->ForgetGalleryById(selected_removed
);
321 EXPECT_EQ(4, dialog()->update_count());
322 EXPECT_EQ(4U, GetFirstSectionSize());
325 const MediaGalleryPrefInfo
& unselected_update_info
=
326 gallery_prefs()->known_galleries().find(unselected_update
)->second
;
327 gallery_prefs()->AddGallery(
328 unselected_update_info
.device_id
, base::FilePath(),
329 MediaGalleryPrefInfo::kScanResult
,
330 base::ASCIIToUTF16("Updated & Unselected"),
331 base::string16(), base::string16(), 0, base::Time(), 1, 0, 0);
332 EXPECT_EQ(5, dialog()->update_count());
333 EXPECT_EQ(4U, GetFirstSectionSize());
334 const MediaGalleryPrefInfo
& selected_update_info
=
335 gallery_prefs()->known_galleries().find(selected_update
)->second
;
336 gallery_prefs()->AddGallery(
337 selected_update_info
.device_id
, base::FilePath(),
338 MediaGalleryPrefInfo::kScanResult
,
339 base::ASCIIToUTF16("Updated & Selected"),
340 base::string16(), base::string16(), 0, base::Time(), 1, 0, 0);
341 EXPECT_EQ(6, dialog()->update_count());
342 EXPECT_EQ(4U, GetFirstSectionSize());
344 MediaGalleriesDialogController::Entries results
=
345 controller()->GetSectionEntries(0);
346 EXPECT_EQ(selected
, results
[0].pref_info
.pref_id
);
347 EXPECT_TRUE(results
[0].selected
);
348 EXPECT_EQ(selected_update
, results
[1].pref_info
.pref_id
);
349 EXPECT_TRUE(results
[1].selected
);
350 EXPECT_EQ(base::ASCIIToUTF16("Updated & Selected"),
351 results
[1].pref_info
.volume_label
);
352 EXPECT_EQ(unselected
, results
[2].pref_info
.pref_id
);
353 EXPECT_FALSE(results
[2].selected
);
354 EXPECT_EQ(unselected_update
, results
[3].pref_info
.pref_id
);
355 EXPECT_FALSE(results
[3].selected
);
356 EXPECT_EQ(base::ASCIIToUTF16("Updated & Unselected"),
357 results
[3].pref_info
.volume_label
);
359 controller()->DialogFinished(true);
360 EXPECT_EQ(4U, gallery_prefs()->GalleriesForExtension(*extension()).size());
362 EXPECT_EQ(2U, GetFirstSectionSize());
363 controller()->DialogFinished(false);
366 TEST_F(MediaGalleriesScanResultControllerTest
, ForgetGallery
) {
367 // Start with two scan results.
368 MediaGalleryPrefId scan1
= AddScanResult("scan1", 1, 0, 0);
369 MediaGalleryPrefId scan2
= AddScanResult("scan2", 2, 0, 0);
370 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
372 // Remove one and then cancel.
374 EXPECT_EQ(2U, GetFirstSectionSize());
375 controller()->DidForgetEntry(scan1
);
376 controller()->DialogFinished(false);
377 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
379 // Remove one and then have it blacklisted from prefs.
381 EXPECT_EQ(2U, GetFirstSectionSize());
382 controller()->DidForgetEntry(scan1
);
383 EXPECT_EQ(1, dialog()->update_count());
384 controller()->DidToggleEntry(scan2
, false); // Uncheck the second.
385 gallery_prefs()->ForgetGalleryById(scan1
);
386 controller()->DialogFinished(true);
387 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
388 EXPECT_EQ(2, dialog_update_count_at_destruction());
392 EXPECT_EQ(1U, GetFirstSectionSize());
393 controller()->DidForgetEntry(scan2
);
394 controller()->DialogFinished(true);
395 EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
397 // Check that nothing shows up.
399 EXPECT_EQ(0U, GetFirstSectionSize());
400 controller()->DialogFinished(false);
403 TEST_F(MediaGalleriesScanResultControllerTest
, SortOrder
) {
404 // Intentionally out of order numerically and alphabetically.
405 MediaGalleryPrefId third
= AddScanResult("third", 2, 2, 2);
406 MediaGalleryPrefId second
=
407 AddGallery("second", MediaGalleryPrefInfo::kAutoDetected
, 9, 0, 0);
408 MediaGalleryPrefId first
= AddScanResult("first", 8, 2, 3);
409 MediaGalleryPrefId fifth
= AddScanResult("abb", 3, 0, 0);
410 MediaGalleryPrefId fourth
= AddScanResult("aaa", 3, 0, 0);
413 MediaGalleriesDialogController::Entries results
=
414 controller()->GetSectionEntries(0);
415 ASSERT_EQ(5U, results
.size());
416 EXPECT_EQ(first
, results
[0].pref_info
.pref_id
);
417 EXPECT_EQ(second
, results
[1].pref_info
.pref_id
);
418 EXPECT_EQ(third
, results
[2].pref_info
.pref_id
);
419 EXPECT_EQ(fourth
, results
[3].pref_info
.pref_id
);
420 EXPECT_EQ(fifth
, results
[4].pref_info
.pref_id
);
421 controller()->DialogFinished(false);