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
54using drive::DriveIntegrationServiceFactory;
55
56namespace file_manager {
57namespace {
58
59enum EntryType {
60  FILE,
61  DIRECTORY,
62};
63
64enum TargetVolume { LOCAL_VOLUME, DRIVE_VOLUME, USB_VOLUME, };
65
66enum SharedOption {
67  NONE,
68  SHARED,
69};
70
71enum 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.
78std::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.
84bool 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.
95bool 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.
107bool 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.
121bool 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.
126struct 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
156void 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.
174struct 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
187void 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.
198class 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.
219class 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
275class 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.
288class 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.
341class 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.
478class 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.
528class 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
566void 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
581void 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
596void 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
608void 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
619void 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
649std::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
727drive::DriveIntegrationService*
728FileManagerBrowserTestBase::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.
736typedef std::tr1::tuple<GuestMode, const char*> TestParameter;
737
738// Test fixture class for normal (not multi-profile related) tests.
739class 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
750IN_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
770WRAPPED_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
779WRAPPED_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
792WRAPPED_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
805WRAPPED_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
819WRAPPED_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
837WRAPPED_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
857WRAPPED_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
872WRAPPED_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
891WRAPPED_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
905WRAPPED_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
917WRAPPED_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
929WRAPPED_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
942WRAPPED_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
954WRAPPED_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
967INSTANTIATE_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
979WRAPPED_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
993WRAPPED_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
1000INSTANTIATE_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
1011WRAPPED_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
1022WRAPPED_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
1042WRAPPED_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
1059WRAPPED_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.
1067struct TestAccountInfo {
1068  const char* const email;
1069  const char* const hash;
1070  const char* const display_name;
1071};
1072
1073enum {
1074  DUMMY_ACCOUNT_INDEX = 0,
1075  PRIMARY_ACCOUNT_INDEX = 1,
1076  SECONDARY_ACCOUNT_INDEX_START = 2,
1077};
1078
1079static const TestAccountInfo kTestAccounts[] = {
1080  {"__dummy__@invalid.domain", "hashdummy", "Dummy Account"},
1081  {"alice@invalid.domain", "hashalice", "Alice"},
1082  {"bob@invalid.domain", "hashbob", "Bob"},
1083  {"charlie@invalid.domain", "hashcharlie", "Charlie"},
1084};
1085
1086// Test fixture class for testing multi-profile features.
1087class 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
1182IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
1183                       MAYBE_PRE_BasicDownloads) {
1184  AddAllUsers();
1185}
1186
1187IN_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
1204IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
1205                       MAYBE_PRE_BasicDrive) {
1206  AddAllUsers();
1207}
1208
1209IN_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
1217template<GuestMode M>
1218class 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
1253template<GuestMode M>
1254std::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
1264typedef GalleryBrowserTestBase<NOT_IN_GUEST_MODE> GalleryBrowserTest;
1265typedef GalleryBrowserTestBase<IN_GUEST_MODE> GalleryBrowserTestInGuestMode;
1266
1267IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, OpenSingleImageOnDownloads) {
1268  AddScript("gallery/open_image_files.js");
1269  set_test_case_name("openSingleImageOnDownloads");
1270  StartTest();
1271}
1272
1273IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1274                       OpenSingleImageOnDownloads) {
1275  AddScript("gallery/open_image_files.js");
1276  set_test_case_name("openSingleImageOnDownloads");
1277  StartTest();
1278}
1279
1280IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, OpenSingleImageOnDrive) {
1281  AddScript("gallery/open_image_files.js");
1282  set_test_case_name("openSingleImageOnDrive");
1283  StartTest();
1284}
1285
1286IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, OpenMultipleImagesOnDownloads) {
1287  AddScript("gallery/open_image_files.js");
1288  set_test_case_name("openMultipleImagesOnDownloads");
1289  StartTest();
1290}
1291
1292IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1293                       OpenMultipleImagesOnDownloads) {
1294  AddScript("gallery/open_image_files.js");
1295  set_test_case_name("openMultipleImagesOnDownloads");
1296  StartTest();
1297}
1298
1299IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, OpenMultipleImagesOnDrive) {
1300  AddScript("gallery/open_image_files.js");
1301  set_test_case_name("openMultipleImagesOnDrive");
1302  StartTest();
1303}
1304
1305IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, TraverseSlideImagesOnDownloads) {
1306  AddScript("gallery/slide_mode.js");
1307  set_test_case_name("traverseSlideImagesOnDownloads");
1308  StartTest();
1309}
1310
1311IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1312                       TraverseSlideImagesOnDownloads) {
1313  AddScript("gallery/slide_mode.js");
1314  set_test_case_name("traverseSlideImagesOnDownloads");
1315  StartTest();
1316}
1317
1318IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, TraverseSlideImagesOnDrive) {
1319  AddScript("gallery/slide_mode.js");
1320  set_test_case_name("traverseSlideImagesOnDrive");
1321  StartTest();
1322}
1323
1324IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, RenameImageOnDownloads) {
1325  AddScript("gallery/slide_mode.js");
1326  set_test_case_name("renameImageOnDownloads");
1327  StartTest();
1328}
1329
1330IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1331                       RenameImageOnDownloads) {
1332  AddScript("gallery/slide_mode.js");
1333  set_test_case_name("renameImageOnDownloads");
1334  StartTest();
1335}
1336
1337IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, RenameImageOnDrive) {
1338  AddScript("gallery/slide_mode.js");
1339  set_test_case_name("renameImageOnDrive");
1340  StartTest();
1341}
1342
1343IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, DeleteImageOnDownloads) {
1344  AddScript("gallery/slide_mode.js");
1345  set_test_case_name("deleteImageOnDownloads");
1346  StartTest();
1347}
1348
1349IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1350                       DeleteImageOnDownloads) {
1351  AddScript("gallery/slide_mode.js");
1352  set_test_case_name("deleteImageOnDownloads");
1353  StartTest();
1354}
1355
1356IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, DeleteImageOnDrive) {
1357  AddScript("gallery/slide_mode.js");
1358  set_test_case_name("deleteImageOnDrive");
1359  StartTest();
1360}
1361
1362IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, RotateImageOnDownloads) {
1363  AddScript("gallery/photo_editor.js");
1364  set_test_case_name("rotateImageOnDownloads");
1365  StartTest();
1366}
1367
1368IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1369                       RotateImageOnDownloads) {
1370  AddScript("gallery/photo_editor.js");
1371  set_test_case_name("rotateImageOnDownloads");
1372  StartTest();
1373}
1374
1375IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, RotateImageOnDrive) {
1376  AddScript("gallery/photo_editor.js");
1377  set_test_case_name("rotateImageOnDrive");
1378  StartTest();
1379}
1380
1381IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, CropImageOnDownloads) {
1382  AddScript("gallery/photo_editor.js");
1383  set_test_case_name("cropImageOnDownloads");
1384  StartTest();
1385}
1386
1387IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1388                       CropImageOnDownloads) {
1389  AddScript("gallery/photo_editor.js");
1390  set_test_case_name("cropImageOnDownloads");
1391  StartTest();
1392}
1393
1394IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, CropImageOnDrive) {
1395  AddScript("gallery/photo_editor.js");
1396  set_test_case_name("cropImageOnDrive");
1397  StartTest();
1398}
1399
1400IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, ExposureImageOnDownloads) {
1401  AddScript("gallery/photo_editor.js");
1402  set_test_case_name("exposureImageOnDownloads");
1403  StartTest();
1404}
1405
1406IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1407                       ExposureImageOnDownloads) {
1408  AddScript("gallery/photo_editor.js");
1409  set_test_case_name("exposureImageOnDownloads");
1410  StartTest();
1411}
1412
1413IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, ExposureImageOnDrive) {
1414  AddScript("gallery/photo_editor.js");
1415  set_test_case_name("exposureImageOnDrive");
1416  StartTest();
1417}
1418
1419template<GuestMode M>
1420class 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
1461template<GuestMode M>
1462std::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
1472typedef VideoPlayerBrowserTestBase<NOT_IN_GUEST_MODE> VideoPlayerBrowserTest;
1473typedef VideoPlayerBrowserTestBase<IN_GUEST_MODE>
1474    VideoPlayerBrowserTestInGuestMode;
1475
1476IN_PROC_BROWSER_TEST_F(VideoPlayerBrowserTest, OpenSingleVideoOnDownloads) {
1477  AddScript("video_player/open_video_files.js");
1478  set_test_case_name("openSingleVideoOnDownloads");
1479  StartTest();
1480}
1481
1482IN_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