Home | History | Annotate | Download | only in media_galleries
      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.
      4 
      5 #include "base/bind.h"
      6 #include "base/command_line.h"
      7 #include "base/files/file_path.h"
      8 #include "base/run_loop.h"
      9 #include "base/strings/string16.h"
     10 #include "base/strings/string_util.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "chrome/browser/extensions/test_extension_system.h"
     13 #include "chrome/browser/media_galleries/media_galleries_dialog_controller_test_util.h"
     14 #include "chrome/browser/media_galleries/media_galleries_permission_controller.h"
     15 #include "chrome/browser/media_galleries/media_galleries_preferences.h"
     16 #include "chrome/browser/media_galleries/media_galleries_test_util.h"
     17 #include "chrome/test/base/testing_profile.h"
     18 #include "components/storage_monitor/storage_info.h"
     19 #include "components/storage_monitor/test_storage_monitor.h"
     20 #include "content/public/test/test_browser_thread_bundle.h"
     21 #include "extensions/common/permissions/media_galleries_permission.h"
     22 #include "testing/gtest/include/gtest/gtest.h"
     23 
     24 #if defined(OS_CHROMEOS)
     25 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
     26 #include "chrome/browser/chromeos/settings/cros_settings.h"
     27 #include "chrome/browser/chromeos/settings/device_settings_service.h"
     28 #endif
     29 
     30 using storage_monitor::StorageInfo;
     31 using storage_monitor::TestStorageMonitor;
     32 
     33 namespace {
     34 
     35 std::string GalleryName(const MediaGalleryPrefInfo& gallery) {
     36   base::string16 name = gallery.GetGalleryDisplayName();
     37   return base::UTF16ToASCII(name);
     38 }
     39 
     40 }  // namespace
     41 
     42 class MediaGalleriesPermissionControllerTest : public ::testing::Test {
     43  public:
     44   MediaGalleriesPermissionControllerTest()
     45       : dialog_(NULL),
     46         dialog_update_count_at_destruction_(0),
     47         controller_(NULL),
     48         profile_(new TestingProfile()),
     49         weak_factory_(this) {
     50   }
     51 
     52   virtual ~MediaGalleriesPermissionControllerTest() {
     53     EXPECT_FALSE(controller_);
     54     EXPECT_FALSE(dialog_);
     55   }
     56 
     57   virtual void SetUp() OVERRIDE {
     58     ASSERT_TRUE(TestStorageMonitor::CreateAndInstall());
     59 
     60     extensions::TestExtensionSystem* extension_system(
     61         static_cast<extensions::TestExtensionSystem*>(
     62             extensions::ExtensionSystem::Get(profile_.get())));
     63     extension_system->CreateExtensionService(
     64         CommandLine::ForCurrentProcess(), base::FilePath(), false);
     65 
     66     gallery_prefs_.reset(new MediaGalleriesPreferences(profile_.get()));
     67     base::RunLoop loop;
     68     gallery_prefs_->EnsureInitialized(loop.QuitClosure());
     69     loop.Run();
     70 
     71     std::vector<std::string> read_permissions;
     72     read_permissions.push_back(
     73         extensions::MediaGalleriesPermission::kReadPermission);
     74     extension_ = AddMediaGalleriesApp("read", read_permissions, profile_.get());
     75   }
     76 
     77   virtual void TearDown() OVERRIDE {
     78     TestStorageMonitor::Destroy();
     79   }
     80 
     81   void StartDialog() {
     82     ASSERT_FALSE(controller_);
     83     controller_ = new MediaGalleriesPermissionController(
     84         *extension_.get(),
     85         gallery_prefs_.get(),
     86         base::Bind(&MediaGalleriesPermissionControllerTest::CreateMockDialog,
     87                    base::Unretained(this)),
     88         base::Bind(
     89             &MediaGalleriesPermissionControllerTest::OnControllerDone,
     90             base::Unretained(this)));
     91   }
     92 
     93   MediaGalleriesPermissionController* controller() {
     94     return controller_;
     95   }
     96 
     97   MockMediaGalleriesDialog* dialog() {
     98     return dialog_;
     99   }
    100 
    101   int dialog_update_count_at_destruction() {
    102     EXPECT_FALSE(dialog_);
    103     return dialog_update_count_at_destruction_;
    104   }
    105 
    106   extensions::Extension* extension() {
    107     return extension_.get();
    108   }
    109 
    110   MediaGalleriesPreferences* gallery_prefs() {
    111     return gallery_prefs_.get();
    112   }
    113 
    114   GalleryDialogId GetDialogIdFromPrefId(MediaGalleryPrefId pref_id);
    115 
    116   void TestForgottenType(MediaGalleryPrefInfo::Type type,
    117                          bool forget_preserves_pref_id);
    118 
    119  protected:
    120   EnsureMediaDirectoriesExists mock_gallery_locations_;
    121 
    122  private:
    123   MediaGalleriesDialog* CreateMockDialog(
    124       MediaGalleriesDialogController* controller) {
    125     EXPECT_FALSE(dialog_);
    126     dialog_update_count_at_destruction_ = 0;
    127     dialog_ = new MockMediaGalleriesDialog(base::Bind(
    128         &MediaGalleriesPermissionControllerTest::OnDialogDestroyed,
    129         weak_factory_.GetWeakPtr()));
    130     return dialog_;
    131   }
    132 
    133   void OnDialogDestroyed(int update_count) {
    134     EXPECT_TRUE(dialog_);
    135     dialog_update_count_at_destruction_ = update_count;
    136     dialog_ = NULL;
    137   }
    138 
    139   void OnControllerDone() {
    140     controller_ = NULL;
    141   }
    142 
    143   // Needed for extension service & friends to work.
    144   content::TestBrowserThreadBundle thread_bundle_;
    145 
    146   // The dialog is owned by the controller, but this pointer should only be
    147   // valid while the dialog is live within the controller.
    148   MockMediaGalleriesDialog* dialog_;
    149   int dialog_update_count_at_destruction_;
    150 
    151   // The controller owns itself.
    152   MediaGalleriesPermissionController* controller_;
    153 
    154   scoped_refptr<extensions::Extension> extension_;
    155 
    156 #if defined OS_CHROMEOS
    157   chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
    158   chromeos::ScopedTestCrosSettings test_cros_settings_;
    159   chromeos::ScopedTestUserManager test_user_manager_;
    160 #endif
    161 
    162   TestStorageMonitor monitor_;
    163   scoped_ptr<TestingProfile> profile_;
    164   scoped_ptr<MediaGalleriesPreferences> gallery_prefs_;
    165 
    166   base::WeakPtrFactory<MediaGalleriesPermissionControllerTest>
    167       weak_factory_;
    168 
    169   DISALLOW_COPY_AND_ASSIGN(MediaGalleriesPermissionControllerTest);
    170 };
    171 
    172 GalleryDialogId
    173 MediaGalleriesPermissionControllerTest::GetDialogIdFromPrefId(
    174     MediaGalleryPrefId pref_id) {
    175   return controller_->GetDialogId(pref_id);
    176 }
    177 
    178 void MediaGalleriesPermissionControllerTest::TestForgottenType(
    179     MediaGalleryPrefInfo::Type type, bool forget_preserves_pref_id) {
    180   EXPECT_EQ(0U, gallery_prefs()->GalleriesForExtension(*extension()).size());
    181 
    182   MediaGalleryPrefId forgotten1 = gallery_prefs()->AddGalleryByPath(
    183       MakeMediaGalleriesTestingPath("forgotten1"), type);
    184   MediaGalleryPrefId forgotten2 = gallery_prefs()->AddGalleryByPath(
    185       MakeMediaGalleriesTestingPath("forgotten2"), type);
    186   // Show dialog and accept to verify 2 entries
    187   StartDialog();
    188   EXPECT_EQ(0U, controller()->GetSectionEntries(0).size());
    189   EXPECT_EQ(mock_gallery_locations_.num_galleries() + 2U,
    190             controller()->GetSectionEntries(1).size());
    191   controller()->DidToggleEntry(GetDialogIdFromPrefId(forgotten1), true);
    192   controller()->DidToggleEntry(GetDialogIdFromPrefId(forgotten2), true);
    193   controller()->DialogFinished(true);
    194   EXPECT_EQ(2U, gallery_prefs()->GalleriesForExtension(*extension()).size());
    195 
    196   // Forget one and cancel to see that it's still there.
    197   StartDialog();
    198   EXPECT_EQ(2U, controller()->GetSectionEntries(0).size());
    199   controller()->DidForgetEntry(GetDialogIdFromPrefId(forgotten1));
    200   EXPECT_EQ(1U, controller()->GetSectionEntries(0).size());
    201   controller()->DialogFinished(false);
    202   EXPECT_EQ(2U, gallery_prefs()->GalleriesForExtension(*extension()).size());
    203 
    204   // Forget one and confirm to see that it's gone.
    205   StartDialog();
    206   EXPECT_EQ(2U, controller()->GetSectionEntries(0).size());
    207   controller()->DidForgetEntry(GetDialogIdFromPrefId(forgotten1));
    208   EXPECT_EQ(1U, controller()->GetSectionEntries(0).size());
    209   controller()->DialogFinished(true);
    210   EXPECT_EQ(1U, gallery_prefs()->GalleriesForExtension(*extension()).size());
    211 
    212   // Add back and test whether the same pref id is preserved.
    213   StartDialog();
    214   controller()->FileSelected(
    215       MakeMediaGalleriesTestingPath("forgotten1"), 0, NULL);
    216   controller()->DialogFinished(true);
    217   EXPECT_EQ(2U, gallery_prefs()->GalleriesForExtension(*extension()).size());
    218   MediaGalleryPrefInfo retrieved_info;
    219   EXPECT_TRUE(gallery_prefs()->LookUpGalleryByPath(
    220       MakeMediaGalleriesTestingPath("forgotten1"), &retrieved_info));
    221   EXPECT_EQ(forget_preserves_pref_id, retrieved_info.pref_id == forgotten1);
    222 
    223   // Add a new one and forget it & see that it's gone.
    224   MediaGalleryPrefId forgotten3 = gallery_prefs()->AddGalleryByPath(
    225       MakeMediaGalleriesTestingPath("forgotten3"), type);
    226   StartDialog();
    227   EXPECT_EQ(2U, controller()->GetSectionEntries(0).size());
    228   EXPECT_EQ(mock_gallery_locations_.num_galleries() + 1U,
    229             controller()->GetSectionEntries(1).size());
    230   controller()->DidToggleEntry(GetDialogIdFromPrefId(forgotten3), true);
    231   controller()->DidForgetEntry(GetDialogIdFromPrefId(forgotten3));
    232   EXPECT_EQ(2U, controller()->GetSectionEntries(0).size());
    233   EXPECT_EQ(static_cast<unsigned long>(mock_gallery_locations_.num_galleries()),
    234             controller()->GetSectionEntries(1).size());
    235   controller()->DialogFinished(true);
    236   EXPECT_EQ(2U, gallery_prefs()->GalleriesForExtension(*extension()).size());
    237 }
    238 
    239 TEST_F(MediaGalleriesPermissionControllerTest, TestForgottenUserAdded) {
    240   TestForgottenType(MediaGalleryPrefInfo::kUserAdded,
    241                     false /* forget_preserves_pref_id */);
    242 }
    243 
    244 TEST_F(MediaGalleriesPermissionControllerTest, TestForgottenAutoDetected) {
    245   TestForgottenType(MediaGalleryPrefInfo::kAutoDetected,
    246                     true /* forget_preserves_pref_id */);
    247 }
    248 
    249 TEST_F(MediaGalleriesPermissionControllerTest, TestForgottenScanResult) {
    250   TestForgottenType(MediaGalleryPrefInfo::kScanResult,
    251                     true /* forget_preserves_pref_id */);
    252 }
    253 
    254 TEST_F(MediaGalleriesPermissionControllerTest, TestNameGeneration) {
    255   MediaGalleryPrefInfo gallery;
    256   gallery.pref_id = 1;
    257   gallery.device_id = StorageInfo::MakeDeviceId(
    258       StorageInfo::FIXED_MASS_STORAGE, "/path/to/gallery");
    259   gallery.type = MediaGalleryPrefInfo::kAutoDetected;
    260   std::string galleryName("/path/to/gallery");
    261 #if defined(OS_CHROMEOS)
    262   galleryName = "gallery";
    263 #endif
    264   EXPECT_EQ(galleryName, GalleryName(gallery));
    265 
    266   gallery.display_name = base::ASCIIToUTF16("override");
    267   EXPECT_EQ("override", GalleryName(gallery));
    268 
    269   gallery.display_name = base::string16();
    270   gallery.volume_label = base::ASCIIToUTF16("label");
    271   EXPECT_EQ(galleryName, GalleryName(gallery));
    272 
    273   gallery.path = base::FilePath(FILE_PATH_LITERAL("sub/gallery2"));
    274   galleryName = "/path/to/gallery/sub/gallery2";
    275 #if defined(OS_CHROMEOS)
    276   galleryName = "gallery2";
    277 #endif
    278 #if defined(OS_WIN)
    279   galleryName = base::FilePath(FILE_PATH_LITERAL("/path/to/gallery"))
    280                     .Append(gallery.path).MaybeAsASCII();
    281 #endif
    282   EXPECT_EQ(galleryName, GalleryName(gallery));
    283 
    284   gallery.path = base::FilePath();
    285   gallery.device_id = StorageInfo::MakeDeviceId(
    286       StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM,
    287       "/path/to/dcim");
    288   gallery.display_name = base::ASCIIToUTF16("override");
    289   EXPECT_EQ("override", GalleryName(gallery));
    290 
    291   gallery.volume_label = base::ASCIIToUTF16("volume");
    292   gallery.vendor_name = base::ASCIIToUTF16("vendor");
    293   gallery.model_name = base::ASCIIToUTF16("model");
    294   EXPECT_EQ("override", GalleryName(gallery));
    295 
    296   gallery.display_name = base::string16();
    297   EXPECT_EQ("volume", GalleryName(gallery));
    298 
    299   gallery.volume_label = base::string16();
    300   EXPECT_EQ("vendor, model", GalleryName(gallery));
    301 
    302   gallery.total_size_in_bytes = 1000000;
    303   EXPECT_EQ("977 KB vendor, model", GalleryName(gallery));
    304 
    305   gallery.path = base::FilePath(FILE_PATH_LITERAL("sub/path"));
    306   EXPECT_EQ("path - 977 KB vendor, model", GalleryName(gallery));
    307 }
    308