31c1c385a65929f1be3695d83455e84e268ffce3
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / file_manager / file_manager_browsertest.cc
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 "apps/app_window.h"
15 #include "apps/app_window_registry.h"
16 #include "base/bind.h"
17 #include "base/file_util.h"
18 #include "base/files/file_path.h"
19 #include "base/json/json_reader.h"
20 #include "base/json/json_value_converter.h"
21 #include "base/json/json_writer.h"
22 #include "base/prefs/pref_service.h"
23 #include "base/strings/string_piece.h"
24 #include "base/strings/utf_string_conversions.h"
25 #include "base/time/time.h"
26 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
27 #include "chrome/browser/chromeos/drive/file_system_interface.h"
28 #include "chrome/browser/chromeos/file_manager/app_id.h"
29 #include "chrome/browser/chromeos/file_manager/drive_test_util.h"
30 #include "chrome/browser/chromeos/file_manager/path_util.h"
31 #include "chrome/browser/chromeos/file_manager/volume_manager.h"
32 #include "chrome/browser/chromeos/profiles/profile_helper.h"
33 #include "chrome/browser/drive/fake_drive_service.h"
34 #include "chrome/browser/extensions/component_loader.h"
35 #include "chrome/browser/extensions/extension_apitest.h"
36 #include "chrome/browser/extensions/extension_test_message_listener.h"
37 #include "chrome/browser/profiles/profile.h"
38 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
39 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
40 #include "chrome/common/chrome_switches.h"
41 #include "chrome/common/pref_names.h"
42 #include "chromeos/chromeos_switches.h"
43 #include "components/user_manager/user_manager.h"
44 #include "content/public/browser/notification_service.h"
45 #include "content/public/test/test_utils.h"
46 #include "extensions/browser/api/test/test_api.h"
47 #include "extensions/browser/notification_types.h"
48 #include "extensions/common/extension.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 "webkit/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     fileapi::ExternalMountPoints* const mount_points =
316         fileapi::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                                          fileapi::kFileSystemTypeNativeLocal,
323                                          fileapi::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 // Slow tests are disabled on debug build. http://crbug.com/327719
819 #if !defined(NDEBUG)
820 #define MAYBE_CreateNewFolder DISABLED_CreateNewFolder
821 #else
822 #define MAYBE_CreateNewFolder CreateNewFolder
823 #endif
824 WRAPPED_INSTANTIATE_TEST_CASE_P(
825     MAYBE_CreateNewFolder,
826     FileManagerBrowserTest,
827     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE,
828                                     "createNewFolderAfterSelectFile"),
829                       TestParameter(IN_GUEST_MODE,
830                                     "createNewFolderDownloads"),
831                       TestParameter(NOT_IN_GUEST_MODE,
832                                     "createNewFolderDownloads"),
833                       TestParameter(NOT_IN_GUEST_MODE,
834                                     "createNewFolderDrive")));
835
836 // Slow tests are disabled on debug build. http://crbug.com/327719
837 #if !defined(NDEBUG)
838 #define MAYBE_KeyboardOperations DISABLED_KeyboardOperations
839 #else
840 #define MAYBE_KeyboardOperations KeyboardOperations
841 #endif
842 WRAPPED_INSTANTIATE_TEST_CASE_P(
843     MAYBE_KeyboardOperations,
844     FileManagerBrowserTest,
845     ::testing::Values(TestParameter(IN_GUEST_MODE, "keyboardDeleteDownloads"),
846                       TestParameter(NOT_IN_GUEST_MODE,
847                                     "keyboardDeleteDownloads"),
848                       TestParameter(NOT_IN_GUEST_MODE, "keyboardDeleteDrive"),
849                       TestParameter(IN_GUEST_MODE, "keyboardCopyDownloads"),
850                       TestParameter(NOT_IN_GUEST_MODE, "keyboardCopyDownloads"),
851                       TestParameter(NOT_IN_GUEST_MODE, "keyboardCopyDrive"),
852                       TestParameter(IN_GUEST_MODE, "renameFileDownloads"),
853                       TestParameter(NOT_IN_GUEST_MODE, "renameFileDownloads"),
854                       TestParameter(NOT_IN_GUEST_MODE, "renameFileDrive")));
855
856 // Slow tests are disabled on debug build. http://crbug.com/327719
857 #if !defined(NDEBUG)
858 #define MAYBE_DriveSpecific DISABLED_DriveSpecific
859 #else
860 #define MAYBE_DriveSpecific DriveSpecific
861 #endif
862 WRAPPED_INSTANTIATE_TEST_CASE_P(
863     MAYBE_DriveSpecific,
864     FileManagerBrowserTest,
865     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "openSidebarRecent"),
866                       TestParameter(NOT_IN_GUEST_MODE, "openSidebarOffline"),
867                       TestParameter(NOT_IN_GUEST_MODE,
868                                     "openSidebarSharedWithMe"),
869                       TestParameter(NOT_IN_GUEST_MODE, "autocomplete")));
870
871 // Slow tests are disabled on debug build. http://crbug.com/327719
872 #if !defined(NDEBUG)
873 #define MAYBE_Transfer DISABLED_Transfer
874 #else
875 #define MAYBE_Transfer Transfer
876 #endif
877 WRAPPED_INSTANTIATE_TEST_CASE_P(
878     MAYBE_Transfer,
879     FileManagerBrowserTest,
880     ::testing::Values(
881         TestParameter(NOT_IN_GUEST_MODE, "transferFromDriveToDownloads"),
882         TestParameter(NOT_IN_GUEST_MODE, "transferFromDownloadsToDrive"),
883         TestParameter(NOT_IN_GUEST_MODE, "transferFromSharedToDownloads"),
884         TestParameter(NOT_IN_GUEST_MODE, "transferFromSharedToDrive"),
885         TestParameter(NOT_IN_GUEST_MODE, "transferFromRecentToDownloads"),
886         TestParameter(NOT_IN_GUEST_MODE, "transferFromRecentToDrive"),
887         TestParameter(NOT_IN_GUEST_MODE, "transferFromOfflineToDownloads"),
888         TestParameter(NOT_IN_GUEST_MODE, "transferFromOfflineToDrive")));
889
890 // Slow tests are disabled on debug build. http://crbug.com/327719
891 #if !defined(NDEBUG)
892 #define MAYBE_RestorePrefs DISABLED_RestorePrefs
893 #else
894 #define MAYBE_RestorePrefs RestorePrefs
895 #endif
896 WRAPPED_INSTANTIATE_TEST_CASE_P(
897     MAYBE_RestorePrefs,
898     FileManagerBrowserTest,
899     ::testing::Values(TestParameter(IN_GUEST_MODE, "restoreSortColumn"),
900                       TestParameter(NOT_IN_GUEST_MODE, "restoreSortColumn"),
901                       TestParameter(IN_GUEST_MODE, "restoreCurrentView"),
902                       TestParameter(NOT_IN_GUEST_MODE, "restoreCurrentView")));
903
904 // Slow tests are disabled on debug build. http://crbug.com/327719
905 #if !defined(NDEBUG)
906 #define MAYBE_ShareDialog DISABLED_ShareDialog
907 #else
908 #define MAYBE_ShareDialog ShareDialog
909 #endif
910 WRAPPED_INSTANTIATE_TEST_CASE_P(
911     MAYBE_ShareDialog,
912     FileManagerBrowserTest,
913     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "shareFile"),
914                       TestParameter(NOT_IN_GUEST_MODE, "shareDirectory")));
915
916 // Slow tests are disabled on debug build. http://crbug.com/327719
917 #if !defined(NDEBUG)
918 #define MAYBE_RestoreGeometry DISABLED_RestoreGeometry
919 #else
920 #define MAYBE_RestoreGeometry RestoreGeometry
921 #endif
922 WRAPPED_INSTANTIATE_TEST_CASE_P(
923     MAYBE_RestoreGeometry,
924     FileManagerBrowserTest,
925     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "restoreGeometry"),
926                       TestParameter(IN_GUEST_MODE, "restoreGeometry")));
927
928 // Slow tests are disabled on debug build. http://crbug.com/327719
929 #if !defined(NDEBUG)
930 #define MAYBE_Traverse DISABLED_Traverse
931 #else
932 #define MAYBE_Traverse Traverse
933 #endif
934 WRAPPED_INSTANTIATE_TEST_CASE_P(
935     MAYBE_Traverse,
936     FileManagerBrowserTest,
937     ::testing::Values(TestParameter(IN_GUEST_MODE, "traverseDownloads"),
938                       TestParameter(NOT_IN_GUEST_MODE, "traverseDownloads"),
939                       TestParameter(NOT_IN_GUEST_MODE, "traverseDrive")));
940
941 // Slow tests are disabled on debug build. http://crbug.com/327719
942 #if !defined(NDEBUG)
943 #define MAYBE_SuggestAppDialog DISABLED_SuggestAppDialog
944 #else
945 #define MAYBE_SuggestAppDialog SuggestAppDialog
946 #endif
947 WRAPPED_INSTANTIATE_TEST_CASE_P(
948     MAYBE_SuggestAppDialog,
949     FileManagerBrowserTest,
950     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "suggestAppDialog")));
951
952 // Slow tests are disabled on debug build. http://crbug.com/327719
953 #if !defined(NDEBUG)
954 #define MAYBE_ExecuteDefaultTaskOnDownloads \
955   DISABLED_ExecuteDefaultTaskOnDownloads
956 #else
957 #define MAYBE_ExecuteDefaultTaskOnDownloads ExecuteDefaultTaskOnDownloads
958 #endif
959 WRAPPED_INSTANTIATE_TEST_CASE_P(
960     MAYBE_ExecuteDefaultTaskOnDownloads,
961     FileManagerBrowserTest,
962     ::testing::Values(
963         TestParameter(NOT_IN_GUEST_MODE, "executeDefaultTaskOnDownloads"),
964         TestParameter(IN_GUEST_MODE, "executeDefaultTaskOnDownloads")));
965
966 // Slow tests are disabled on debug build. http://crbug.com/327719
967 #if !defined(NDEBUG)
968 #define MAYBE_ExecuteDefaultTaskOnDrive DISABLED_ExecuteDefaultTaskOnDrive
969 #else
970 #define MAYBE_ExecuteDefaultTaskOnDrive ExecuteDefaultTaskOnDrive
971 #endif
972 INSTANTIATE_TEST_CASE_P(
973     MAYBE_ExecuteDefaultTaskOnDrive,
974     FileManagerBrowserTest,
975     ::testing::Values(
976         TestParameter(NOT_IN_GUEST_MODE, "executeDefaultTaskOnDrive")));
977
978 // Slow tests are disabled on debug build. http://crbug.com/327719
979 #if !defined(NDEBUG)
980 #define MAYBE_DefaultActionDialog DISABLED_DefaultActionDialog
981 #else
982 #define MAYBE_DefaultActionDialog DefaultActionDialog
983 #endif
984 WRAPPED_INSTANTIATE_TEST_CASE_P(
985     MAYBE_DefaultActionDialog,
986     FileManagerBrowserTest,
987     ::testing::Values(
988         TestParameter(NOT_IN_GUEST_MODE, "defaultActionDialogOnDownloads"),
989         TestParameter(IN_GUEST_MODE, "defaultActionDialogOnDownloads"),
990         TestParameter(NOT_IN_GUEST_MODE, "defaultActionDialogOnDrive")));
991
992 // Slow tests are disabled on debug build. http://crbug.com/327719
993 #if !defined(NDEBUG)
994 #define MAYBE_FolderShortcuts DISABLED_FolderShortcuts
995 #else
996 #define MAYBE_FolderShortcuts FolderShortcuts
997 #endif
998 WRAPPED_INSTANTIATE_TEST_CASE_P(
999     MAYBE_FolderShortcuts,
1000     FileManagerBrowserTest,
1001     ::testing::Values(
1002         TestParameter(NOT_IN_GUEST_MODE, "traverseFolderShortcuts"),
1003         TestParameter(NOT_IN_GUEST_MODE, "addRemoveFolderShortcuts")));
1004
1005 INSTANTIATE_TEST_CASE_P(
1006     TabIndex,
1007     FileManagerBrowserTest,
1008     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "searchBoxFocus")));
1009
1010 // Slow tests are disabled on debug build. http://crbug.com/327719
1011 #if !defined(NDEBUG)
1012 #define MAYBE_Thumbnails DISABLED_Thumbnails
1013 #else
1014 #define MAYBE_Thumbnails Thumbnails
1015 #endif
1016 WRAPPED_INSTANTIATE_TEST_CASE_P(
1017     MAYBE_Thumbnails,
1018     FileManagerBrowserTest,
1019     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "thumbnailsDownloads"),
1020                       TestParameter(IN_GUEST_MODE, "thumbnailsDownloads")));
1021
1022 #if !defined(NDEBUG)
1023 #define MAYBE_OpenFileDialog DISABLED_OpenFileDialog
1024 #else
1025 #define MAYBE_OpenFileDialog OpenFileDialog
1026 #endif
1027 WRAPPED_INSTANTIATE_TEST_CASE_P(
1028     MAYBE_OpenFileDialog,
1029     FileManagerBrowserTest,
1030     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE,
1031                                     "openFileDialogOnDownloads"),
1032                       TestParameter(IN_GUEST_MODE,
1033                                     "openFileDialogOnDownloads"),
1034                       TestParameter(NOT_IN_GUEST_MODE,
1035                                     "openFileDialogOnDrive"),
1036                       TestParameter(IN_INCOGNITO,
1037                                     "openFileDialogOnDownloads"),
1038                       TestParameter(IN_INCOGNITO,
1039                                     "openFileDialogOnDrive")));
1040
1041 // Slow tests are disabled on debug build. http://crbug.com/327719
1042 #if !defined(NDEBUG)
1043 #define MAYBE_CopyBetweenWindows DISABLED_CopyBetweenWindows
1044 #else
1045 #define MAYBE_CopyBetweenWindows CopyBetweenWindows
1046 #endif
1047 WRAPPED_INSTANTIATE_TEST_CASE_P(
1048     MAYBE_CopyBetweenWindows,
1049     FileManagerBrowserTest,
1050     ::testing::Values(
1051         TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsLocalToDrive"),
1052         TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsLocalToUsb"),
1053         TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsUsbToDrive"),
1054         TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsDriveToLocal"),
1055         TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsDriveToUsb"),
1056         TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsUsbToLocal")));
1057
1058 // Slow tests are disabled on debug build. http://crbug.com/327719
1059 #if !defined(NDEBUG)
1060 #define MAYBE_ShowGridView DISABLED_ShowGridView
1061 #else
1062 #define MAYBE_ShowGridView ShowGridView
1063 #endif
1064 WRAPPED_INSTANTIATE_TEST_CASE_P(
1065     MAYBE_ShowGridView,
1066     FileManagerBrowserTest,
1067     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "showGridViewDownloads"),
1068                       TestParameter(IN_GUEST_MODE, "showGridViewDownloads"),
1069                       TestParameter(NOT_IN_GUEST_MODE, "showGridViewDrive")));
1070
1071 // Structure to describe an account info.
1072 struct TestAccountInfo {
1073   const char* const email;
1074   const char* const hash;
1075   const char* const display_name;
1076 };
1077
1078 enum {
1079   DUMMY_ACCOUNT_INDEX = 0,
1080   PRIMARY_ACCOUNT_INDEX = 1,
1081   SECONDARY_ACCOUNT_INDEX_START = 2,
1082 };
1083
1084 static const TestAccountInfo kTestAccounts[] = {
1085   {"__dummy__@invalid.domain", "hashdummy", "Dummy Account"},
1086   {"alice@invalid.domain", "hashalice", "Alice"},
1087   {"bob@invalid.domain", "hashbob", "Bob"},
1088   {"charlie@invalid.domain", "hashcharlie", "Charlie"},
1089 };
1090
1091 // Test fixture class for testing multi-profile features.
1092 class MultiProfileFileManagerBrowserTest : public FileManagerBrowserTestBase {
1093  protected:
1094   // Enables multi-profiles.
1095   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1096     FileManagerBrowserTestBase::SetUpCommandLine(command_line);
1097     // Logs in to a dummy profile (For making MultiProfileWindowManager happy;
1098     // browser test creates a default window and the manager tries to assign a
1099     // user for it, and we need a profile connected to a user.)
1100     command_line->AppendSwitchASCII(chromeos::switches::kLoginUser,
1101                                     kTestAccounts[DUMMY_ACCOUNT_INDEX].email);
1102     command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile,
1103                                     kTestAccounts[DUMMY_ACCOUNT_INDEX].hash);
1104   }
1105
1106   // Logs in to the primary profile of this test.
1107   virtual void SetUpOnMainThread() OVERRIDE {
1108     const TestAccountInfo& info = kTestAccounts[PRIMARY_ACCOUNT_INDEX];
1109
1110     AddUser(info, true);
1111     FileManagerBrowserTestBase::SetUpOnMainThread();
1112   }
1113
1114   // Loads all users to the current session and sets up necessary fields.
1115   // This is used for preparing all accounts in PRE_ test setup, and for testing
1116   // actual login behavior.
1117   void AddAllUsers() {
1118     for (size_t i = 0; i < arraysize(kTestAccounts); ++i)
1119       AddUser(kTestAccounts[i], i >= SECONDARY_ACCOUNT_INDEX_START);
1120   }
1121
1122   // Returns primary profile (if it is already created.)
1123   virtual Profile* profile() OVERRIDE {
1124     Profile* const profile = chromeos::ProfileHelper::GetProfileByUserIdHash(
1125         kTestAccounts[PRIMARY_ACCOUNT_INDEX].hash);
1126     return profile ? profile : FileManagerBrowserTestBase::profile();
1127   }
1128
1129   // Sets the test case name (used as a function name in test_cases.js to call.)
1130   void set_test_case_name(const std::string& name) { test_case_name_ = name; }
1131
1132   // Adds a new user for testing to the current session.
1133   void AddUser(const TestAccountInfo& info, bool log_in) {
1134     user_manager::UserManager* const user_manager =
1135         user_manager::UserManager::Get();
1136     if (log_in)
1137       user_manager->UserLoggedIn(info.email, info.hash, false);
1138     user_manager->SaveUserDisplayName(info.email,
1139                                       base::UTF8ToUTF16(info.display_name));
1140     chromeos::ProfileHelper::GetProfileByUserIdHash(info.hash)->GetPrefs()->
1141         SetString(prefs::kGoogleServicesUsername, info.email);
1142   }
1143
1144  private:
1145   virtual GuestMode GetGuestModeParam() const OVERRIDE {
1146     return NOT_IN_GUEST_MODE;
1147   }
1148
1149   virtual const char* GetTestCaseNameParam() const OVERRIDE {
1150     return test_case_name_.c_str();
1151   }
1152
1153   virtual std::string OnMessage(const std::string& name,
1154                                 const base::Value* value) OVERRIDE {
1155     if (name == "addAllUsers") {
1156       AddAllUsers();
1157       return "true";
1158     } else if (name == "getWindowOwnerId") {
1159       chrome::MultiUserWindowManager* const window_manager =
1160           chrome::MultiUserWindowManager::GetInstance();
1161       apps::AppWindowRegistry* const app_window_registry =
1162           apps::AppWindowRegistry::Get(profile());
1163       DCHECK(window_manager);
1164       DCHECK(app_window_registry);
1165
1166       const apps::AppWindowRegistry::AppWindowList& list =
1167           app_window_registry->GetAppWindowsForApp(
1168               file_manager::kFileManagerAppId);
1169       return list.size() == 1u ?
1170           window_manager->GetUserPresentingWindow(
1171               list.front()->GetNativeWindow()) : "";
1172     }
1173     return FileManagerBrowserTestBase::OnMessage(name, value);
1174   }
1175
1176   std::string test_case_name_;
1177 };
1178
1179 // Slow tests are disabled on debug build. http://crbug.com/327719
1180 #if !defined(NDEBUG)
1181 #define MAYBE_PRE_BasicDownloads DISABLED_PRE_BasicDownloads
1182 #define MAYBE_BasicDownloads DISABLED_BasicDownloads
1183 #else
1184 #define MAYBE_PRE_BasicDownloads PRE_BasicDownloads
1185 #define MAYBE_BasicDownloads BasicDownloads
1186 #endif
1187 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
1188                        MAYBE_PRE_BasicDownloads) {
1189   AddAllUsers();
1190 }
1191
1192 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
1193                        MAYBE_BasicDownloads) {
1194   AddAllUsers();
1195
1196   // Sanity check that normal operations work in multi-profile setting as well.
1197   set_test_case_name("keyboardCopyDownloads");
1198   StartTest();
1199 }
1200
1201 // Slow tests are disabled on debug build. http://crbug.com/327719
1202 #if !defined(NDEBUG)
1203 #define MAYBE_PRE_BasicDrive DISABLED_PRE_BasicDrive
1204 #define MAYBE_BasicDrive DISABLED_BasicDrive
1205 #else
1206 #define MAYBE_PRE_BasicDrive PRE_BasicDrive
1207 #define MAYBE_BasicDrive BasicDrive
1208 #endif
1209 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
1210                        MAYBE_PRE_BasicDrive) {
1211   AddAllUsers();
1212 }
1213
1214 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, MAYBE_BasicDrive) {
1215   AddAllUsers();
1216
1217   // Sanity check that normal operations work in multi-profile setting as well.
1218   set_test_case_name("keyboardCopyDrive");
1219   StartTest();
1220 }
1221
1222 // Slow tests are disabled on debug build. http://crbug.com/327719
1223 #if !defined(NDEBUG)
1224 #define MAYBE_PRE_Badge DISABLED_PRE_Badge
1225 #define MAYBE_Badge DISABLED_Badge
1226 #else
1227 #define MAYBE_PRE_Badge PRE_Badge
1228 #define MAYBE_Badge Badge
1229 #endif
1230 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, MAYBE_PRE_Badge) {
1231   AddAllUsers();
1232 }
1233
1234 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, MAYBE_Badge) {
1235   // Test the profile badge to be correctly shown and hidden.
1236   set_test_case_name("multiProfileBadge");
1237   StartTest();
1238 }
1239
1240 // Slow tests are disabled on debug build. http://crbug.com/327719
1241 #if !defined(NDEBUG)
1242 #define MAYBE_PRE_VisitDesktopMenu DISABLED_PRE_VisitDesktopMenu
1243 #define MAYBE_VisitDesktopMenu DISABLED_VisitDesktopMenu
1244 #else
1245 #define MAYBE_PRE_VisitDesktopMenu PRE_VisitDesktopMenu
1246 #define MAYBE_VisitDesktopMenu VisitDesktopMenu
1247 #endif
1248 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
1249                        MAYBE_PRE_VisitDesktopMenu) {
1250   AddAllUsers();
1251 }
1252
1253 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
1254                        MAYBE_VisitDesktopMenu) {
1255   // Test for the menu item for visiting other profile's desktop.
1256   set_test_case_name("multiProfileVisitDesktopMenu");
1257   StartTest();
1258 }
1259
1260 template<GuestMode M>
1261 class GalleryBrowserTestBase : public FileManagerBrowserTestBase {
1262  public:
1263   virtual GuestMode GetGuestModeParam() const OVERRIDE { return M; }
1264   virtual const char* GetTestCaseNameParam() const OVERRIDE {
1265     return test_case_name_.c_str();
1266   }
1267
1268  protected:
1269   virtual void SetUp() OVERRIDE {
1270     AddScript("gallery/test_util.js");
1271     FileManagerBrowserTestBase::SetUp();
1272   }
1273
1274   virtual std::string OnMessage(const std::string& name,
1275                                 const base::Value* value) OVERRIDE;
1276
1277   virtual const char* GetTestManifestName() const OVERRIDE {
1278     return "gallery_test_manifest.json";
1279   }
1280
1281   void AddScript(const std::string& name) {
1282     scripts_.AppendString(
1283         "chrome-extension://ejhcmmdhhpdhhgmifplfmjobgegbibkn/" + name);
1284   }
1285
1286   void set_test_case_name(const std::string& name) {
1287     test_case_name_ = name;
1288   }
1289
1290  private:
1291   base::ListValue scripts_;
1292   std::string test_case_name_;
1293 };
1294
1295 template<GuestMode M>
1296 std::string GalleryBrowserTestBase<M>::OnMessage(const std::string& name,
1297                                                  const base::Value* value) {
1298   if (name == "getScripts") {
1299     std::string jsonString;
1300     base::JSONWriter::Write(&scripts_, &jsonString);
1301     return jsonString;
1302   }
1303   return FileManagerBrowserTestBase::OnMessage(name, value);
1304 }
1305
1306 typedef GalleryBrowserTestBase<NOT_IN_GUEST_MODE> GalleryBrowserTest;
1307 typedef GalleryBrowserTestBase<IN_GUEST_MODE> GalleryBrowserTestInGuestMode;
1308
1309 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, OpenSingleImageOnDownloads) {
1310   AddScript("gallery/open_image_files.js");
1311   set_test_case_name("openSingleImageOnDownloads");
1312   StartTest();
1313 }
1314
1315 IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1316                        OpenSingleImageOnDownloads) {
1317   AddScript("gallery/open_image_files.js");
1318   set_test_case_name("openSingleImageOnDownloads");
1319   StartTest();
1320 }
1321
1322 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, OpenSingleImageOnDrive) {
1323   AddScript("gallery/open_image_files.js");
1324   set_test_case_name("openSingleImageOnDrive");
1325   StartTest();
1326 }
1327
1328 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, OpenMultipleImagesOnDownloads) {
1329   AddScript("gallery/open_image_files.js");
1330   set_test_case_name("openMultipleImagesOnDownloads");
1331   StartTest();
1332 }
1333
1334 IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1335                        OpenMultipleImagesOnDownloads) {
1336   AddScript("gallery/open_image_files.js");
1337   set_test_case_name("openMultipleImagesOnDownloads");
1338   StartTest();
1339 }
1340
1341 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, OpenMultipleImagesOnDrive) {
1342   AddScript("gallery/open_image_files.js");
1343   set_test_case_name("openMultipleImagesOnDrive");
1344   StartTest();
1345 }
1346
1347 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, TraverseSlideImagesOnDownloads) {
1348   AddScript("gallery/slide_mode.js");
1349   set_test_case_name("traverseSlideImagesOnDownloads");
1350   StartTest();
1351 }
1352
1353 IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1354                        TraverseSlideImagesOnDownloads) {
1355   AddScript("gallery/slide_mode.js");
1356   set_test_case_name("traverseSlideImagesOnDownloads");
1357   StartTest();
1358 }
1359
1360 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, TraverseSlideImagesOnDrive) {
1361   AddScript("gallery/slide_mode.js");
1362   set_test_case_name("traverseSlideImagesOnDrive");
1363   StartTest();
1364 }
1365
1366 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, RenameImageOnDownloads) {
1367   AddScript("gallery/slide_mode.js");
1368   set_test_case_name("renameImageOnDownloads");
1369   StartTest();
1370 }
1371
1372 IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1373                        RenameImageOnDownloads) {
1374   AddScript("gallery/slide_mode.js");
1375   set_test_case_name("renameImageOnDownloads");
1376   StartTest();
1377 }
1378
1379 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, RenameImageOnDrive) {
1380   AddScript("gallery/slide_mode.js");
1381   set_test_case_name("renameImageOnDrive");
1382   StartTest();
1383 }
1384
1385 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, DeleteImageOnDownloads) {
1386   AddScript("gallery/slide_mode.js");
1387   set_test_case_name("deleteImageOnDownloads");
1388   StartTest();
1389 }
1390
1391 IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1392                        DeleteImageOnDownloads) {
1393   AddScript("gallery/slide_mode.js");
1394   set_test_case_name("deleteImageOnDownloads");
1395   StartTest();
1396 }
1397
1398 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, DeleteImageOnDrive) {
1399   AddScript("gallery/slide_mode.js");
1400   set_test_case_name("deleteImageOnDrive");
1401   StartTest();
1402 }
1403
1404 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, RotateImageOnDownloads) {
1405   AddScript("gallery/photo_editor.js");
1406   set_test_case_name("rotateImageOnDownloads");
1407   StartTest();
1408 }
1409
1410 IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1411                        RotateImageOnDownloads) {
1412   AddScript("gallery/photo_editor.js");
1413   set_test_case_name("rotateImageOnDownloads");
1414   StartTest();
1415 }
1416
1417 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, RotateImageOnDrive) {
1418   AddScript("gallery/photo_editor.js");
1419   set_test_case_name("rotateImageOnDrive");
1420   StartTest();
1421 }
1422
1423 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, CropImageOnDownloads) {
1424   AddScript("gallery/photo_editor.js");
1425   set_test_case_name("cropImageOnDownloads");
1426   StartTest();
1427 }
1428
1429 IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1430                        CropImageOnDownloads) {
1431   AddScript("gallery/photo_editor.js");
1432   set_test_case_name("cropImageOnDownloads");
1433   StartTest();
1434 }
1435
1436 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, CropImageOnDrive) {
1437   AddScript("gallery/photo_editor.js");
1438   set_test_case_name("cropImageOnDrive");
1439   StartTest();
1440 }
1441
1442 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, ExposureImageOnDownloads) {
1443   AddScript("gallery/photo_editor.js");
1444   set_test_case_name("exposureImageOnDownloads");
1445   StartTest();
1446 }
1447
1448 IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1449                        ExposureImageOnDownloads) {
1450   AddScript("gallery/photo_editor.js");
1451   set_test_case_name("exposureImageOnDownloads");
1452   StartTest();
1453 }
1454
1455 IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, ExposureImageOnDrive) {
1456   AddScript("gallery/photo_editor.js");
1457   set_test_case_name("exposureImageOnDrive");
1458   StartTest();
1459 }
1460
1461 }  // namespace
1462 }  // namespace file_manager