Home | History | Annotate | Download | only in file_manager
      1 // Copyright (c) 2013 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 // Browser test for basic Chrome OS file manager functionality:
      6 //  - The file list is updated when a file is added externally to the Downloads
      7 //    folder.
      8 //  - Selecting a file and copy-pasting it with the keyboard copies the file.
      9 //  - Selecting a file and pressing delete deletes it.
     10 
     11 #include <deque>
     12 #include <string>
     13 
     14 #include "base/bind.h"
     15 #include "base/files/file_path.h"
     16 #include "base/files/file_util.h"
     17 #include "base/json/json_reader.h"
     18 #include "base/json/json_value_converter.h"
     19 #include "base/json/json_writer.h"
     20 #include "base/prefs/pref_service.h"
     21 #include "base/strings/string_piece.h"
     22 #include "base/strings/utf_string_conversions.h"
     23 #include "base/time/time.h"
     24 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
     25 #include "chrome/browser/chromeos/drive/file_system_interface.h"
     26 #include "chrome/browser/chromeos/file_manager/app_id.h"
     27 #include "chrome/browser/chromeos/file_manager/drive_test_util.h"
     28 #include "chrome/browser/chromeos/file_manager/path_util.h"
     29 #include "chrome/browser/chromeos/file_manager/volume_manager.h"
     30 #include "chrome/browser/chromeos/profiles/profile_helper.h"
     31 #include "chrome/browser/drive/fake_drive_service.h"
     32 #include "chrome/browser/extensions/component_loader.h"
     33 #include "chrome/browser/extensions/extension_apitest.h"
     34 #include "chrome/browser/profiles/profile.h"
     35 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
     36 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
     37 #include "chrome/common/chrome_switches.h"
     38 #include "chrome/common/pref_names.h"
     39 #include "chromeos/chromeos_switches.h"
     40 #include "components/user_manager/user_manager.h"
     41 #include "content/public/browser/notification_service.h"
     42 #include "content/public/test/test_utils.h"
     43 #include "extensions/browser/api/test/test_api.h"
     44 #include "extensions/browser/app_window/app_window.h"
     45 #include "extensions/browser/app_window/app_window_registry.h"
     46 #include "extensions/browser/notification_types.h"
     47 #include "extensions/common/extension.h"
     48 #include "extensions/test/extension_test_message_listener.h"
     49 #include "google_apis/drive/drive_api_parser.h"
     50 #include "google_apis/drive/test_util.h"
     51 #include "net/test/embedded_test_server/embedded_test_server.h"
     52 #include "storage/browser/fileapi/external_mount_points.h"
     53 
     54 using drive::DriveIntegrationServiceFactory;
     55 
     56 namespace file_manager {
     57 namespace {
     58 
     59 enum EntryType {
     60   FILE,
     61   DIRECTORY,
     62 };
     63 
     64 enum TargetVolume { LOCAL_VOLUME, DRIVE_VOLUME, USB_VOLUME, };
     65 
     66 enum SharedOption {
     67   NONE,
     68   SHARED,
     69 };
     70 
     71 enum GuestMode {
     72   NOT_IN_GUEST_MODE,
     73   IN_GUEST_MODE,
     74   IN_INCOGNITO
     75 };
     76 
     77 // This global operator is used from Google Test to format error messages.
     78 std::ostream& operator<<(std::ostream& os, const GuestMode& guest_mode) {
     79   return os << (guest_mode == IN_GUEST_MODE ?
     80                 "IN_GUEST_MODE" : "NOT_IN_GUEST_MODE");
     81 }
     82 
     83 // Maps the given string to EntryType. Returns true on success.
     84 bool MapStringToEntryType(const base::StringPiece& value, EntryType* output) {
     85   if (value == "file")
     86     *output = FILE;
     87   else if (value == "directory")
     88     *output = DIRECTORY;
     89   else
     90     return false;
     91   return true;
     92 }
     93 
     94 // Maps the given string to SharedOption. Returns true on success.
     95 bool MapStringToSharedOption(const base::StringPiece& value,
     96                              SharedOption* output) {
     97   if (value == "shared")
     98     *output = SHARED;
     99   else if (value == "none")
    100     *output = NONE;
    101   else
    102     return false;
    103   return true;
    104 }
    105 
    106 // Maps the given string to TargetVolume. Returns true on success.
    107 bool MapStringToTargetVolume(const base::StringPiece& value,
    108                              TargetVolume* output) {
    109   if (value == "drive")
    110     *output = DRIVE_VOLUME;
    111   else if (value == "local")
    112     *output = LOCAL_VOLUME;
    113   else if (value == "usb")
    114     *output = USB_VOLUME;
    115   else
    116     return false;
    117   return true;
    118 }
    119 
    120 // Maps the given string to base::Time. Returns true on success.
    121 bool MapStringToTime(const base::StringPiece& value, base::Time* time) {
    122   return base::Time::FromString(value.as_string().c_str(), time);
    123 }
    124 
    125 // Test data of file or directory.
    126 struct TestEntryInfo {
    127   TestEntryInfo() : type(FILE), shared_option(NONE) {}
    128 
    129   TestEntryInfo(EntryType type,
    130                 const std::string& source_file_name,
    131                 const std::string& target_path,
    132                 const std::string& mime_type,
    133                 SharedOption shared_option,
    134                 const base::Time& last_modified_time) :
    135       type(type),
    136       source_file_name(source_file_name),
    137       target_path(target_path),
    138       mime_type(mime_type),
    139       shared_option(shared_option),
    140       last_modified_time(last_modified_time) {
    141   }
    142 
    143   EntryType type;
    144   std::string source_file_name;  // Source file name to be used as a prototype.
    145   std::string target_path;  // Target file or directory path.
    146   std::string mime_type;
    147   SharedOption shared_option;
    148   base::Time last_modified_time;
    149 
    150   // Registers the member information to the given converter.
    151   static void RegisterJSONConverter(
    152       base::JSONValueConverter<TestEntryInfo>* converter);
    153 };
    154 
    155 // static
    156 void TestEntryInfo::RegisterJSONConverter(
    157     base::JSONValueConverter<TestEntryInfo>* converter) {
    158   converter->RegisterCustomField("type",
    159                                  &TestEntryInfo::type,
    160                                  &MapStringToEntryType);
    161   converter->RegisterStringField("sourceFileName",
    162                                  &TestEntryInfo::source_file_name);
    163   converter->RegisterStringField("targetPath", &TestEntryInfo::target_path);
    164   converter->RegisterStringField("mimeType", &TestEntryInfo::mime_type);
    165   converter->RegisterCustomField("sharedOption",
    166                                  &TestEntryInfo::shared_option,
    167                                  &MapStringToSharedOption);
    168   converter->RegisterCustomField("lastModifiedTime",
    169                                  &TestEntryInfo::last_modified_time,
    170                                  &MapStringToTime);
    171 }
    172 
    173 // Message from JavaScript to add entries.
    174 struct AddEntriesMessage {
    175   // Target volume to be added the |entries|.
    176   TargetVolume volume;
    177 
    178   // Entries to be added.
    179   ScopedVector<TestEntryInfo> entries;
    180 
    181   // Registers the member information to the given converter.
    182   static void RegisterJSONConverter(
    183       base::JSONValueConverter<AddEntriesMessage>* converter);
    184 };
    185 
    186 // static
    187 void AddEntriesMessage::RegisterJSONConverter(
    188     base::JSONValueConverter<AddEntriesMessage>* converter) {
    189   converter->RegisterCustomField("volume",
    190                                  &AddEntriesMessage::volume,
    191                                  &MapStringToTargetVolume);
    192   converter->RegisterRepeatedMessage<TestEntryInfo>(
    193       "entries",
    194       &AddEntriesMessage::entries);
    195 }
    196 
    197 // Test volume.
    198 class TestVolume {
    199  protected:
    200   explicit TestVolume(const std::string& name) : name_(name) {}
    201   virtual ~TestVolume() {}
    202 
    203   bool CreateRootDirectory(const Profile* profile) {
    204     const base::FilePath path = profile->GetPath().Append(name_);
    205     return root_.path() == path || root_.Set(path);
    206   }
    207 
    208   const std::string& name() { return name_; }
    209   const base::FilePath root_path() { return root_.path(); }
    210 
    211  private:
    212   std::string name_;
    213   base::ScopedTempDir root_;
    214 };
    215 
    216 // The local volume class for test.
    217 // This class provides the operations for a test volume that simulates local
    218 // drive.
    219 class LocalTestVolume : public TestVolume {
    220  public:
    221   explicit LocalTestVolume(const std::string& name) : TestVolume(name) {}
    222   virtual ~LocalTestVolume() {}
    223 
    224   // Adds this volume to the file system as a local volume. Returns true on
    225   // success.
    226   virtual bool Mount(Profile* profile) = 0;
    227 
    228   void CreateEntry(const TestEntryInfo& entry) {
    229     const base::FilePath target_path =
    230         root_path().AppendASCII(entry.target_path);
    231 
    232     entries_.insert(std::make_pair(target_path, entry));
    233     switch (entry.type) {
    234       case FILE: {
    235         const base::FilePath source_path =
    236             google_apis::test_util::GetTestFilePath("chromeos/file_manager").
    237             AppendASCII(entry.source_file_name);
    238         ASSERT_TRUE(base::CopyFile(source_path, target_path))
    239             << "Copy from " << source_path.value()
    240             << " to " << target_path.value() << " failed.";
    241         break;
    242       }
    243       case DIRECTORY:
    244         ASSERT_TRUE(base::CreateDirectory(target_path)) <<
    245             "Failed to create a directory: " << target_path.value();
    246         break;
    247     }
    248     ASSERT_TRUE(UpdateModifiedTime(entry));
    249   }
    250 
    251  private:
    252   // Updates ModifiedTime of the entry and its parents by referring
    253   // TestEntryInfo. Returns true on success.
    254   bool UpdateModifiedTime(const TestEntryInfo& entry) {
    255     const base::FilePath path = root_path().AppendASCII(entry.target_path);
    256     if (!base::TouchFile(path, entry.last_modified_time,
    257                          entry.last_modified_time))
    258       return false;
    259 
    260     // Update the modified time of parent directories because it may be also
    261     // affected by the update of child items.
    262     if (path.DirName() != root_path()) {
    263       const std::map<base::FilePath, const TestEntryInfo>::iterator it =
    264           entries_.find(path.DirName());
    265       if (it == entries_.end())
    266         return false;
    267       return UpdateModifiedTime(it->second);
    268     }
    269     return true;
    270   }
    271 
    272   std::map<base::FilePath, const TestEntryInfo> entries_;
    273 };
    274 
    275 class DownloadsTestVolume : public LocalTestVolume {
    276  public:
    277   DownloadsTestVolume() : LocalTestVolume("Downloads") {}
    278   virtual ~DownloadsTestVolume() {}
    279 
    280   virtual bool Mount(Profile* profile) OVERRIDE {
    281     return CreateRootDirectory(profile) &&
    282            VolumeManager::Get(profile)
    283                ->RegisterDownloadsDirectoryForTesting(root_path());
    284   }
    285 };
    286 
    287 // Test volume for mimicing a specified type of volumes by a local folder.
    288 class FakeTestVolume : public LocalTestVolume {
    289  public:
    290   FakeTestVolume(const std::string& name,
    291                  VolumeType volume_type,
    292                  chromeos::DeviceType device_type)
    293       : LocalTestVolume(name),
    294         volume_type_(volume_type),
    295         device_type_(device_type) {}
    296   virtual ~FakeTestVolume() {}
    297 
    298   // Simple test entries used for testing, e.g., read-only volumes.
    299   bool PrepareTestEntries(Profile* profile) {
    300     if (!CreateRootDirectory(profile))
    301       return false;
    302     // Must be in sync with BASIC_FAKE_ENTRY_SET in the JS test code.
    303     CreateEntry(
    304         TestEntryInfo(FILE, "text.txt", "hello.txt", "text/plain", NONE,
    305                       base::Time::Now()));
    306     CreateEntry(
    307         TestEntryInfo(DIRECTORY, std::string(), "A", std::string(), NONE,
    308                       base::Time::Now()));
    309     return true;
    310   }
    311 
    312   virtual bool Mount(Profile* profile) OVERRIDE {
    313     if (!CreateRootDirectory(profile))
    314       return false;
    315     storage::ExternalMountPoints* const mount_points =
    316         storage::ExternalMountPoints::GetSystemInstance();
    317 
    318     // First revoke the existing mount point (if any).
    319     mount_points->RevokeFileSystem(name());
    320     const bool result =
    321         mount_points->RegisterFileSystem(name(),
    322                                          storage::kFileSystemTypeNativeLocal,
    323                                          storage::FileSystemMountOption(),
    324                                          root_path());
    325     if (!result)
    326       return false;
    327 
    328     VolumeManager::Get(profile)->AddVolumeInfoForTesting(
    329         root_path(), volume_type_, device_type_);
    330     return true;
    331   }
    332 
    333  private:
    334   const VolumeType volume_type_;
    335   const chromeos::DeviceType device_type_;
    336 };
    337 
    338 // The drive volume class for test.
    339 // This class provides the operations for a test volume that simulates Google
    340 // drive.
    341 class DriveTestVolume : public TestVolume {
    342  public:
    343   DriveTestVolume() : TestVolume("drive"), integration_service_(NULL) {}
    344   virtual ~DriveTestVolume() {}
    345 
    346   void CreateEntry(const TestEntryInfo& entry) {
    347     const base::FilePath path =
    348         base::FilePath::FromUTF8Unsafe(entry.target_path);
    349     const std::string target_name = path.BaseName().AsUTF8Unsafe();
    350 
    351     // Obtain the parent entry.
    352     drive::FileError error = drive::FILE_ERROR_OK;
    353     scoped_ptr<drive::ResourceEntry> parent_entry(new drive::ResourceEntry);
    354     integration_service_->file_system()->GetResourceEntry(
    355         drive::util::GetDriveMyDriveRootPath().Append(path).DirName(),
    356         google_apis::test_util::CreateCopyResultCallback(
    357             &error, &parent_entry));
    358     content::RunAllBlockingPoolTasksUntilIdle();
    359     ASSERT_EQ(drive::FILE_ERROR_OK, error);
    360     ASSERT_TRUE(parent_entry);
    361 
    362     switch (entry.type) {
    363       case FILE:
    364         CreateFile(entry.source_file_name,
    365                    parent_entry->resource_id(),
    366                    target_name,
    367                    entry.mime_type,
    368                    entry.shared_option == SHARED,
    369                    entry.last_modified_time);
    370         break;
    371       case DIRECTORY:
    372         CreateDirectory(
    373             parent_entry->resource_id(), target_name, entry.last_modified_time);
    374         break;
    375     }
    376   }
    377 
    378   // Creates an empty directory with the given |name| and |modification_time|.
    379   void CreateDirectory(const std::string& parent_id,
    380                        const std::string& target_name,
    381                        const base::Time& modification_time) {
    382     google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    383     scoped_ptr<google_apis::FileResource> entry;
    384     fake_drive_service_->AddNewDirectory(
    385         parent_id,
    386         target_name,
    387         drive::DriveServiceInterface::AddNewDirectoryOptions(),
    388         google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    389     base::MessageLoop::current()->RunUntilIdle();
    390     ASSERT_EQ(google_apis::HTTP_CREATED, error);
    391     ASSERT_TRUE(entry);
    392 
    393     fake_drive_service_->SetLastModifiedTime(
    394         entry->file_id(),
    395         modification_time,
    396         google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    397     base::MessageLoop::current()->RunUntilIdle();
    398     ASSERT_TRUE(error == google_apis::HTTP_SUCCESS);
    399     ASSERT_TRUE(entry);
    400     CheckForUpdates();
    401   }
    402 
    403   // Creates a test file with the given spec.
    404   // Serves |test_file_name| file. Pass an empty string for an empty file.
    405   void CreateFile(const std::string& source_file_name,
    406                   const std::string& parent_id,
    407                   const std::string& target_name,
    408                   const std::string& mime_type,
    409                   bool shared_with_me,
    410                   const base::Time& modification_time) {
    411     google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    412 
    413     std::string content_data;
    414     if (!source_file_name.empty()) {
    415       base::FilePath source_file_path =
    416           google_apis::test_util::GetTestFilePath("chromeos/file_manager").
    417               AppendASCII(source_file_name);
    418       ASSERT_TRUE(base::ReadFileToString(source_file_path, &content_data));
    419     }
    420 
    421     scoped_ptr<google_apis::FileResource> entry;
    422     fake_drive_service_->AddNewFile(
    423         mime_type,
    424         content_data,
    425         parent_id,
    426         target_name,
    427         shared_with_me,
    428         google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    429     base::MessageLoop::current()->RunUntilIdle();
    430     ASSERT_EQ(google_apis::HTTP_CREATED, error);
    431     ASSERT_TRUE(entry);
    432 
    433     fake_drive_service_->SetLastModifiedTime(
    434         entry->file_id(),
    435         modification_time,
    436         google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    437     base::MessageLoop::current()->RunUntilIdle();
    438     ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
    439     ASSERT_TRUE(entry);
    440 
    441     CheckForUpdates();
    442   }
    443 
    444   // Notifies FileSystem that the contents in FakeDriveService are
    445   // changed, hence the new contents should be fetched.
    446   void CheckForUpdates() {
    447     if (integration_service_ && integration_service_->file_system()) {
    448       integration_service_->file_system()->CheckForUpdates();
    449     }
    450   }
    451 
    452   // Sets the url base for the test server to be used to generate share urls
    453   // on the files and directories.
    454   void ConfigureShareUrlBase(const GURL& share_url_base) {
    455     fake_drive_service_->set_share_url_base(share_url_base);
    456   }
    457 
    458   drive::DriveIntegrationService* CreateDriveIntegrationService(
    459       Profile* profile) {
    460     profile_ = profile;
    461     fake_drive_service_ = new drive::FakeDriveService;
    462     fake_drive_service_->LoadAppListForDriveApi("drive/applist.json");
    463 
    464     if (!CreateRootDirectory(profile))
    465       return NULL;
    466     integration_service_ = new drive::DriveIntegrationService(
    467         profile, NULL, fake_drive_service_, std::string(), root_path(), NULL);
    468     return integration_service_;
    469   }
    470 
    471  private:
    472   Profile* profile_;
    473   drive::FakeDriveService* fake_drive_service_;
    474   drive::DriveIntegrationService* integration_service_;
    475 };
    476 
    477 // Listener to obtain the test relative messages synchronously.
    478 class FileManagerTestListener : public content::NotificationObserver {
    479  public:
    480   struct Message {
    481     int type;
    482     std::string message;
    483     scoped_refptr<extensions::TestSendMessageFunction> function;
    484   };
    485 
    486   FileManagerTestListener() {
    487     registrar_.Add(this,
    488                    extensions::NOTIFICATION_EXTENSION_TEST_PASSED,
    489                    content::NotificationService::AllSources());
    490     registrar_.Add(this,
    491                    extensions::NOTIFICATION_EXTENSION_TEST_FAILED,
    492                    content::NotificationService::AllSources());
    493     registrar_.Add(this,
    494                    extensions::NOTIFICATION_EXTENSION_TEST_MESSAGE,
    495                    content::NotificationService::AllSources());
    496   }
    497 
    498   Message GetNextMessage() {
    499     if (messages_.empty())
    500       content::RunMessageLoop();
    501     const Message entry = messages_.front();
    502     messages_.pop_front();
    503     return entry;
    504   }
    505 
    506   virtual void Observe(int type,
    507                        const content::NotificationSource& source,
    508                        const content::NotificationDetails& details) OVERRIDE {
    509     Message entry;
    510     entry.type = type;
    511     entry.message = type != extensions::NOTIFICATION_EXTENSION_TEST_PASSED
    512                         ? *content::Details<std::string>(details).ptr()
    513                         : std::string();
    514     entry.function =
    515         type == extensions::NOTIFICATION_EXTENSION_TEST_MESSAGE
    516             ? content::Source<extensions::TestSendMessageFunction>(source).ptr()
    517             : NULL;
    518     messages_.push_back(entry);
    519     base::MessageLoopForUI::current()->Quit();
    520   }
    521 
    522  private:
    523   std::deque<Message> messages_;
    524   content::NotificationRegistrar registrar_;
    525 };
    526 
    527 // The base test class.
    528 class FileManagerBrowserTestBase : public ExtensionApiTest {
    529  protected:
    530   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE;
    531 
    532   virtual void SetUpOnMainThread() OVERRIDE;
    533 
    534   // Adds an incognito and guest-mode flags for tests in the guest mode.
    535   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE;
    536 
    537   // Loads our testing extension and sends it a string identifying the current
    538   // test.
    539   virtual void StartTest();
    540   void RunTestMessageLoop();
    541 
    542   // Overriding point for test configurations.
    543   virtual const char* GetTestManifestName() const {
    544     return "file_manager_test_manifest.json";
    545   }
    546   virtual GuestMode GetGuestModeParam() const = 0;
    547   virtual const char* GetTestCaseNameParam() const = 0;
    548   virtual std::string OnMessage(const std::string& name,
    549                                 const base::Value* value);
    550 
    551   scoped_ptr<LocalTestVolume> local_volume_;
    552   linked_ptr<DriveTestVolume> drive_volume_;
    553   std::map<Profile*, linked_ptr<DriveTestVolume> > drive_volumes_;
    554   scoped_ptr<FakeTestVolume> usb_volume_;
    555   scoped_ptr<FakeTestVolume> mtp_volume_;
    556 
    557  private:
    558   drive::DriveIntegrationService* CreateDriveIntegrationService(
    559       Profile* profile);
    560   DriveIntegrationServiceFactory::FactoryCallback
    561       create_drive_integration_service_;
    562   scoped_ptr<DriveIntegrationServiceFactory::ScopedFactoryForTest>
    563       service_factory_for_test_;
    564 };
    565 
    566 void FileManagerBrowserTestBase::SetUpInProcessBrowserTestFixture() {
    567   ExtensionApiTest::SetUpInProcessBrowserTestFixture();
    568   extensions::ComponentLoader::EnableBackgroundExtensionsForTesting();
    569 
    570   local_volume_.reset(new DownloadsTestVolume);
    571   if (GetGuestModeParam() != IN_GUEST_MODE) {
    572     create_drive_integration_service_ =
    573         base::Bind(&FileManagerBrowserTestBase::CreateDriveIntegrationService,
    574                    base::Unretained(this));
    575     service_factory_for_test_.reset(
    576         new DriveIntegrationServiceFactory::ScopedFactoryForTest(
    577             &create_drive_integration_service_));
    578   }
    579 }
    580 
    581 void FileManagerBrowserTestBase::SetUpOnMainThread() {
    582   ExtensionApiTest::SetUpOnMainThread();
    583   ASSERT_TRUE(local_volume_->Mount(profile()));
    584 
    585   if (GetGuestModeParam() != IN_GUEST_MODE) {
    586     // Install the web server to serve the mocked share dialog.
    587     ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    588     const GURL share_url_base(embedded_test_server()->GetURL(
    589         "/chromeos/file_manager/share_dialog_mock/index.html"));
    590     drive_volume_ = drive_volumes_[profile()->GetOriginalProfile()];
    591     drive_volume_->ConfigureShareUrlBase(share_url_base);
    592     test_util::WaitUntilDriveMountPointIsAdded(profile());
    593   }
    594 }
    595 
    596 void FileManagerBrowserTestBase::SetUpCommandLine(CommandLine* command_line) {
    597   if (GetGuestModeParam() == IN_GUEST_MODE) {
    598     command_line->AppendSwitch(chromeos::switches::kGuestSession);
    599     command_line->AppendSwitchNative(chromeos::switches::kLoginUser, "");
    600     command_line->AppendSwitch(switches::kIncognito);
    601   }
    602   if (GetGuestModeParam() == IN_INCOGNITO) {
    603     command_line->AppendSwitch(switches::kIncognito);
    604   }
    605   ExtensionApiTest::SetUpCommandLine(command_line);
    606 }
    607 
    608 void FileManagerBrowserTestBase::StartTest() {
    609   // Launch the extension.
    610   const base::FilePath path =
    611       test_data_dir_.AppendASCII("file_manager_browsertest");
    612   const extensions::Extension* const extension =
    613       LoadExtensionAsComponentWithManifest(path, GetTestManifestName());
    614   ASSERT_TRUE(extension);
    615 
    616   RunTestMessageLoop();
    617 }
    618 
    619 void FileManagerBrowserTestBase::RunTestMessageLoop() {
    620   // Handle the messages from JavaScript.
    621   // The while loop is break when the test is passed or failed.
    622   FileManagerTestListener listener;
    623   while (true) {
    624     FileManagerTestListener::Message entry = listener.GetNextMessage();
    625     if (entry.type == extensions::NOTIFICATION_EXTENSION_TEST_PASSED) {
    626       // Test succeed.
    627       break;
    628     } else if (entry.type == extensions::NOTIFICATION_EXTENSION_TEST_FAILED) {
    629       // Test failed.
    630       ADD_FAILURE() << entry.message;
    631       break;
    632     }
    633 
    634     // Parse the message value as JSON.
    635     const scoped_ptr<const base::Value> value(
    636         base::JSONReader::Read(entry.message));
    637 
    638     // If the message is not the expected format, just ignore it.
    639     const base::DictionaryValue* message_dictionary = NULL;
    640     std::string name;
    641     if (!value || !value->GetAsDictionary(&message_dictionary) ||
    642         !message_dictionary->GetString("name", &name))
    643       continue;
    644 
    645     entry.function->Reply(OnMessage(name, value.get()));
    646   }
    647 }
    648 
    649 std::string FileManagerBrowserTestBase::OnMessage(const std::string& name,
    650                                                   const base::Value* value) {
    651   if (name == "getTestName") {
    652     // Pass the test case name.
    653     return GetTestCaseNameParam();
    654   } else if (name == "getRootPaths") {
    655     // Pass the root paths.
    656     const scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue());
    657     res->SetString("downloads",
    658         "/" + util::GetDownloadsMountPointName(profile()));
    659     res->SetString("drive",
    660         "/" + drive::util::GetDriveMountPointPath(profile()
    661             ).BaseName().AsUTF8Unsafe() + "/root");
    662     std::string jsonString;
    663     base::JSONWriter::Write(res.get(), &jsonString);
    664     return jsonString;
    665   } else if (name == "isInGuestMode") {
    666     // Obtain whether the test is in guest mode or not.
    667     return GetGuestModeParam() != NOT_IN_GUEST_MODE ? "true" : "false";
    668   } else if (name == "getCwsWidgetContainerMockUrl") {
    669     // Obtain whether the test is in guest mode or not.
    670     const GURL url = embedded_test_server()->GetURL(
    671           "/chromeos/file_manager/cws_container_mock/index.html");
    672     std::string origin = url.GetOrigin().spec();
    673 
    674     // Removes trailing a slash.
    675     if (*origin.rbegin() == '/')
    676       origin.resize(origin.length() - 1);
    677 
    678     const scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue());
    679     res->SetString("url", url.spec());
    680     res->SetString("origin", origin);
    681     std::string jsonString;
    682     base::JSONWriter::Write(res.get(), &jsonString);
    683     return jsonString;
    684   } else if (name == "addEntries") {
    685     // Add entries to the specified volume.
    686     base::JSONValueConverter<AddEntriesMessage> add_entries_message_converter;
    687     AddEntriesMessage message;
    688     if (!add_entries_message_converter.Convert(*value, &message))
    689       return "onError";
    690     for (size_t i = 0; i < message.entries.size(); ++i) {
    691       switch (message.volume) {
    692         case LOCAL_VOLUME:
    693           local_volume_->CreateEntry(*message.entries[i]);
    694           break;
    695         case DRIVE_VOLUME:
    696           if (drive_volume_.get())
    697             drive_volume_->CreateEntry(*message.entries[i]);
    698           break;
    699         case USB_VOLUME:
    700           if (usb_volume_)
    701             usb_volume_->CreateEntry(*message.entries[i]);
    702           break;
    703         default:
    704           NOTREACHED();
    705           break;
    706       }
    707     }
    708     return "onEntryAdded";
    709   } else if (name == "mountFakeUsb") {
    710     usb_volume_.reset(new FakeTestVolume("fake-usb",
    711                                          VOLUME_TYPE_REMOVABLE_DISK_PARTITION,
    712                                          chromeos::DEVICE_TYPE_USB));
    713     usb_volume_->Mount(profile());
    714     return "true";
    715   } else if (name == "mountFakeMtp") {
    716     mtp_volume_.reset(new FakeTestVolume("fake-mtp",
    717                                          VOLUME_TYPE_MTP,
    718                                          chromeos::DEVICE_TYPE_UNKNOWN));
    719     if (!mtp_volume_->PrepareTestEntries(profile()))
    720       return "false";
    721     mtp_volume_->Mount(profile());
    722     return "true";
    723   }
    724   return "unknownMessage";
    725 }
    726 
    727 drive::DriveIntegrationService*
    728 FileManagerBrowserTestBase::CreateDriveIntegrationService(Profile* profile) {
    729   drive_volumes_[profile->GetOriginalProfile()].reset(new DriveTestVolume());
    730   return drive_volumes_[profile->GetOriginalProfile()]->
    731       CreateDriveIntegrationService(profile);
    732 }
    733 
    734 // Parameter of FileManagerBrowserTest.
    735 // The second value is the case name of JavaScript.
    736 typedef std::tr1::tuple<GuestMode, const char*> TestParameter;
    737 
    738 // Test fixture class for normal (not multi-profile related) tests.
    739 class FileManagerBrowserTest :
    740       public FileManagerBrowserTestBase,
    741       public ::testing::WithParamInterface<TestParameter> {
    742   virtual GuestMode GetGuestModeParam() const OVERRIDE {
    743     return std::tr1::get<0>(GetParam());
    744   }
    745   virtual const char* GetTestCaseNameParam() const OVERRIDE {
    746     return std::tr1::get<1>(GetParam());
    747   }
    748 };
    749 
    750 IN_PROC_BROWSER_TEST_P(FileManagerBrowserTest, Test) {
    751   StartTest();
    752 }
    753 
    754 // Unlike TEST/TEST_F, which are macros that expand to further macros,
    755 // INSTANTIATE_TEST_CASE_P is a macro that expands directly to code that
    756 // stringizes the arguments. As a result, macros passed as parameters (such as
    757 // prefix or test_case_name) will not be expanded by the preprocessor. To work
    758 // around this, indirect the macro for INSTANTIATE_TEST_CASE_P, so that the
    759 // pre-processor will expand macros such as MAYBE_test_name before
    760 // instantiating the test.
    761 #define WRAPPED_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
    762   INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator)
    763 
    764 // Slow tests are disabled on debug build. http://crbug.com/327719
    765 #if !defined(NDEBUG)
    766 #define MAYBE_FileDisplay DISABLED_FileDisplay
    767 #else
    768 #define MAYBE_FileDisplay FileDisplay
    769 #endif
    770 WRAPPED_INSTANTIATE_TEST_CASE_P(
    771     MAYBE_FileDisplay,
    772     FileManagerBrowserTest,
    773     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "fileDisplayDownloads"),
    774                       TestParameter(IN_GUEST_MODE, "fileDisplayDownloads"),
    775                       TestParameter(NOT_IN_GUEST_MODE, "fileDisplayDrive"),
    776                       TestParameter(NOT_IN_GUEST_MODE, "fileDisplayMtp")));
    777 
    778 // http://crbug.com/327719
    779 WRAPPED_INSTANTIATE_TEST_CASE_P(
    780     DISABLED_OpenZipFiles,
    781     FileManagerBrowserTest,
    782     ::testing::Values(TestParameter(IN_GUEST_MODE, "zipOpenDownloads"),
    783                       TestParameter(NOT_IN_GUEST_MODE, "zipOpenDownloads"),
    784                       TestParameter(NOT_IN_GUEST_MODE, "zipOpenDrive")));
    785 
    786 // Slow tests are disabled on debug build. http://crbug.com/327719
    787 #if !defined(NDEBUG)
    788 #define MAYBE_OpenVideoFiles DISABLED_OpenVideoFiles
    789 #else
    790 #define MAYBE_OpenVideoFiles OpenVideoFiles
    791 #endif
    792 WRAPPED_INSTANTIATE_TEST_CASE_P(
    793     MAYBE_OpenVideoFiles,
    794     FileManagerBrowserTest,
    795     ::testing::Values(TestParameter(IN_GUEST_MODE, "videoOpenDownloads"),
    796                       TestParameter(NOT_IN_GUEST_MODE, "videoOpenDownloads"),
    797                       TestParameter(NOT_IN_GUEST_MODE, "videoOpenDrive")));
    798 
    799 // Slow tests are disabled on debug build. http://crbug.com/327719
    800 #if !defined(NDEBUG)
    801 #define MAYBE_OpenAudioFiles DISABLED_OpenAudioFiles
    802 #else
    803 #define MAYBE_OpenAudioFiles OpenAudioFiles
    804 #endif
    805 WRAPPED_INSTANTIATE_TEST_CASE_P(
    806     MAYBE_OpenAudioFiles,
    807     FileManagerBrowserTest,
    808     ::testing::Values(
    809         TestParameter(IN_GUEST_MODE, "audioOpenDownloads"),
    810         TestParameter(NOT_IN_GUEST_MODE, "audioOpenDownloads"),
    811         TestParameter(NOT_IN_GUEST_MODE, "audioOpenDrive"),
    812         TestParameter(NOT_IN_GUEST_MODE, "audioAutoAdvanceDrive"),
    813         TestParameter(NOT_IN_GUEST_MODE, "audioRepeatSingleFileDrive"),
    814         TestParameter(NOT_IN_GUEST_MODE, "audioNoRepeatSingleFileDrive"),
    815         TestParameter(NOT_IN_GUEST_MODE, "audioRepeatMultipleFileDrive"),
    816         TestParameter(NOT_IN_GUEST_MODE, "audioNoRepeatMultipleFileDrive")));
    817 
    818 // Flaky http://crbug.com/327719
    819 WRAPPED_INSTANTIATE_TEST_CASE_P(
    820     DISABLED_CreateNewFolder,
    821     FileManagerBrowserTest,
    822     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE,
    823                                     "createNewFolderAfterSelectFile"),
    824                       TestParameter(IN_GUEST_MODE,
    825                                     "createNewFolderDownloads"),
    826                       TestParameter(NOT_IN_GUEST_MODE,
    827                                     "createNewFolderDownloads"),
    828                       TestParameter(NOT_IN_GUEST_MODE,
    829                                     "createNewFolderDrive")));
    830 
    831 // Slow tests are disabled on debug build. http://crbug.com/327719
    832 #if !defined(NDEBUG)
    833 #define MAYBE_KeyboardOperations DISABLED_KeyboardOperations
    834 #else
    835 #define MAYBE_KeyboardOperations KeyboardOperations
    836 #endif
    837 WRAPPED_INSTANTIATE_TEST_CASE_P(
    838     MAYBE_KeyboardOperations,
    839     FileManagerBrowserTest,
    840     ::testing::Values(TestParameter(IN_GUEST_MODE, "keyboardDeleteDownloads"),
    841                       TestParameter(NOT_IN_GUEST_MODE,
    842                                     "keyboardDeleteDownloads"),
    843                       TestParameter(NOT_IN_GUEST_MODE, "keyboardDeleteDrive"),
    844                       TestParameter(IN_GUEST_MODE, "keyboardCopyDownloads"),
    845                       TestParameter(NOT_IN_GUEST_MODE, "keyboardCopyDownloads"),
    846                       TestParameter(NOT_IN_GUEST_MODE, "keyboardCopyDrive"),
    847                       TestParameter(IN_GUEST_MODE, "renameFileDownloads"),
    848                       TestParameter(NOT_IN_GUEST_MODE, "renameFileDownloads"),
    849                       TestParameter(NOT_IN_GUEST_MODE, "renameFileDrive")));
    850 
    851 // Slow tests are disabled on debug build. http://crbug.com/327719
    852 #if !defined(NDEBUG)
    853 #define MAYBE_DriveSpecific DISABLED_DriveSpecific
    854 #else
    855 #define MAYBE_DriveSpecific DriveSpecific
    856 #endif
    857 WRAPPED_INSTANTIATE_TEST_CASE_P(
    858     MAYBE_DriveSpecific,
    859     FileManagerBrowserTest,
    860     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "openSidebarRecent"),
    861                       TestParameter(NOT_IN_GUEST_MODE, "openSidebarOffline"),
    862                       TestParameter(NOT_IN_GUEST_MODE,
    863                                     "openSidebarSharedWithMe"),
    864                       TestParameter(NOT_IN_GUEST_MODE, "autocomplete")));
    865 
    866 // Slow tests are disabled on debug build. http://crbug.com/327719
    867 #if !defined(NDEBUG)
    868 #define MAYBE_Transfer DISABLED_Transfer
    869 #else
    870 #define MAYBE_Transfer Transfer
    871 #endif
    872 WRAPPED_INSTANTIATE_TEST_CASE_P(
    873     MAYBE_Transfer,
    874     FileManagerBrowserTest,
    875     ::testing::Values(
    876         TestParameter(NOT_IN_GUEST_MODE, "transferFromDriveToDownloads"),
    877         TestParameter(NOT_IN_GUEST_MODE, "transferFromDownloadsToDrive"),
    878         TestParameter(NOT_IN_GUEST_MODE, "transferFromSharedToDownloads"),
    879         TestParameter(NOT_IN_GUEST_MODE, "transferFromSharedToDrive"),
    880         TestParameter(NOT_IN_GUEST_MODE, "transferFromRecentToDownloads"),
    881         TestParameter(NOT_IN_GUEST_MODE, "transferFromRecentToDrive"),
    882         TestParameter(NOT_IN_GUEST_MODE, "transferFromOfflineToDownloads"),
    883         TestParameter(NOT_IN_GUEST_MODE, "transferFromOfflineToDrive")));
    884 
    885 // Slow tests are disabled on debug build. http://crbug.com/327719
    886 #if !defined(NDEBUG)
    887 #define MAYBE_RestorePrefs DISABLED_RestorePrefs
    888 #else
    889 #define MAYBE_RestorePrefs RestorePrefs
    890 #endif
    891 WRAPPED_INSTANTIATE_TEST_CASE_P(
    892     MAYBE_RestorePrefs,
    893     FileManagerBrowserTest,
    894     ::testing::Values(TestParameter(IN_GUEST_MODE, "restoreSortColumn"),
    895                       TestParameter(NOT_IN_GUEST_MODE, "restoreSortColumn"),
    896                       TestParameter(IN_GUEST_MODE, "restoreCurrentView"),
    897                       TestParameter(NOT_IN_GUEST_MODE, "restoreCurrentView")));
    898 
    899 // Slow tests are disabled on debug build. http://crbug.com/327719
    900 #if !defined(NDEBUG)
    901 #define MAYBE_ShareDialog DISABLED_ShareDialog
    902 #else
    903 #define MAYBE_ShareDialog ShareDialog
    904 #endif
    905 WRAPPED_INSTANTIATE_TEST_CASE_P(
    906     MAYBE_ShareDialog,
    907     FileManagerBrowserTest,
    908     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "shareFile"),
    909                       TestParameter(NOT_IN_GUEST_MODE, "shareDirectory")));
    910 
    911 // Slow tests are disabled on debug build. http://crbug.com/327719
    912 #if !defined(NDEBUG)
    913 #define MAYBE_RestoreGeometry DISABLED_RestoreGeometry
    914 #else
    915 #define MAYBE_RestoreGeometry RestoreGeometry
    916 #endif
    917 WRAPPED_INSTANTIATE_TEST_CASE_P(
    918     MAYBE_RestoreGeometry,
    919     FileManagerBrowserTest,
    920     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "restoreGeometry"),
    921                       TestParameter(IN_GUEST_MODE, "restoreGeometry")));
    922 
    923 // Slow tests are disabled on debug build. http://crbug.com/327719
    924 #if !defined(NDEBUG)
    925 #define MAYBE_Traverse DISABLED_Traverse
    926 #else
    927 #define MAYBE_Traverse Traverse
    928 #endif
    929 WRAPPED_INSTANTIATE_TEST_CASE_P(
    930     MAYBE_Traverse,
    931     FileManagerBrowserTest,
    932     ::testing::Values(TestParameter(IN_GUEST_MODE, "traverseDownloads"),
    933                       TestParameter(NOT_IN_GUEST_MODE, "traverseDownloads"),
    934                       TestParameter(NOT_IN_GUEST_MODE, "traverseDrive")));
    935 
    936 // Slow tests are disabled on debug build. http://crbug.com/327719
    937 #if !defined(NDEBUG)
    938 #define MAYBE_SuggestAppDialog DISABLED_SuggestAppDialog
    939 #else
    940 #define MAYBE_SuggestAppDialog SuggestAppDialog
    941 #endif
    942 WRAPPED_INSTANTIATE_TEST_CASE_P(
    943     MAYBE_SuggestAppDialog,
    944     FileManagerBrowserTest,
    945     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "suggestAppDialog")));
    946 
    947 // Slow tests are disabled on debug build. http://crbug.com/327719
    948 #if !defined(NDEBUG)
    949 #define MAYBE_ExecuteDefaultTaskOnDownloads \
    950   DISABLED_ExecuteDefaultTaskOnDownloads
    951 #else
    952 #define MAYBE_ExecuteDefaultTaskOnDownloads ExecuteDefaultTaskOnDownloads
    953 #endif
    954 WRAPPED_INSTANTIATE_TEST_CASE_P(
    955     MAYBE_ExecuteDefaultTaskOnDownloads,
    956     FileManagerBrowserTest,
    957     ::testing::Values(
    958         TestParameter(NOT_IN_GUEST_MODE, "executeDefaultTaskOnDownloads"),
    959         TestParameter(IN_GUEST_MODE, "executeDefaultTaskOnDownloads")));
    960 
    961 // Slow tests are disabled on debug build. http://crbug.com/327719
    962 #if !defined(NDEBUG)
    963 #define MAYBE_ExecuteDefaultTaskOnDrive DISABLED_ExecuteDefaultTaskOnDrive
    964 #else
    965 #define MAYBE_ExecuteDefaultTaskOnDrive ExecuteDefaultTaskOnDrive
    966 #endif
    967 INSTANTIATE_TEST_CASE_P(
    968     MAYBE_ExecuteDefaultTaskOnDrive,
    969     FileManagerBrowserTest,
    970     ::testing::Values(
    971         TestParameter(NOT_IN_GUEST_MODE, "executeDefaultTaskOnDrive")));
    972 
    973 // Slow tests are disabled on debug build. http://crbug.com/327719
    974 #if !defined(NDEBUG)
    975 #define MAYBE_DefaultActionDialog DISABLED_DefaultActionDialog
    976 #else
    977 #define MAYBE_DefaultActionDialog DefaultActionDialog
    978 #endif
    979 WRAPPED_INSTANTIATE_TEST_CASE_P(
    980     MAYBE_DefaultActionDialog,
    981     FileManagerBrowserTest,
    982     ::testing::Values(
    983         TestParameter(NOT_IN_GUEST_MODE, "defaultActionDialogOnDownloads"),
    984         TestParameter(IN_GUEST_MODE, "defaultActionDialogOnDownloads"),
    985         TestParameter(NOT_IN_GUEST_MODE, "defaultActionDialogOnDrive")));
    986 
    987 // Slow tests are disabled on debug build. http://crbug.com/327719
    988 #if !defined(NDEBUG)
    989 #define MAYBE_FolderShortcuts DISABLED_FolderShortcuts
    990 #else
    991 #define MAYBE_FolderShortcuts FolderShortcuts
    992 #endif
    993 WRAPPED_INSTANTIATE_TEST_CASE_P(
    994     MAYBE_FolderShortcuts,
    995     FileManagerBrowserTest,
    996     ::testing::Values(
    997         TestParameter(NOT_IN_GUEST_MODE, "traverseFolderShortcuts"),
    998         TestParameter(NOT_IN_GUEST_MODE, "addRemoveFolderShortcuts")));
    999 
   1000 INSTANTIATE_TEST_CASE_P(
   1001     TabIndex,
   1002     FileManagerBrowserTest,
   1003     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "searchBoxFocus")));
   1004 
   1005 // Slow tests are disabled on debug build. http://crbug.com/327719
   1006 #if !defined(NDEBUG)
   1007 #define MAYBE_Thumbnails DISABLED_Thumbnails
   1008 #else
   1009 #define MAYBE_Thumbnails Thumbnails
   1010 #endif
   1011 WRAPPED_INSTANTIATE_TEST_CASE_P(
   1012     MAYBE_Thumbnails,
   1013     FileManagerBrowserTest,
   1014     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "thumbnailsDownloads"),
   1015                       TestParameter(IN_GUEST_MODE, "thumbnailsDownloads")));
   1016 
   1017 #if !defined(NDEBUG)
   1018 #define MAYBE_OpenFileDialog DISABLED_OpenFileDialog
   1019 #else
   1020 #define MAYBE_OpenFileDialog OpenFileDialog
   1021 #endif
   1022 WRAPPED_INSTANTIATE_TEST_CASE_P(
   1023     MAYBE_OpenFileDialog,
   1024     FileManagerBrowserTest,
   1025     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE,
   1026                                     "openFileDialogOnDownloads"),
   1027                       TestParameter(IN_GUEST_MODE,
   1028                                     "openFileDialogOnDownloads"),
   1029                       TestParameter(NOT_IN_GUEST_MODE,
   1030                                     "openFileDialogOnDrive"),
   1031                       TestParameter(IN_INCOGNITO,
   1032                                     "openFileDialogOnDownloads"),
   1033                       TestParameter(IN_INCOGNITO,
   1034                                     "openFileDialogOnDrive")));
   1035 
   1036 // Slow tests are disabled on debug build. http://crbug.com/327719
   1037 #if !defined(NDEBUG)
   1038 #define MAYBE_CopyBetweenWindows DISABLED_CopyBetweenWindows
   1039 #else
   1040 #define MAYBE_CopyBetweenWindows CopyBetweenWindows
   1041 #endif
   1042 WRAPPED_INSTANTIATE_TEST_CASE_P(
   1043     MAYBE_CopyBetweenWindows,
   1044     FileManagerBrowserTest,
   1045     ::testing::Values(
   1046         TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsLocalToDrive"),
   1047         TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsLocalToUsb"),
   1048         TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsUsbToDrive"),
   1049         TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsDriveToLocal"),
   1050         TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsDriveToUsb"),
   1051         TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsUsbToLocal")));
   1052 
   1053 // Slow tests are disabled on debug build. http://crbug.com/327719
   1054 #if !defined(NDEBUG)
   1055 #define MAYBE_ShowGridView DISABLED_ShowGridView
   1056 #else
   1057 #define MAYBE_ShowGridView ShowGridView
   1058 #endif
   1059 WRAPPED_INSTANTIATE_TEST_CASE_P(
   1060     MAYBE_ShowGridView,
   1061     FileManagerBrowserTest,
   1062     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "showGridViewDownloads"),
   1063                       TestParameter(IN_GUEST_MODE, "showGridViewDownloads"),
   1064                       TestParameter(NOT_IN_GUEST_MODE, "showGridViewDrive")));
   1065 
   1066 // Structure to describe an account info.
   1067 struct TestAccountInfo {
   1068   const char* const email;
   1069   const char* const hash;
   1070   const char* const display_name;
   1071 };
   1072 
   1073 enum {
   1074   DUMMY_ACCOUNT_INDEX = 0,
   1075   PRIMARY_ACCOUNT_INDEX = 1,
   1076   SECONDARY_ACCOUNT_INDEX_START = 2,
   1077 };
   1078 
   1079 static const TestAccountInfo kTestAccounts[] = {
   1080   {"__dummy__ (at) invalid.domain", "hashdummy", "Dummy Account"},
   1081   {"alice (at) invalid.domain", "hashalice", "Alice"},
   1082   {"bob (at) invalid.domain", "hashbob", "Bob"},
   1083   {"charlie (at) invalid.domain", "hashcharlie", "Charlie"},
   1084 };
   1085 
   1086 // Test fixture class for testing multi-profile features.
   1087 class MultiProfileFileManagerBrowserTest : public FileManagerBrowserTestBase {
   1088  protected:
   1089   // Enables multi-profiles.
   1090   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
   1091     FileManagerBrowserTestBase::SetUpCommandLine(command_line);
   1092     // Logs in to a dummy profile (For making MultiProfileWindowManager happy;
   1093     // browser test creates a default window and the manager tries to assign a
   1094     // user for it, and we need a profile connected to a user.)
   1095     command_line->AppendSwitchASCII(chromeos::switches::kLoginUser,
   1096                                     kTestAccounts[DUMMY_ACCOUNT_INDEX].email);
   1097     command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile,
   1098                                     kTestAccounts[DUMMY_ACCOUNT_INDEX].hash);
   1099   }
   1100 
   1101   // Logs in to the primary profile of this test.
   1102   virtual void SetUpOnMainThread() OVERRIDE {
   1103     const TestAccountInfo& info = kTestAccounts[PRIMARY_ACCOUNT_INDEX];
   1104 
   1105     AddUser(info, true);
   1106     FileManagerBrowserTestBase::SetUpOnMainThread();
   1107   }
   1108 
   1109   // Loads all users to the current session and sets up necessary fields.
   1110   // This is used for preparing all accounts in PRE_ test setup, and for testing
   1111   // actual login behavior.
   1112   void AddAllUsers() {
   1113     for (size_t i = 0; i < arraysize(kTestAccounts); ++i)
   1114       AddUser(kTestAccounts[i], i >= SECONDARY_ACCOUNT_INDEX_START);
   1115   }
   1116 
   1117   // Returns primary profile (if it is already created.)
   1118   virtual Profile* profile() OVERRIDE {
   1119     Profile* const profile = chromeos::ProfileHelper::GetProfileByUserIdHash(
   1120         kTestAccounts[PRIMARY_ACCOUNT_INDEX].hash);
   1121     return profile ? profile : FileManagerBrowserTestBase::profile();
   1122   }
   1123 
   1124   // Sets the test case name (used as a function name in test_cases.js to call.)
   1125   void set_test_case_name(const std::string& name) { test_case_name_ = name; }
   1126 
   1127   // Adds a new user for testing to the current session.
   1128   void AddUser(const TestAccountInfo& info, bool log_in) {
   1129     user_manager::UserManager* const user_manager =
   1130         user_manager::UserManager::Get();
   1131     if (log_in)
   1132       user_manager->UserLoggedIn(info.email, info.hash, false);
   1133     user_manager->SaveUserDisplayName(info.email,
   1134                                       base::UTF8ToUTF16(info.display_name));
   1135     chromeos::ProfileHelper::GetProfileByUserIdHash(info.hash)->GetPrefs()->
   1136         SetString(prefs::kGoogleServicesUsername, info.email);
   1137   }
   1138 
   1139  private:
   1140   virtual GuestMode GetGuestModeParam() const OVERRIDE {
   1141     return NOT_IN_GUEST_MODE;
   1142   }
   1143 
   1144   virtual const char* GetTestCaseNameParam() const OVERRIDE {
   1145     return test_case_name_.c_str();
   1146   }
   1147 
   1148   virtual std::string OnMessage(const std::string& name,
   1149                                 const base::Value* value) OVERRIDE {
   1150     if (name == "addAllUsers") {
   1151       AddAllUsers();
   1152       return "true";
   1153     } else if (name == "getWindowOwnerId") {
   1154       chrome::MultiUserWindowManager* const window_manager =
   1155           chrome::MultiUserWindowManager::GetInstance();
   1156       extensions::AppWindowRegistry* const app_window_registry =
   1157           extensions::AppWindowRegistry::Get(profile());
   1158       DCHECK(window_manager);
   1159       DCHECK(app_window_registry);
   1160 
   1161       const extensions::AppWindowRegistry::AppWindowList& list =
   1162           app_window_registry->GetAppWindowsForApp(
   1163               file_manager::kFileManagerAppId);
   1164       return list.size() == 1u ?
   1165           window_manager->GetUserPresentingWindow(
   1166               list.front()->GetNativeWindow()) : "";
   1167     }
   1168     return FileManagerBrowserTestBase::OnMessage(name, value);
   1169   }
   1170 
   1171   std::string test_case_name_;
   1172 };
   1173 
   1174 // Slow tests are disabled on debug build. http://crbug.com/327719
   1175 #if !defined(NDEBUG)
   1176 #define MAYBE_PRE_BasicDownloads DISABLED_PRE_BasicDownloads
   1177 #define MAYBE_BasicDownloads DISABLED_BasicDownloads
   1178 #else
   1179 #define MAYBE_PRE_BasicDownloads PRE_BasicDownloads
   1180 #define MAYBE_BasicDownloads BasicDownloads
   1181 #endif
   1182 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
   1183                        MAYBE_PRE_BasicDownloads) {
   1184   AddAllUsers();
   1185 }
   1186 
   1187 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
   1188                        MAYBE_BasicDownloads) {
   1189   AddAllUsers();
   1190 
   1191   // Sanity check that normal operations work in multi-profile setting as well.
   1192   set_test_case_name("keyboardCopyDownloads");
   1193   StartTest();
   1194 }
   1195 
   1196 // Slow tests are disabled on debug build. http://crbug.com/327719
   1197 #if !defined(NDEBUG)
   1198 #define MAYBE_PRE_BasicDrive DISABLED_PRE_BasicDrive
   1199 #define MAYBE_BasicDrive DISABLED_BasicDrive
   1200 #else
   1201 #define MAYBE_PRE_BasicDrive PRE_BasicDrive
   1202 #define MAYBE_BasicDrive BasicDrive
   1203 #endif
   1204 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
   1205                        MAYBE_PRE_BasicDrive) {
   1206   AddAllUsers();
   1207 }
   1208 
   1209 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, MAYBE_BasicDrive) {
   1210   AddAllUsers();
   1211 
   1212   // Sanity check that normal operations work in multi-profile setting as well.
   1213   set_test_case_name("keyboardCopyDrive");
   1214   StartTest();
   1215 }
   1216 
   1217 template<GuestMode M>
   1218 class GalleryBrowserTestBase : public FileManagerBrowserTestBase {
   1219  public:
   1220   virtual GuestMode GetGuestModeParam() const OVERRIDE { return M; }
   1221   virtual const char* GetTestCaseNameParam() const OVERRIDE {
   1222     return test_case_name_.c_str();
   1223   }
   1224 
   1225  protected:
   1226   virtual void SetUp() OVERRIDE {
   1227     AddScript("common/test_util_common.js");
   1228     AddScript("gallery/test_util.js");
   1229     FileManagerBrowserTestBase::SetUp();
   1230   }
   1231 
   1232   virtual std::string OnMessage(const std::string& name,
   1233                                 const base::Value* value) OVERRIDE;
   1234 
   1235   virtual const char* GetTestManifestName() const OVERRIDE {
   1236     return "gallery_test_manifest.json";
   1237   }
   1238 
   1239   void AddScript(const std::string& name) {
   1240     scripts_.AppendString(
   1241         "chrome-extension://ejhcmmdhhpdhhgmifplfmjobgegbibkn/" + name);
   1242   }
   1243 
   1244   void set_test_case_name(const std::string& name) {
   1245     test_case_name_ = name;
   1246   }
   1247 
   1248  private:
   1249   base::ListValue scripts_;
   1250   std::string test_case_name_;
   1251 };
   1252 
   1253 template<GuestMode M>
   1254 std::string GalleryBrowserTestBase<M>::OnMessage(const std::string& name,
   1255                                                  const base::Value* value) {
   1256   if (name == "getScripts") {
   1257     std::string jsonString;
   1258     base::JSONWriter::Write(&scripts_, &jsonString);
   1259     return jsonString;
   1260   }
   1261   return FileManagerBrowserTestBase::OnMessage(name, value);
   1262 }
   1263 
   1264 typedef GalleryBrowserTestBase<NOT_IN_GUEST_MODE> GalleryBrowserTest;
   1265 typedef GalleryBrowserTestBase<IN_GUEST_MODE> GalleryBrowserTestInGuestMode;
   1266 
   1267 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, OpenSingleImageOnDownloads) {
   1268   AddScript("gallery/open_image_files.js");
   1269   set_test_case_name("openSingleImageOnDownloads");
   1270   StartTest();
   1271 }
   1272 
   1273 IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
   1274                        OpenSingleImageOnDownloads) {
   1275   AddScript("gallery/open_image_files.js");
   1276   set_test_case_name("openSingleImageOnDownloads");
   1277   StartTest();
   1278 }
   1279 
   1280 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, OpenSingleImageOnDrive) {
   1281   AddScript("gallery/open_image_files.js");
   1282   set_test_case_name("openSingleImageOnDrive");
   1283   StartTest();
   1284 }
   1285 
   1286 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, OpenMultipleImagesOnDownloads) {
   1287   AddScript("gallery/open_image_files.js");
   1288   set_test_case_name("openMultipleImagesOnDownloads");
   1289   StartTest();
   1290 }
   1291 
   1292 IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
   1293                        OpenMultipleImagesOnDownloads) {
   1294   AddScript("gallery/open_image_files.js");
   1295   set_test_case_name("openMultipleImagesOnDownloads");
   1296   StartTest();
   1297 }
   1298 
   1299 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, OpenMultipleImagesOnDrive) {
   1300   AddScript("gallery/open_image_files.js");
   1301   set_test_case_name("openMultipleImagesOnDrive");
   1302   StartTest();
   1303 }
   1304 
   1305 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, TraverseSlideImagesOnDownloads) {
   1306   AddScript("gallery/slide_mode.js");
   1307   set_test_case_name("traverseSlideImagesOnDownloads");
   1308   StartTest();
   1309 }
   1310 
   1311 IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
   1312                        TraverseSlideImagesOnDownloads) {
   1313   AddScript("gallery/slide_mode.js");
   1314   set_test_case_name("traverseSlideImagesOnDownloads");
   1315   StartTest();
   1316 }
   1317 
   1318 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, TraverseSlideImagesOnDrive) {
   1319   AddScript("gallery/slide_mode.js");
   1320   set_test_case_name("traverseSlideImagesOnDrive");
   1321   StartTest();
   1322 }
   1323 
   1324 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, RenameImageOnDownloads) {
   1325   AddScript("gallery/slide_mode.js");
   1326   set_test_case_name("renameImageOnDownloads");
   1327   StartTest();
   1328 }
   1329 
   1330 IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
   1331                        RenameImageOnDownloads) {
   1332   AddScript("gallery/slide_mode.js");
   1333   set_test_case_name("renameImageOnDownloads");
   1334   StartTest();
   1335 }
   1336 
   1337 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, RenameImageOnDrive) {
   1338   AddScript("gallery/slide_mode.js");
   1339   set_test_case_name("renameImageOnDrive");
   1340   StartTest();
   1341 }
   1342 
   1343 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, DeleteImageOnDownloads) {
   1344   AddScript("gallery/slide_mode.js");
   1345   set_test_case_name("deleteImageOnDownloads");
   1346   StartTest();
   1347 }
   1348 
   1349 IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
   1350                        DeleteImageOnDownloads) {
   1351   AddScript("gallery/slide_mode.js");
   1352   set_test_case_name("deleteImageOnDownloads");
   1353   StartTest();
   1354 }
   1355 
   1356 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, DeleteImageOnDrive) {
   1357   AddScript("gallery/slide_mode.js");
   1358   set_test_case_name("deleteImageOnDrive");
   1359   StartTest();
   1360 }
   1361 
   1362 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, RotateImageOnDownloads) {
   1363   AddScript("gallery/photo_editor.js");
   1364   set_test_case_name("rotateImageOnDownloads");
   1365   StartTest();
   1366 }
   1367 
   1368 IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
   1369                        RotateImageOnDownloads) {
   1370   AddScript("gallery/photo_editor.js");
   1371   set_test_case_name("rotateImageOnDownloads");
   1372   StartTest();
   1373 }
   1374 
   1375 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, RotateImageOnDrive) {
   1376   AddScript("gallery/photo_editor.js");
   1377   set_test_case_name("rotateImageOnDrive");
   1378   StartTest();
   1379 }
   1380 
   1381 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, CropImageOnDownloads) {
   1382   AddScript("gallery/photo_editor.js");
   1383   set_test_case_name("cropImageOnDownloads");
   1384   StartTest();
   1385 }
   1386 
   1387 IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
   1388                        CropImageOnDownloads) {
   1389   AddScript("gallery/photo_editor.js");
   1390   set_test_case_name("cropImageOnDownloads");
   1391   StartTest();
   1392 }
   1393 
   1394 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, CropImageOnDrive) {
   1395   AddScript("gallery/photo_editor.js");
   1396   set_test_case_name("cropImageOnDrive");
   1397   StartTest();
   1398 }
   1399 
   1400 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, ExposureImageOnDownloads) {
   1401   AddScript("gallery/photo_editor.js");
   1402   set_test_case_name("exposureImageOnDownloads");
   1403   StartTest();
   1404 }
   1405 
   1406 IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
   1407                        ExposureImageOnDownloads) {
   1408   AddScript("gallery/photo_editor.js");
   1409   set_test_case_name("exposureImageOnDownloads");
   1410   StartTest();
   1411 }
   1412 
   1413 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, ExposureImageOnDrive) {
   1414   AddScript("gallery/photo_editor.js");
   1415   set_test_case_name("exposureImageOnDrive");
   1416   StartTest();
   1417 }
   1418 
   1419 template<GuestMode M>
   1420 class VideoPlayerBrowserTestBase : public FileManagerBrowserTestBase {
   1421  public:
   1422   virtual GuestMode GetGuestModeParam() const OVERRIDE { return M; }
   1423   virtual const char* GetTestCaseNameParam() const OVERRIDE {
   1424     return test_case_name_.c_str();
   1425   }
   1426 
   1427  protected:
   1428   virtual void SetUp() OVERRIDE {
   1429     AddScript("common/test_util_common.js");
   1430     AddScript("video_player/test_util.js");
   1431     FileManagerBrowserTestBase::SetUp();
   1432   }
   1433 
   1434   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
   1435     command_line->AppendSwitch(
   1436         chromeos::switches::kEnableVideoPlayerChromecastSupport);
   1437     FileManagerBrowserTestBase::SetUpCommandLine(command_line);
   1438   }
   1439 
   1440   virtual std::string OnMessage(const std::string& name,
   1441                                 const base::Value* value) OVERRIDE;
   1442 
   1443   virtual const char* GetTestManifestName() const OVERRIDE {
   1444     return "video_player_test_manifest.json";
   1445   }
   1446 
   1447   void AddScript(const std::string& name) {
   1448     scripts_.AppendString(
   1449         "chrome-extension://ljoplibgfehghmibaoaepfagnmbbfiga/" + name);
   1450   }
   1451 
   1452   void set_test_case_name(const std::string& name) {
   1453     test_case_name_ = name;
   1454   }
   1455 
   1456  private:
   1457   base::ListValue scripts_;
   1458   std::string test_case_name_;
   1459 };
   1460 
   1461 template<GuestMode M>
   1462 std::string VideoPlayerBrowserTestBase<M>::OnMessage(const std::string& name,
   1463                                                      const base::Value* value) {
   1464   if (name == "getScripts") {
   1465     std::string jsonString;
   1466     base::JSONWriter::Write(&scripts_, &jsonString);
   1467     return jsonString;
   1468   }
   1469   return FileManagerBrowserTestBase::OnMessage(name, value);
   1470 }
   1471 
   1472 typedef VideoPlayerBrowserTestBase<NOT_IN_GUEST_MODE> VideoPlayerBrowserTest;
   1473 typedef VideoPlayerBrowserTestBase<IN_GUEST_MODE>
   1474     VideoPlayerBrowserTestInGuestMode;
   1475 
   1476 IN_PROC_BROWSER_TEST_F(VideoPlayerBrowserTest, OpenSingleVideoOnDownloads) {
   1477   AddScript("video_player/open_video_files.js");
   1478   set_test_case_name("openSingleVideoOnDownloads");
   1479   StartTest();
   1480 }
   1481 
   1482 IN_PROC_BROWSER_TEST_F(VideoPlayerBrowserTest, OpenSingleVideoOnDrive) {
   1483   AddScript("video_player/open_video_files.js");
   1484   set_test_case_name("openSingleVideoOnDrive");
   1485   StartTest();
   1486 }
   1487 
   1488 }  // namespace
   1489 }  // namespace file_manager
   1490