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.
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
8 // - Selecting a file and copy-pasting it with the keyboard copies the file.
9 // - Selecting a file and pressing delete deletes it.
14 #include "apps/app_window.h"
15 #include "apps/app_window_registry.h"
16 #include "ash/session/session_state_delegate.h"
17 #include "ash/shell.h"
18 #include "base/bind.h"
19 #include "base/callback.h"
20 #include "base/file_util.h"
21 #include "base/files/file_path.h"
22 #include "base/json/json_reader.h"
23 #include "base/json/json_value_converter.h"
24 #include "base/json/json_writer.h"
25 #include "base/prefs/pref_service.h"
26 #include "base/strings/string_piece.h"
27 #include "base/strings/stringprintf.h"
28 #include "base/strings/utf_string_conversions.h"
29 #include "base/time/time.h"
30 #include "chrome/browser/browser_process.h"
31 #include "chrome/browser/chrome_notification_types.h"
32 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
33 #include "chrome/browser/chromeos/drive/file_system_interface.h"
34 #include "chrome/browser/chromeos/drive/test_util.h"
35 #include "chrome/browser/chromeos/file_manager/app_id.h"
36 #include "chrome/browser/chromeos/file_manager/drive_test_util.h"
37 #include "chrome/browser/chromeos/file_manager/path_util.h"
38 #include "chrome/browser/chromeos/file_manager/volume_manager.h"
39 #include "chrome/browser/chromeos/login/user_manager.h"
40 #include "chrome/browser/chromeos/profiles/profile_helper.h"
41 #include "chrome/browser/drive/fake_drive_service.h"
42 #include "chrome/browser/extensions/component_loader.h"
43 #include "chrome/browser/extensions/extension_apitest.h"
44 #include "chrome/browser/extensions/extension_test_message_listener.h"
45 #include "chrome/browser/profiles/profile.h"
46 #include "chrome/browser/profiles/profile_manager.h"
47 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
48 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
49 #include "chrome/common/chrome_switches.h"
50 #include "chrome/common/pref_names.h"
51 #include "chromeos/chromeos_switches.h"
52 #include "content/public/browser/browser_context.h"
53 #include "content/public/browser/notification_service.h"
54 #include "content/public/test/test_utils.h"
55 #include "extensions/browser/api/test/test_api.h"
56 #include "extensions/common/extension.h"
57 #include "google_apis/drive/gdata_wapi_parser.h"
58 #include "google_apis/drive/test_util.h"
59 #include "net/test/embedded_test_server/embedded_test_server.h"
60 #include "webkit/browser/fileapi/external_mount_points.h"
62 using drive::DriveIntegrationServiceFactory;
64 namespace file_manager {
72 enum TargetVolume { LOCAL_VOLUME, DRIVE_VOLUME, USB_VOLUME, };
84 // This global operator is used from Google Test to format error messages.
85 std::ostream& operator<<(std::ostream& os, const GuestMode& guest_mode) {
86 return os << (guest_mode == IN_GUEST_MODE ?
87 "IN_GUEST_MODE" : "NOT_IN_GUEST_MODE");
90 // Maps the given string to EntryType. Returns true on success.
91 bool MapStringToEntryType(const base::StringPiece& value, EntryType* output) {
94 else if (value == "directory")
101 // Maps the given string to SharedOption. Returns true on success.
102 bool MapStringToSharedOption(const base::StringPiece& value,
103 SharedOption* output) {
104 if (value == "shared")
106 else if (value == "none")
113 // Maps the given string to TargetVolume. Returns true on success.
114 bool MapStringToTargetVolume(const base::StringPiece& value,
115 TargetVolume* output) {
116 if (value == "drive")
117 *output = DRIVE_VOLUME;
118 else if (value == "local")
119 *output = LOCAL_VOLUME;
120 else if (value == "usb")
121 *output = USB_VOLUME;
127 // Maps the given string to base::Time. Returns true on success.
128 bool MapStringToTime(const base::StringPiece& value, base::Time* time) {
129 return base::Time::FromString(value.as_string().c_str(), time);
132 // Test data of file or directory.
133 struct TestEntryInfo {
134 TestEntryInfo() : type(FILE), shared_option(NONE) {}
136 TestEntryInfo(EntryType type,
137 const std::string& source_file_name,
138 const std::string& target_path,
139 const std::string& mime_type,
140 SharedOption shared_option,
141 const base::Time& last_modified_time) :
143 source_file_name(source_file_name),
144 target_path(target_path),
145 mime_type(mime_type),
146 shared_option(shared_option),
147 last_modified_time(last_modified_time) {
151 std::string source_file_name; // Source file name to be used as a prototype.
152 std::string target_path; // Target file or directory path.
153 std::string mime_type;
154 SharedOption shared_option;
155 base::Time last_modified_time;
157 // Registers the member information to the given converter.
158 static void RegisterJSONConverter(
159 base::JSONValueConverter<TestEntryInfo>* converter);
163 void TestEntryInfo::RegisterJSONConverter(
164 base::JSONValueConverter<TestEntryInfo>* converter) {
165 converter->RegisterCustomField("type",
166 &TestEntryInfo::type,
167 &MapStringToEntryType);
168 converter->RegisterStringField("sourceFileName",
169 &TestEntryInfo::source_file_name);
170 converter->RegisterStringField("targetPath", &TestEntryInfo::target_path);
171 converter->RegisterStringField("mimeType", &TestEntryInfo::mime_type);
172 converter->RegisterCustomField("sharedOption",
173 &TestEntryInfo::shared_option,
174 &MapStringToSharedOption);
175 converter->RegisterCustomField("lastModifiedTime",
176 &TestEntryInfo::last_modified_time,
180 // Message from JavaScript to add entries.
181 struct AddEntriesMessage {
182 // Target volume to be added the |entries|.
185 // Entries to be added.
186 ScopedVector<TestEntryInfo> entries;
188 // Registers the member information to the given converter.
189 static void RegisterJSONConverter(
190 base::JSONValueConverter<AddEntriesMessage>* converter);
195 void AddEntriesMessage::RegisterJSONConverter(
196 base::JSONValueConverter<AddEntriesMessage>* converter) {
197 converter->RegisterCustomField("volume",
198 &AddEntriesMessage::volume,
199 &MapStringToTargetVolume);
200 converter->RegisterRepeatedMessage<TestEntryInfo>(
202 &AddEntriesMessage::entries);
208 explicit TestVolume(const std::string& name) : name_(name) {}
209 virtual ~TestVolume() {}
211 bool CreateRootDirectory(const Profile* profile) {
212 return root_.Set(profile->GetPath().Append(name_));
215 const std::string& name() { return name_; }
216 const base::FilePath root_path() { return root_.path(); }
220 base::ScopedTempDir root_;
223 // The local volume class for test.
224 // This class provides the operations for a test volume that simulates local
226 class LocalTestVolume : public TestVolume {
228 explicit LocalTestVolume(const std::string& name) : TestVolume(name) {}
229 virtual ~LocalTestVolume() {}
231 // Adds this volume to the file system as a local volume. Returns true on
233 virtual bool Mount(Profile* profile) = 0;
235 void CreateEntry(const TestEntryInfo& entry) {
236 const base::FilePath target_path =
237 root_path().AppendASCII(entry.target_path);
239 entries_.insert(std::make_pair(target_path, entry));
240 switch (entry.type) {
242 const base::FilePath source_path =
243 google_apis::test_util::GetTestFilePath("chromeos/file_manager").
244 AppendASCII(entry.source_file_name);
245 ASSERT_TRUE(base::CopyFile(source_path, target_path))
246 << "Copy from " << source_path.value()
247 << " to " << target_path.value() << " failed.";
251 ASSERT_TRUE(base::CreateDirectory(target_path)) <<
252 "Failed to create a directory: " << target_path.value();
255 ASSERT_TRUE(UpdateModifiedTime(entry));
259 // Updates ModifiedTime of the entry and its parents by referring
260 // TestEntryInfo. Returns true on success.
261 bool UpdateModifiedTime(const TestEntryInfo& entry) {
262 const base::FilePath path = root_path().AppendASCII(entry.target_path);
263 if (!base::TouchFile(path, entry.last_modified_time,
264 entry.last_modified_time))
267 // Update the modified time of parent directories because it may be also
268 // affected by the update of child items.
269 if (path.DirName() != root_path()) {
270 const std::map<base::FilePath, const TestEntryInfo>::iterator it =
271 entries_.find(path.DirName());
272 if (it == entries_.end())
274 return UpdateModifiedTime(it->second);
279 std::map<base::FilePath, const TestEntryInfo> entries_;
282 class DownloadsTestVolume : public LocalTestVolume {
284 DownloadsTestVolume() : LocalTestVolume("Downloads") {}
285 virtual ~DownloadsTestVolume() {}
287 virtual bool Mount(Profile* profile) OVERRIDE {
288 return CreateRootDirectory(profile) &&
289 VolumeManager::Get(profile)
290 ->RegisterDownloadsDirectoryForTesting(root_path());
294 class FakeUsbTestVolume : public LocalTestVolume {
296 FakeUsbTestVolume() : LocalTestVolume("fake-usb") {}
297 virtual ~FakeUsbTestVolume() {}
299 virtual bool Mount(Profile* profile) OVERRIDE {
300 if (!CreateRootDirectory(profile))
302 fileapi::ExternalMountPoints* const mount_points =
303 fileapi::ExternalMountPoints::GetSystemInstance();
305 // First revoke the existing mount point (if any).
306 mount_points->RevokeFileSystem(name());
308 mount_points->RegisterFileSystem(name(),
309 fileapi::kFileSystemTypeNativeLocal,
310 fileapi::FileSystemMountOption(),
315 VolumeManager::Get(profile)
316 ->AddVolumeInfoForTesting(root_path(),
317 VOLUME_TYPE_REMOVABLE_DISK_PARTITION,
318 chromeos::DEVICE_TYPE_USB);
323 // The drive volume class for test.
324 // This class provides the operations for a test volume that simulates Google
326 class DriveTestVolume : public TestVolume {
328 DriveTestVolume() : TestVolume("drive"), integration_service_(NULL) {}
329 virtual ~DriveTestVolume() {}
331 void CreateEntry(const TestEntryInfo& entry) {
332 const base::FilePath path =
333 base::FilePath::FromUTF8Unsafe(entry.target_path);
334 const std::string target_name = path.BaseName().AsUTF8Unsafe();
336 // Obtain the parent entry.
337 drive::FileError error = drive::FILE_ERROR_OK;
338 scoped_ptr<drive::ResourceEntry> parent_entry(new drive::ResourceEntry);
339 integration_service_->file_system()->GetResourceEntry(
340 drive::util::GetDriveMyDriveRootPath().Append(path).DirName(),
341 google_apis::test_util::CreateCopyResultCallback(
342 &error, &parent_entry));
343 drive::test_util::RunBlockingPoolTask();
344 ASSERT_EQ(drive::FILE_ERROR_OK, error);
345 ASSERT_TRUE(parent_entry);
347 switch (entry.type) {
349 CreateFile(entry.source_file_name,
350 parent_entry->resource_id(),
353 entry.shared_option == SHARED,
354 entry.last_modified_time);
358 parent_entry->resource_id(), target_name, entry.last_modified_time);
363 // Creates an empty directory with the given |name| and |modification_time|.
364 void CreateDirectory(const std::string& parent_id,
365 const std::string& target_name,
366 const base::Time& modification_time) {
367 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
368 scoped_ptr<google_apis::ResourceEntry> resource_entry;
369 fake_drive_service_->AddNewDirectory(
372 drive::DriveServiceInterface::AddNewDirectoryOptions(),
373 google_apis::test_util::CreateCopyResultCallback(&error,
375 base::MessageLoop::current()->RunUntilIdle();
376 ASSERT_EQ(google_apis::HTTP_CREATED, error);
377 ASSERT_TRUE(resource_entry);
379 fake_drive_service_->SetLastModifiedTime(
380 resource_entry->resource_id(),
382 google_apis::test_util::CreateCopyResultCallback(&error,
384 base::MessageLoop::current()->RunUntilIdle();
385 ASSERT_TRUE(error == google_apis::HTTP_SUCCESS);
386 ASSERT_TRUE(resource_entry);
390 // Creates a test file with the given spec.
391 // Serves |test_file_name| file. Pass an empty string for an empty file.
392 void CreateFile(const std::string& source_file_name,
393 const std::string& parent_id,
394 const std::string& target_name,
395 const std::string& mime_type,
397 const base::Time& modification_time) {
398 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
400 std::string content_data;
401 if (!source_file_name.empty()) {
402 base::FilePath source_file_path =
403 google_apis::test_util::GetTestFilePath("chromeos/file_manager").
404 AppendASCII(source_file_name);
405 ASSERT_TRUE(base::ReadFileToString(source_file_path, &content_data));
408 scoped_ptr<google_apis::ResourceEntry> resource_entry;
409 fake_drive_service_->AddNewFile(
415 google_apis::test_util::CreateCopyResultCallback(&error,
417 base::MessageLoop::current()->RunUntilIdle();
418 ASSERT_EQ(google_apis::HTTP_CREATED, error);
419 ASSERT_TRUE(resource_entry);
421 fake_drive_service_->SetLastModifiedTime(
422 resource_entry->resource_id(),
424 google_apis::test_util::CreateCopyResultCallback(&error,
426 base::MessageLoop::current()->RunUntilIdle();
427 ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
428 ASSERT_TRUE(resource_entry);
433 // Notifies FileSystem that the contents in FakeDriveService are
434 // changed, hence the new contents should be fetched.
435 void CheckForUpdates() {
436 if (integration_service_ && integration_service_->file_system()) {
437 integration_service_->file_system()->CheckForUpdates();
441 // Sets the url base for the test server to be used to generate share urls
442 // on the files and directories.
443 void ConfigureShareUrlBase(const GURL& share_url_base) {
444 fake_drive_service_->set_share_url_base(share_url_base);
447 drive::DriveIntegrationService* CreateDriveIntegrationService(
450 fake_drive_service_ = new drive::FakeDriveService;
451 fake_drive_service_->LoadAppListForDriveApi("drive/applist.json");
453 if (!CreateRootDirectory(profile))
455 integration_service_ = new drive::DriveIntegrationService(
456 profile, NULL, fake_drive_service_, std::string(), root_path(), NULL);
457 return integration_service_;
462 drive::FakeDriveService* fake_drive_service_;
463 drive::DriveIntegrationService* integration_service_;
466 // Listener to obtain the test relative messages synchronously.
467 class FileManagerTestListener : public content::NotificationObserver {
472 scoped_refptr<extensions::TestSendMessageFunction> function;
475 FileManagerTestListener() {
477 chrome::NOTIFICATION_EXTENSION_TEST_PASSED,
478 content::NotificationService::AllSources());
480 chrome::NOTIFICATION_EXTENSION_TEST_FAILED,
481 content::NotificationService::AllSources());
483 chrome::NOTIFICATION_EXTENSION_TEST_MESSAGE,
484 content::NotificationService::AllSources());
487 Message GetNextMessage() {
488 if (messages_.empty())
489 content::RunMessageLoop();
490 const Message entry = messages_.front();
491 messages_.pop_front();
495 virtual void Observe(int type,
496 const content::NotificationSource& source,
497 const content::NotificationDetails& details) OVERRIDE {
500 entry.message = type != chrome::NOTIFICATION_EXTENSION_TEST_PASSED ?
501 *content::Details<std::string>(details).ptr() :
503 entry.function = type == chrome::NOTIFICATION_EXTENSION_TEST_MESSAGE ?
504 content::Source<extensions::TestSendMessageFunction>(source).ptr() :
506 messages_.push_back(entry);
507 base::MessageLoopForUI::current()->Quit();
511 std::deque<Message> messages_;
512 content::NotificationRegistrar registrar_;
515 // The base test class.
516 class FileManagerBrowserTestBase : public ExtensionApiTest {
518 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE;
520 virtual void SetUpOnMainThread() OVERRIDE;
522 // Adds an incognito and guest-mode flags for tests in the guest mode.
523 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE;
525 // Loads our testing extension and sends it a string identifying the current
529 // Overriding point for test configurations.
530 virtual GuestMode GetGuestModeParam() const = 0;
531 virtual const char* GetTestCaseNameParam() const = 0;
532 virtual std::string OnMessage(const std::string& name,
533 const base::Value* value);
535 scoped_ptr<LocalTestVolume> local_volume_;
536 linked_ptr<DriveTestVolume> drive_volume_;
537 std::map<Profile*, linked_ptr<DriveTestVolume> > drive_volumes_;
538 scoped_ptr<LocalTestVolume> usb_volume_;
541 drive::DriveIntegrationService* CreateDriveIntegrationService(
543 DriveIntegrationServiceFactory::FactoryCallback
544 create_drive_integration_service_;
545 scoped_ptr<DriveIntegrationServiceFactory::ScopedFactoryForTest>
546 service_factory_for_test_;
549 void FileManagerBrowserTestBase::SetUpInProcessBrowserTestFixture() {
550 ExtensionApiTest::SetUpInProcessBrowserTestFixture();
551 extensions::ComponentLoader::EnableBackgroundExtensionsForTesting();
553 local_volume_.reset(new DownloadsTestVolume);
554 if (GetGuestModeParam() != IN_GUEST_MODE) {
555 create_drive_integration_service_ =
556 base::Bind(&FileManagerBrowserTestBase::CreateDriveIntegrationService,
557 base::Unretained(this));
558 service_factory_for_test_.reset(
559 new DriveIntegrationServiceFactory::ScopedFactoryForTest(
560 &create_drive_integration_service_));
564 void FileManagerBrowserTestBase::SetUpOnMainThread() {
565 ExtensionApiTest::SetUpOnMainThread();
566 ASSERT_TRUE(local_volume_->Mount(profile()));
568 if (GetGuestModeParam() != IN_GUEST_MODE) {
569 // Install the web server to serve the mocked share dialog.
570 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
571 const GURL share_url_base(embedded_test_server()->GetURL(
572 "/chromeos/file_manager/share_dialog_mock/index.html"));
573 drive_volume_ = drive_volumes_[profile()];
574 drive_volume_->ConfigureShareUrlBase(share_url_base);
575 test_util::WaitUntilDriveMountPointIsAdded(profile());
579 void FileManagerBrowserTestBase::SetUpCommandLine(CommandLine* command_line) {
580 if (GetGuestModeParam() == IN_GUEST_MODE) {
581 command_line->AppendSwitch(chromeos::switches::kGuestSession);
582 command_line->AppendSwitchNative(chromeos::switches::kLoginUser, "");
583 command_line->AppendSwitch(switches::kIncognito);
585 ExtensionApiTest::SetUpCommandLine(command_line);
588 void FileManagerBrowserTestBase::StartTest() {
589 // Launch the extension.
590 base::FilePath path = test_data_dir_.AppendASCII("file_manager_browsertest");
591 const extensions::Extension* extension = LoadExtensionAsComponent(path);
592 ASSERT_TRUE(extension);
594 // Handle the messages from JavaScript.
595 // The while loop is break when the test is passed or failed.
596 FileManagerTestListener listener;
598 FileManagerTestListener::Message entry = listener.GetNextMessage();
599 if (entry.type == chrome::NOTIFICATION_EXTENSION_TEST_PASSED) {
602 } else if (entry.type == chrome::NOTIFICATION_EXTENSION_TEST_FAILED) {
604 ADD_FAILURE() << entry.message;
608 // Parse the message value as JSON.
609 const scoped_ptr<const base::Value> value(
610 base::JSONReader::Read(entry.message));
612 // If the message is not the expected format, just ignore it.
613 const base::DictionaryValue* message_dictionary = NULL;
615 if (!value || !value->GetAsDictionary(&message_dictionary) ||
616 !message_dictionary->GetString("name", &name))
619 entry.function->Reply(OnMessage(name, value.get()));
623 std::string FileManagerBrowserTestBase::OnMessage(const std::string& name,
624 const base::Value* value) {
625 if (name == "getTestName") {
626 // Pass the test case name.
627 return GetTestCaseNameParam();
628 } else if (name == "getRootPaths") {
629 // Pass the root paths.
630 const scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue());
631 res->SetString("downloads",
632 "/" + util::GetDownloadsMountPointName(profile()));
633 res->SetString("drive",
634 "/" + drive::util::GetDriveMountPointPath(profile()
635 ).BaseName().AsUTF8Unsafe() + "/root");
636 std::string jsonString;
637 base::JSONWriter::Write(res.get(), &jsonString);
639 } else if (name == "isInGuestMode") {
640 // Obtain whether the test is in guest mode or not.
641 return GetGuestModeParam() ? "true" : "false";
642 } else if (name == "getCwsWidgetContainerMockUrl") {
643 // Obtain whether the test is in guest mode or not.
644 const GURL url = embedded_test_server()->GetURL(
645 "/chromeos/file_manager/cws_container_mock/index.html");
646 std::string origin = url.GetOrigin().spec();
648 // Removes trailing a slash.
649 if (*origin.rbegin() == '/')
650 origin.resize(origin.length() - 1);
652 const scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue());
653 res->SetString("url", url.spec());
654 res->SetString("origin", origin);
655 std::string jsonString;
656 base::JSONWriter::Write(res.get(), &jsonString);
658 } else if (name == "addEntries") {
659 // Add entries to the specified volume.
660 base::JSONValueConverter<AddEntriesMessage> add_entries_message_converter;
661 AddEntriesMessage message;
662 if (!add_entries_message_converter.Convert(*value, &message))
664 for (size_t i = 0; i < message.entries.size(); ++i) {
665 switch (message.volume) {
667 local_volume_->CreateEntry(*message.entries[i]);
670 if (drive_volume_.get())
671 drive_volume_->CreateEntry(*message.entries[i]);
675 usb_volume_->CreateEntry(*message.entries[i]);
682 return "onEntryAdded";
683 } else if (name == "mountFakeUsb") {
684 usb_volume_.reset(new FakeUsbTestVolume());
685 usb_volume_->Mount(profile());
688 return "unknownMessage";
691 drive::DriveIntegrationService*
692 FileManagerBrowserTestBase::CreateDriveIntegrationService(Profile* profile) {
693 drive_volumes_[profile].reset(new DriveTestVolume());
694 return drive_volumes_[profile]->CreateDriveIntegrationService(profile);
697 // Parameter of FileManagerBrowserTest.
698 // The second value is the case name of JavaScript.
699 typedef std::tr1::tuple<GuestMode, const char*> TestParameter;
701 // Test fixture class for normal (not multi-profile related) tests.
702 class FileManagerBrowserTest :
703 public FileManagerBrowserTestBase,
704 public ::testing::WithParamInterface<TestParameter> {
705 virtual GuestMode GetGuestModeParam() const OVERRIDE {
706 return std::tr1::get<0>(GetParam());
708 virtual const char* GetTestCaseNameParam() const OVERRIDE {
709 return std::tr1::get<1>(GetParam());
713 IN_PROC_BROWSER_TEST_P(FileManagerBrowserTest, Test) {
717 INSTANTIATE_TEST_CASE_P(
719 FileManagerBrowserTest,
720 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "fileDisplayDownloads"),
721 TestParameter(IN_GUEST_MODE, "fileDisplayDownloads"),
722 TestParameter(NOT_IN_GUEST_MODE, "fileDisplayDrive")));
724 INSTANTIATE_TEST_CASE_P(
726 FileManagerBrowserTest,
727 ::testing::Values(TestParameter(IN_GUEST_MODE, "galleryOpenDownloads"),
728 TestParameter(NOT_IN_GUEST_MODE, "galleryOpenDownloads"),
729 TestParameter(NOT_IN_GUEST_MODE, "galleryOpenDrive"),
730 TestParameter(IN_GUEST_MODE, "zipOpenDownloads"),
731 TestParameter(NOT_IN_GUEST_MODE, "zipOpenDownloads")));
732 // http://crbug.com/348008
733 // DISABLED TestParameter(NOT_IN_GUEST_MODE, "zipOpenDrive")));
735 INSTANTIATE_TEST_CASE_P(
737 FileManagerBrowserTest,
738 ::testing::Values(TestParameter(IN_GUEST_MODE, "videoOpenDownloads"),
739 TestParameter(NOT_IN_GUEST_MODE, "videoOpenDownloads"),
740 TestParameter(NOT_IN_GUEST_MODE, "videoOpenDrive")));
742 INSTANTIATE_TEST_CASE_P(
744 FileManagerBrowserTest,
746 TestParameter(IN_GUEST_MODE, "audioOpenDownloads"),
747 TestParameter(NOT_IN_GUEST_MODE, "audioOpenDownloads"),
748 TestParameter(NOT_IN_GUEST_MODE, "audioOpenDrive"),
749 TestParameter(NOT_IN_GUEST_MODE, "audioAutoAdvanceDrive"),
750 TestParameter(NOT_IN_GUEST_MODE, "audioRepeatSingleFileDrive"),
751 TestParameter(NOT_IN_GUEST_MODE, "audioNoRepeatSingleFileDrive"),
752 TestParameter(NOT_IN_GUEST_MODE, "audioRepeatMultipleFileDrive"),
753 TestParameter(NOT_IN_GUEST_MODE, "audioNoRepeatMultipleFileDrive")));
755 INSTANTIATE_TEST_CASE_P(
757 FileManagerBrowserTest,
758 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE,
759 "createNewFolderAfterSelectFile"),
760 TestParameter(IN_GUEST_MODE,
761 "createNewFolderDownloads"),
762 TestParameter(NOT_IN_GUEST_MODE,
763 "createNewFolderDownloads"),
764 TestParameter(NOT_IN_GUEST_MODE,
765 "createNewFolderDrive")));
767 INSTANTIATE_TEST_CASE_P(
769 FileManagerBrowserTest,
770 ::testing::Values(TestParameter(IN_GUEST_MODE, "keyboardDeleteDownloads"),
771 TestParameter(NOT_IN_GUEST_MODE,
772 "keyboardDeleteDownloads"),
773 TestParameter(NOT_IN_GUEST_MODE, "keyboardDeleteDrive"),
774 TestParameter(IN_GUEST_MODE, "keyboardCopyDownloads"),
775 TestParameter(NOT_IN_GUEST_MODE, "keyboardCopyDownloads"),
776 TestParameter(NOT_IN_GUEST_MODE, "keyboardCopyDrive"),
777 TestParameter(IN_GUEST_MODE,
778 "renameFileDownloads"),
779 TestParameter(NOT_IN_GUEST_MODE,
780 "renameFileDownloads"),
781 TestParameter(NOT_IN_GUEST_MODE,
782 "renameFileDrive")));
784 // Disabled due to frequent timeouts; http://crbug.com/370980.
785 INSTANTIATE_TEST_CASE_P(
786 DISABLED_DriveSpecific,
787 FileManagerBrowserTest,
788 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "openSidebarRecent"),
789 TestParameter(NOT_IN_GUEST_MODE, "openSidebarOffline"),
790 TestParameter(NOT_IN_GUEST_MODE,
791 "openSidebarSharedWithMe"),
792 TestParameter(NOT_IN_GUEST_MODE, "autocomplete")));
794 INSTANTIATE_TEST_CASE_P(
796 FileManagerBrowserTest,
797 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE,
798 "transferFromDriveToDownloads"),
799 TestParameter(NOT_IN_GUEST_MODE,
800 "transferFromDownloadsToDrive"),
801 TestParameter(NOT_IN_GUEST_MODE,
802 "transferFromSharedToDownloads"),
803 TestParameter(NOT_IN_GUEST_MODE,
804 "transferFromSharedToDrive"),
805 TestParameter(NOT_IN_GUEST_MODE,
806 "transferFromRecentToDownloads"),
807 TestParameter(NOT_IN_GUEST_MODE,
808 "transferFromRecentToDrive"),
809 TestParameter(NOT_IN_GUEST_MODE,
810 "transferFromOfflineToDownloads"),
811 TestParameter(NOT_IN_GUEST_MODE,
812 "transferFromOfflineToDrive")));
814 INSTANTIATE_TEST_CASE_P(
816 FileManagerBrowserTest,
817 ::testing::Values(TestParameter(IN_GUEST_MODE, "restoreSortColumn"),
818 TestParameter(NOT_IN_GUEST_MODE, "restoreSortColumn"),
819 TestParameter(IN_GUEST_MODE, "restoreCurrentView"),
820 TestParameter(NOT_IN_GUEST_MODE, "restoreCurrentView")));
822 INSTANTIATE_TEST_CASE_P(
824 FileManagerBrowserTest,
825 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "shareFile"),
826 TestParameter(NOT_IN_GUEST_MODE, "shareDirectory")));
828 INSTANTIATE_TEST_CASE_P(
830 FileManagerBrowserTest,
831 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "restoreGeometry"),
832 TestParameter(IN_GUEST_MODE, "restoreGeometry")));
834 INSTANTIATE_TEST_CASE_P(
836 FileManagerBrowserTest,
837 ::testing::Values(TestParameter(IN_GUEST_MODE, "traverseDownloads"),
838 TestParameter(NOT_IN_GUEST_MODE, "traverseDownloads"),
839 TestParameter(NOT_IN_GUEST_MODE, "traverseDrive")));
841 INSTANTIATE_TEST_CASE_P(
843 FileManagerBrowserTest,
844 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "suggestAppDialog")));
846 INSTANTIATE_TEST_CASE_P(
847 ExecuteDefaultTaskOnDownloads,
848 FileManagerBrowserTest,
850 TestParameter(NOT_IN_GUEST_MODE, "executeDefaultTaskOnDownloads"),
851 TestParameter(IN_GUEST_MODE, "executeDefaultTaskOnDownloads")));
853 INSTANTIATE_TEST_CASE_P(
854 ExecuteDefaultTaskOnDrive,
855 FileManagerBrowserTest,
857 TestParameter(NOT_IN_GUEST_MODE, "executeDefaultTaskOnDrive")));
859 INSTANTIATE_TEST_CASE_P(
861 FileManagerBrowserTest,
862 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE,
863 "traverseNavigationList")));
865 INSTANTIATE_TEST_CASE_P(
867 FileManagerBrowserTest,
868 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "searchBoxFocus")));
870 INSTANTIATE_TEST_CASE_P(
872 FileManagerBrowserTest,
873 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "thumbnailsDownloads"),
874 TestParameter(IN_GUEST_MODE, "thumbnailsDownloads")));
876 INSTANTIATE_TEST_CASE_P(
878 FileManagerBrowserTest,
880 TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsLocalToDrive"),
881 TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsLocalToUsb"),
882 TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsUsbToDrive")));
884 // Structure to describe an account info.
885 struct TestAccountInfo {
886 const char* const email;
887 const char* const hash;
888 const char* const display_name;
892 DUMMY_ACCOUNT_INDEX = 0,
893 PRIMARY_ACCOUNT_INDEX = 1,
894 SECONDARY_ACCOUNT_INDEX_START = 2,
897 static const TestAccountInfo kTestAccounts[] = {
898 {"__dummy__@invalid.domain", "hashdummy", "Dummy Account"},
899 {"alice@invalid.domain", "hashalice", "Alice"},
900 {"bob@invalid.domain", "hashbob", "Bob"},
901 {"charlie@invalid.domain", "hashcharlie", "Charlie"},
904 // Test fixture class for testing multi-profile features.
905 class MultiProfileFileManagerBrowserTest : public FileManagerBrowserTestBase {
907 // Enables multi-profiles.
908 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
909 FileManagerBrowserTestBase::SetUpCommandLine(command_line);
910 command_line->AppendSwitch(switches::kMultiProfiles);
911 // Logs in to a dummy profile (For making MultiProfileWindowManager happy;
912 // browser test creates a default window and the manager tries to assign a
913 // user for it, and we need a profile connected to a user.)
914 command_line->AppendSwitchASCII(chromeos::switches::kLoginUser,
915 kTestAccounts[DUMMY_ACCOUNT_INDEX].email);
916 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile,
917 kTestAccounts[DUMMY_ACCOUNT_INDEX].hash);
920 // Logs in to the primary profile of this test.
921 virtual void SetUpOnMainThread() OVERRIDE {
922 const TestAccountInfo& info = kTestAccounts[PRIMARY_ACCOUNT_INDEX];
925 FileManagerBrowserTestBase::SetUpOnMainThread();
928 // Loads all users to the current session and sets up necessary fields.
929 // This is used for preparing all accounts in PRE_ test setup, and for testing
930 // actual login behavior.
932 for (size_t i = 0; i < arraysize(kTestAccounts); ++i)
933 AddUser(kTestAccounts[i], i >= SECONDARY_ACCOUNT_INDEX_START);
936 // Add as many as users
937 void AddExtraUsersForStressTesting() {
938 ash::Shell* const shell = ash::Shell::GetInstance();
939 const size_t maxLogin =
940 shell->session_state_delegate()->GetMaximumNumberOfLoggedInUsers();
942 for (int i = 0; i + arraysize(kTestAccounts) < maxLogin; ++i) {
943 const std::string email = base::StringPrintf("user%d@invalid.domain", i);
944 const std::string hash = base::StringPrintf("hashuser%d", i);
945 const std::string name = base::StringPrintf("Additional User %d", i);
946 const TestAccountInfo info = {email.c_str(), hash.c_str(), name.c_str()};
951 // Returns primary profile (if it is already created.)
952 virtual Profile* profile() OVERRIDE {
953 Profile* const profile = chromeos::ProfileHelper::GetProfileByUserIdHash(
954 kTestAccounts[PRIMARY_ACCOUNT_INDEX].hash);
955 return profile ? profile : FileManagerBrowserTestBase::profile();
958 // Sets the test case name (used as a function name in test_cases.js to call.)
959 void set_test_case_name(const std::string& name) { test_case_name_ = name; }
961 // Adds a new user for testing to the current session.
962 void AddUser(const TestAccountInfo& info, bool log_in) {
963 chromeos::UserManager* const user_manager = chromeos::UserManager::Get();
965 user_manager->UserLoggedIn(info.email, info.hash, false);
966 user_manager->SaveUserDisplayName(info.email,
967 base::UTF8ToUTF16(info.display_name));
968 chromeos::ProfileHelper::GetProfileByUserIdHash(info.hash)->GetPrefs()->
969 SetString(prefs::kGoogleServicesUsername, info.email);
973 virtual GuestMode GetGuestModeParam() const OVERRIDE {
974 return NOT_IN_GUEST_MODE;
977 virtual const char* GetTestCaseNameParam() const OVERRIDE {
978 return test_case_name_.c_str();
981 virtual std::string OnMessage(const std::string& name,
982 const base::Value* value) OVERRIDE {
983 if (name == "addAllUsers") {
986 } else if (name == "getWindowOwnerId") {
987 chrome::MultiUserWindowManager* const window_manager =
988 chrome::MultiUserWindowManager::GetInstance();
989 apps::AppWindowRegistry* const app_window_registry =
990 apps::AppWindowRegistry::Get(profile());
991 DCHECK(window_manager);
992 DCHECK(app_window_registry);
994 const apps::AppWindowRegistry::AppWindowList& list =
995 app_window_registry->GetAppWindowsForApp(
996 file_manager::kFileManagerAppId);
997 return list.size() == 1u ?
998 window_manager->GetUserPresentingWindow(
999 list.front()->GetNativeWindow()) : "";
1001 return FileManagerBrowserTestBase::OnMessage(name, value);
1004 std::string test_case_name_;
1007 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, PRE_BasicDownloads) {
1011 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, BasicDownloads) {
1014 // Sanity check that normal operations work in multi-profile setting as well.
1015 set_test_case_name("keyboardCopyDownloads");
1019 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, PRE_BasicDrive) {
1023 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, BasicDrive) {
1026 // Sanity check that normal operations work in multi-profile setting as well.
1027 set_test_case_name("keyboardCopyDrive");
1031 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, PRE_Badge) {
1035 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, Badge) {
1036 // Test the profile badge to be correctly shown and hidden.
1037 set_test_case_name("multiProfileBadge");
1041 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
1042 PRE_VisitDesktopMenu) {
1046 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, VisitDesktopMenu) {
1047 // Test for the menu item for visiting other profile's desktop.
1048 set_test_case_name("multiProfileVisitDesktopMenu");
1052 // TODO(kinaba): investigate the flakiness.
1053 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
1054 DISABLED_PRE_MaxUser) {
1056 AddExtraUsersForStressTesting();
1059 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
1061 // Run the same test as VisitDesktopMenu with maximum number of users logged
1062 // in and checks that nothing goes wrong. Here, the primary user (alice) logs
1063 // in first, then the "extra" users follow, and then lastly the other users
1064 // (bob and charlie) are added in the test. Thus the existing test verifies
1065 // that the feature is effectively working with lastly logged in users.
1066 AddExtraUsersForStressTesting();
1068 set_test_case_name("multiProfileVisitDesktopMenu");
1073 } // namespace file_manager