file_manager_browsertest.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
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
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    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.
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// 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
824WRAPPED_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
842WRAPPED_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
862WRAPPED_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
877WRAPPED_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
896WRAPPED_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
910WRAPPED_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
922WRAPPED_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
934WRAPPED_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
947WRAPPED_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
959WRAPPED_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
972INSTANTIATE_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
984WRAPPED_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
998WRAPPED_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
1005INSTANTIATE_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
1016WRAPPED_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
1027WRAPPED_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
1047WRAPPED_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
1064WRAPPED_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.
1072struct TestAccountInfo {
1073  const char* const email;
1074  const char* const hash;
1075  const char* const display_name;
1076};
1077
1078enum {
1079  DUMMY_ACCOUNT_INDEX = 0,
1080  PRIMARY_ACCOUNT_INDEX = 1,
1081  SECONDARY_ACCOUNT_INDEX_START = 2,
1082};
1083
1084static 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.
1092class 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
1187IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
1188                       MAYBE_PRE_BasicDownloads) {
1189  AddAllUsers();
1190}
1191
1192IN_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
1209IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
1210                       MAYBE_PRE_BasicDrive) {
1211  AddAllUsers();
1212}
1213
1214IN_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
1230IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, MAYBE_PRE_Badge) {
1231  AddAllUsers();
1232}
1233
1234IN_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
1248IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
1249                       MAYBE_PRE_VisitDesktopMenu) {
1250  AddAllUsers();
1251}
1252
1253IN_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
1260template<GuestMode M>
1261class 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
1295template<GuestMode M>
1296std::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
1306typedef GalleryBrowserTestBase<NOT_IN_GUEST_MODE> GalleryBrowserTest;
1307typedef GalleryBrowserTestBase<IN_GUEST_MODE> GalleryBrowserTestInGuestMode;
1308
1309IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, OpenSingleImageOnDownloads) {
1310  AddScript("gallery/open_image_files.js");
1311  set_test_case_name("openSingleImageOnDownloads");
1312  StartTest();
1313}
1314
1315IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1316                       OpenSingleImageOnDownloads) {
1317  AddScript("gallery/open_image_files.js");
1318  set_test_case_name("openSingleImageOnDownloads");
1319  StartTest();
1320}
1321
1322IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, OpenSingleImageOnDrive) {
1323  AddScript("gallery/open_image_files.js");
1324  set_test_case_name("openSingleImageOnDrive");
1325  StartTest();
1326}
1327
1328IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, OpenMultipleImagesOnDownloads) {
1329  AddScript("gallery/open_image_files.js");
1330  set_test_case_name("openMultipleImagesOnDownloads");
1331  StartTest();
1332}
1333
1334IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1335                       OpenMultipleImagesOnDownloads) {
1336  AddScript("gallery/open_image_files.js");
1337  set_test_case_name("openMultipleImagesOnDownloads");
1338  StartTest();
1339}
1340
1341IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, OpenMultipleImagesOnDrive) {
1342  AddScript("gallery/open_image_files.js");
1343  set_test_case_name("openMultipleImagesOnDrive");
1344  StartTest();
1345}
1346
1347IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, TraverseSlideImagesOnDownloads) {
1348  AddScript("gallery/slide_mode.js");
1349  set_test_case_name("traverseSlideImagesOnDownloads");
1350  StartTest();
1351}
1352
1353IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1354                       TraverseSlideImagesOnDownloads) {
1355  AddScript("gallery/slide_mode.js");
1356  set_test_case_name("traverseSlideImagesOnDownloads");
1357  StartTest();
1358}
1359
1360IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, TraverseSlideImagesOnDrive) {
1361  AddScript("gallery/slide_mode.js");
1362  set_test_case_name("traverseSlideImagesOnDrive");
1363  StartTest();
1364}
1365
1366IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, RenameImageOnDownloads) {
1367  AddScript("gallery/slide_mode.js");
1368  set_test_case_name("renameImageOnDownloads");
1369  StartTest();
1370}
1371
1372IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1373                       RenameImageOnDownloads) {
1374  AddScript("gallery/slide_mode.js");
1375  set_test_case_name("renameImageOnDownloads");
1376  StartTest();
1377}
1378
1379IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, RenameImageOnDrive) {
1380  AddScript("gallery/slide_mode.js");
1381  set_test_case_name("renameImageOnDrive");
1382  StartTest();
1383}
1384
1385IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, DeleteImageOnDownloads) {
1386  AddScript("gallery/slide_mode.js");
1387  set_test_case_name("deleteImageOnDownloads");
1388  StartTest();
1389}
1390
1391IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1392                       DeleteImageOnDownloads) {
1393  AddScript("gallery/slide_mode.js");
1394  set_test_case_name("deleteImageOnDownloads");
1395  StartTest();
1396}
1397
1398IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, DeleteImageOnDrive) {
1399  AddScript("gallery/slide_mode.js");
1400  set_test_case_name("deleteImageOnDrive");
1401  StartTest();
1402}
1403
1404IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, RotateImageOnDownloads) {
1405  AddScript("gallery/photo_editor.js");
1406  set_test_case_name("rotateImageOnDownloads");
1407  StartTest();
1408}
1409
1410IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1411                       RotateImageOnDownloads) {
1412  AddScript("gallery/photo_editor.js");
1413  set_test_case_name("rotateImageOnDownloads");
1414  StartTest();
1415}
1416
1417IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, RotateImageOnDrive) {
1418  AddScript("gallery/photo_editor.js");
1419  set_test_case_name("rotateImageOnDrive");
1420  StartTest();
1421}
1422
1423IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, CropImageOnDownloads) {
1424  AddScript("gallery/photo_editor.js");
1425  set_test_case_name("cropImageOnDownloads");
1426  StartTest();
1427}
1428
1429IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1430                       CropImageOnDownloads) {
1431  AddScript("gallery/photo_editor.js");
1432  set_test_case_name("cropImageOnDownloads");
1433  StartTest();
1434}
1435
1436IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, CropImageOnDrive) {
1437  AddScript("gallery/photo_editor.js");
1438  set_test_case_name("cropImageOnDrive");
1439  StartTest();
1440}
1441
1442IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, ExposureImageOnDownloads) {
1443  AddScript("gallery/photo_editor.js");
1444  set_test_case_name("exposureImageOnDownloads");
1445  StartTest();
1446}
1447
1448IN_PROC_BROWSER_TEST_F(GalleryBrowserTestInGuestMode,
1449                       ExposureImageOnDownloads) {
1450  AddScript("gallery/photo_editor.js");
1451  set_test_case_name("exposureImageOnDownloads");
1452  StartTest();
1453}
1454
1455IN_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
1463