Disable NavigationList/FileManagerBrowserTest
[chromium-blink-merge.git] / chrome / browser / chromeos / file_manager / file_manager_browsertest.cc
blob7d684a6589a78745e3ddf81c0291ae2567927758
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
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.
11 #include <deque>
12 #include <string>
14 #include "apps/app_window.h"
15 #include "apps/app_window_registry.h"
16 #include "ash/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 {
65 namespace {
67 enum EntryType {
68 FILE,
69 DIRECTORY,
72 enum TargetVolume { LOCAL_VOLUME, DRIVE_VOLUME, USB_VOLUME, };
74 enum SharedOption {
75 NONE,
76 SHARED,
79 enum GuestMode {
80 NOT_IN_GUEST_MODE,
81 IN_GUEST_MODE,
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) {
92 if (value == "file")
93 *output = FILE;
94 else if (value == "directory")
95 *output = DIRECTORY;
96 else
97 return false;
98 return true;
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")
105 *output = SHARED;
106 else if (value == "none")
107 *output = NONE;
108 else
109 return false;
110 return true;
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;
122 else
123 return false;
124 return true;
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) :
142 type(type),
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) {
150 EntryType type;
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);
162 // static
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,
177 &MapStringToTime);
180 // Message from JavaScript to add entries.
181 struct AddEntriesMessage {
182 // Target volume to be added the |entries|.
183 TargetVolume volume;
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);
194 // static
195 void AddEntriesMessage::RegisterJSONConverter(
196 base::JSONValueConverter<AddEntriesMessage>* converter) {
197 converter->RegisterCustomField("volume",
198 &AddEntriesMessage::volume,
199 &MapStringToTargetVolume);
200 converter->RegisterRepeatedMessage<TestEntryInfo>(
201 "entries",
202 &AddEntriesMessage::entries);
205 // Test volume.
206 class TestVolume {
207 protected:
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(); }
218 private:
219 std::string name_;
220 base::ScopedTempDir root_;
223 // The local volume class for test.
224 // This class provides the operations for a test volume that simulates local
225 // drive.
226 class LocalTestVolume : public TestVolume {
227 public:
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
232 // success.
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) {
241 case FILE: {
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.";
248 break;
250 case DIRECTORY:
251 ASSERT_TRUE(base::CreateDirectory(target_path)) <<
252 "Failed to create a directory: " << target_path.value();
253 break;
255 ASSERT_TRUE(UpdateModifiedTime(entry));
258 private:
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))
265 return false;
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())
273 return false;
274 return UpdateModifiedTime(it->second);
276 return true;
279 std::map<base::FilePath, const TestEntryInfo> entries_;
282 class DownloadsTestVolume : public LocalTestVolume {
283 public:
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 {
295 public:
296 FakeUsbTestVolume() : LocalTestVolume("fake-usb") {}
297 virtual ~FakeUsbTestVolume() {}
299 virtual bool Mount(Profile* profile) OVERRIDE {
300 if (!CreateRootDirectory(profile))
301 return false;
302 fileapi::ExternalMountPoints* const mount_points =
303 fileapi::ExternalMountPoints::GetSystemInstance();
305 // First revoke the existing mount point (if any).
306 mount_points->RevokeFileSystem(name());
307 const bool result =
308 mount_points->RegisterFileSystem(name(),
309 fileapi::kFileSystemTypeNativeLocal,
310 fileapi::FileSystemMountOption(),
311 root_path());
312 if (!result)
313 return false;
315 VolumeManager::Get(profile)
316 ->AddVolumeInfoForTesting(root_path(),
317 VOLUME_TYPE_REMOVABLE_DISK_PARTITION,
318 chromeos::DEVICE_TYPE_USB);
319 return true;
323 // The drive volume class for test.
324 // This class provides the operations for a test volume that simulates Google
325 // drive.
326 class DriveTestVolume : public TestVolume {
327 public:
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) {
348 case FILE:
349 CreateFile(entry.source_file_name,
350 parent_entry->resource_id(),
351 target_name,
352 entry.mime_type,
353 entry.shared_option == SHARED,
354 entry.last_modified_time);
355 break;
356 case DIRECTORY:
357 CreateDirectory(
358 parent_entry->resource_id(), target_name, entry.last_modified_time);
359 break;
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(
370 parent_id,
371 target_name,
372 drive::DriveServiceInterface::AddNewDirectoryOptions(),
373 google_apis::test_util::CreateCopyResultCallback(&error,
374 &resource_entry));
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(),
381 modification_time,
382 google_apis::test_util::CreateCopyResultCallback(&error,
383 &resource_entry));
384 base::MessageLoop::current()->RunUntilIdle();
385 ASSERT_TRUE(error == google_apis::HTTP_SUCCESS);
386 ASSERT_TRUE(resource_entry);
387 CheckForUpdates();
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,
396 bool shared_with_me,
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(
410 mime_type,
411 content_data,
412 parent_id,
413 target_name,
414 shared_with_me,
415 google_apis::test_util::CreateCopyResultCallback(&error,
416 &resource_entry));
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(),
423 modification_time,
424 google_apis::test_util::CreateCopyResultCallback(&error,
425 &resource_entry));
426 base::MessageLoop::current()->RunUntilIdle();
427 ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
428 ASSERT_TRUE(resource_entry);
430 CheckForUpdates();
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(
448 Profile* profile) {
449 profile_ = profile;
450 fake_drive_service_ = new drive::FakeDriveService;
451 fake_drive_service_->LoadAppListForDriveApi("drive/applist.json");
453 if (!CreateRootDirectory(profile))
454 return NULL;
455 integration_service_ = new drive::DriveIntegrationService(
456 profile, NULL, fake_drive_service_, std::string(), root_path(), NULL);
457 return integration_service_;
460 private:
461 Profile* profile_;
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 {
468 public:
469 struct Message {
470 int type;
471 std::string message;
472 scoped_refptr<extensions::TestSendMessageFunction> function;
475 FileManagerTestListener() {
476 registrar_.Add(this,
477 chrome::NOTIFICATION_EXTENSION_TEST_PASSED,
478 content::NotificationService::AllSources());
479 registrar_.Add(this,
480 chrome::NOTIFICATION_EXTENSION_TEST_FAILED,
481 content::NotificationService::AllSources());
482 registrar_.Add(this,
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();
492 return entry;
495 virtual void Observe(int type,
496 const content::NotificationSource& source,
497 const content::NotificationDetails& details) OVERRIDE {
498 Message entry;
499 entry.type = type;
500 entry.message = type != chrome::NOTIFICATION_EXTENSION_TEST_PASSED ?
501 *content::Details<std::string>(details).ptr() :
502 std::string();
503 entry.function = type == chrome::NOTIFICATION_EXTENSION_TEST_MESSAGE ?
504 content::Source<extensions::TestSendMessageFunction>(source).ptr() :
505 NULL;
506 messages_.push_back(entry);
507 base::MessageLoopForUI::current()->Quit();
510 private:
511 std::deque<Message> messages_;
512 content::NotificationRegistrar registrar_;
515 // The base test class.
516 class FileManagerBrowserTestBase : public ExtensionApiTest {
517 protected:
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
526 // test.
527 void StartTest();
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_;
540 private:
541 drive::DriveIntegrationService* CreateDriveIntegrationService(
542 Profile* profile);
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;
597 while (true) {
598 FileManagerTestListener::Message entry = listener.GetNextMessage();
599 if (entry.type == chrome::NOTIFICATION_EXTENSION_TEST_PASSED) {
600 // Test succeed.
601 break;
602 } else if (entry.type == chrome::NOTIFICATION_EXTENSION_TEST_FAILED) {
603 // Test failed.
604 ADD_FAILURE() << entry.message;
605 break;
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;
614 std::string name;
615 if (!value || !value->GetAsDictionary(&message_dictionary) ||
616 !message_dictionary->GetString("name", &name))
617 continue;
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);
638 return 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);
657 return 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))
663 return "onError";
664 for (size_t i = 0; i < message.entries.size(); ++i) {
665 switch (message.volume) {
666 case LOCAL_VOLUME:
667 local_volume_->CreateEntry(*message.entries[i]);
668 break;
669 case DRIVE_VOLUME:
670 if (drive_volume_.get())
671 drive_volume_->CreateEntry(*message.entries[i]);
672 break;
673 case USB_VOLUME:
674 if (usb_volume_)
675 usb_volume_->CreateEntry(*message.entries[i]);
676 break;
677 default:
678 NOTREACHED();
679 break;
682 return "onEntryAdded";
683 } else if (name == "mountFakeUsb") {
684 usb_volume_.reset(new FakeUsbTestVolume());
685 usb_volume_->Mount(profile());
686 return "true";
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) {
714 StartTest();
717 INSTANTIATE_TEST_CASE_P(
718 FileDisplay,
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(
725 OpenSpecialTypes,
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(
736 OpenVideoFiles,
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(
743 OpenAudioFiles,
744 FileManagerBrowserTest,
745 ::testing::Values(
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")));
751 INSTANTIATE_TEST_CASE_P(
752 KeyboardOperations,
753 FileManagerBrowserTest,
754 ::testing::Values(TestParameter(IN_GUEST_MODE, "keyboardDeleteDownloads"),
755 TestParameter(NOT_IN_GUEST_MODE,
756 "keyboardDeleteDownloads"),
757 TestParameter(NOT_IN_GUEST_MODE, "keyboardDeleteDrive"),
758 TestParameter(IN_GUEST_MODE, "keyboardCopyDownloads"),
759 TestParameter(NOT_IN_GUEST_MODE, "keyboardCopyDownloads"),
760 TestParameter(NOT_IN_GUEST_MODE, "keyboardCopyDrive"),
761 TestParameter(IN_GUEST_MODE,
762 "createNewFolderDownloads"),
763 TestParameter(NOT_IN_GUEST_MODE,
764 "createNewFolderDownloads"),
765 TestParameter(NOT_IN_GUEST_MODE,
766 "createNewFolderDrive")));
768 INSTANTIATE_TEST_CASE_P(
769 DriveSpecific,
770 FileManagerBrowserTest,
771 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "openSidebarRecent"),
772 TestParameter(NOT_IN_GUEST_MODE, "openSidebarOffline"),
773 TestParameter(NOT_IN_GUEST_MODE,
774 "openSidebarSharedWithMe"),
775 TestParameter(NOT_IN_GUEST_MODE, "autocomplete")));
777 INSTANTIATE_TEST_CASE_P(
778 Transfer,
779 FileManagerBrowserTest,
780 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE,
781 "transferFromDriveToDownloads"),
782 TestParameter(NOT_IN_GUEST_MODE,
783 "transferFromDownloadsToDrive"),
784 TestParameter(NOT_IN_GUEST_MODE,
785 "transferFromSharedToDownloads"),
786 TestParameter(NOT_IN_GUEST_MODE,
787 "transferFromSharedToDrive"),
788 TestParameter(NOT_IN_GUEST_MODE,
789 "transferFromRecentToDownloads"),
790 TestParameter(NOT_IN_GUEST_MODE,
791 "transferFromRecentToDrive"),
792 TestParameter(NOT_IN_GUEST_MODE,
793 "transferFromOfflineToDownloads"),
794 TestParameter(NOT_IN_GUEST_MODE,
795 "transferFromOfflineToDrive")));
797 INSTANTIATE_TEST_CASE_P(
798 HideSearchBox,
799 FileManagerBrowserTest,
800 ::testing::Values(TestParameter(IN_GUEST_MODE, "hideSearchBox"),
801 TestParameter(NOT_IN_GUEST_MODE, "hideSearchBox")));
803 INSTANTIATE_TEST_CASE_P(
804 RestorePrefs,
805 FileManagerBrowserTest,
806 ::testing::Values(TestParameter(IN_GUEST_MODE, "restoreSortColumn"),
807 TestParameter(NOT_IN_GUEST_MODE, "restoreSortColumn"),
808 TestParameter(IN_GUEST_MODE, "restoreCurrentView"),
809 TestParameter(NOT_IN_GUEST_MODE, "restoreCurrentView")));
811 INSTANTIATE_TEST_CASE_P(
812 ShareDialog,
813 FileManagerBrowserTest,
814 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "shareFile"),
815 TestParameter(NOT_IN_GUEST_MODE, "shareDirectory")));
817 INSTANTIATE_TEST_CASE_P(
818 RestoreGeometry,
819 FileManagerBrowserTest,
820 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "restoreGeometry"),
821 TestParameter(IN_GUEST_MODE, "restoreGeometry")));
823 INSTANTIATE_TEST_CASE_P(
824 Traverse,
825 FileManagerBrowserTest,
826 ::testing::Values(TestParameter(IN_GUEST_MODE, "traverseDownloads"),
827 TestParameter(NOT_IN_GUEST_MODE, "traverseDownloads"),
828 TestParameter(NOT_IN_GUEST_MODE, "traverseDrive")));
830 INSTANTIATE_TEST_CASE_P(
831 SuggestAppDialog,
832 FileManagerBrowserTest,
833 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "suggestAppDialog")));
835 INSTANTIATE_TEST_CASE_P(
836 ExecuteDefaultTaskOnDownloads,
837 FileManagerBrowserTest,
838 ::testing::Values(
839 TestParameter(NOT_IN_GUEST_MODE, "executeDefaultTaskOnDownloads"),
840 TestParameter(IN_GUEST_MODE, "executeDefaultTaskOnDownloads")));
842 INSTANTIATE_TEST_CASE_P(
843 ExecuteDefaultTaskOnDrive,
844 FileManagerBrowserTest,
845 ::testing::Values(
846 TestParameter(NOT_IN_GUEST_MODE, "executeDefaultTaskOnDrive")));
848 // TODO: http://crbug.com/360436
849 INSTANTIATE_TEST_CASE_P(
850 DISABLED_NavigationList,
851 FileManagerBrowserTest,
852 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE,
853 "traverseNavigationList")));
855 INSTANTIATE_TEST_CASE_P(
856 TabIndex,
857 FileManagerBrowserTest,
858 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "searchBoxFocus")));
860 INSTANTIATE_TEST_CASE_P(
861 Thumbnails,
862 FileManagerBrowserTest,
863 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "thumbnailsDownloads"),
864 TestParameter(IN_GUEST_MODE, "thumbnailsDownloads")));
866 INSTANTIATE_TEST_CASE_P(
867 CopyBetweenWindows,
868 FileManagerBrowserTest,
869 ::testing::Values(
870 TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsLocalToDrive"),
871 TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsLocalToUsb"),
872 TestParameter(NOT_IN_GUEST_MODE, "copyBetweenWindowsUsbToDrive")));
874 // Structure to describe an account info.
875 struct TestAccountInfo {
876 const char* const email;
877 const char* const hash;
878 const char* const display_name;
881 enum {
882 DUMMY_ACCOUNT_INDEX = 0,
883 PRIMARY_ACCOUNT_INDEX = 1,
884 SECONDARY_ACCOUNT_INDEX_START = 2,
887 static const TestAccountInfo kTestAccounts[] = {
888 {"__dummy__@invalid.domain", "hashdummy", "Dummy Account"},
889 {"alice@invalid.domain", "hashalice", "Alice"},
890 {"bob@invalid.domain", "hashbob", "Bob"},
891 {"charlie@invalid.domain", "hashcharlie", "Charlie"},
894 // Test fixture class for testing multi-profile features.
895 class MultiProfileFileManagerBrowserTest : public FileManagerBrowserTestBase {
896 protected:
897 // Enables multi-profiles.
898 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
899 FileManagerBrowserTestBase::SetUpCommandLine(command_line);
900 command_line->AppendSwitch(switches::kMultiProfiles);
901 // Logs in to a dummy profile (For making MultiProfileWindowManager happy;
902 // browser test creates a default window and the manager tries to assign a
903 // user for it, and we need a profile connected to a user.)
904 command_line->AppendSwitchASCII(chromeos::switches::kLoginUser,
905 kTestAccounts[DUMMY_ACCOUNT_INDEX].email);
906 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile,
907 kTestAccounts[DUMMY_ACCOUNT_INDEX].hash);
910 // Logs in to the primary profile of this test.
911 virtual void SetUpOnMainThread() OVERRIDE {
912 const TestAccountInfo& info = kTestAccounts[PRIMARY_ACCOUNT_INDEX];
914 AddUser(info, true);
915 chromeos::UserManager* const user_manager = chromeos::UserManager::Get();
916 if (user_manager->GetActiveUser() != user_manager->FindUser(info.email))
917 chromeos::UserManager::Get()->SwitchActiveUser(info.email);
918 FileManagerBrowserTestBase::SetUpOnMainThread();
921 // Loads all users to the current session and sets up necessary fields.
922 // This is used for preparing all accounts in PRE_ test setup, and for testing
923 // actual login behavior.
924 void AddAllUsers() {
925 for (size_t i = 0; i < arraysize(kTestAccounts); ++i)
926 AddUser(kTestAccounts[i], i >= SECONDARY_ACCOUNT_INDEX_START);
929 // Add as many as users
930 void AddExtraUsersForStressTesting() {
931 ash::Shell* const shell = ash::Shell::GetInstance();
932 const size_t maxLogin =
933 shell->session_state_delegate()->GetMaximumNumberOfLoggedInUsers();
935 for (int i = 0; i + arraysize(kTestAccounts) < maxLogin; ++i) {
936 const std::string email = base::StringPrintf("user%d@invalid.domain", i);
937 const std::string hash = base::StringPrintf("hashuser%d", i);
938 const std::string name = base::StringPrintf("Additional User %d", i);
939 const TestAccountInfo info = {email.c_str(), hash.c_str(), name.c_str()};
940 AddUser(info, true);
944 // Returns primary profile (if it is already created.)
945 virtual Profile* profile() OVERRIDE {
946 Profile* const profile = chromeos::ProfileHelper::GetProfileByUserIdHash(
947 kTestAccounts[PRIMARY_ACCOUNT_INDEX].hash);
948 return profile ? profile : FileManagerBrowserTestBase::profile();
951 // Sets the test case name (used as a function name in test_cases.js to call.)
952 void set_test_case_name(const std::string& name) { test_case_name_ = name; }
954 // Adds a new user for testing to the current session.
955 void AddUser(const TestAccountInfo& info, bool log_in) {
956 chromeos::UserManager* const user_manager = chromeos::UserManager::Get();
957 if (log_in)
958 user_manager->UserLoggedIn(info.email, info.hash, false);
959 user_manager->SaveUserDisplayName(info.email,
960 base::UTF8ToUTF16(info.display_name));
961 chromeos::ProfileHelper::GetProfileByUserIdHash(info.hash)->GetPrefs()->
962 SetString(prefs::kGoogleServicesUsername, info.email);
965 private:
966 virtual GuestMode GetGuestModeParam() const OVERRIDE {
967 return NOT_IN_GUEST_MODE;
970 virtual const char* GetTestCaseNameParam() const OVERRIDE {
971 return test_case_name_.c_str();
974 virtual std::string OnMessage(const std::string& name,
975 const base::Value* value) OVERRIDE {
976 if (name == "addAllUsers") {
977 AddAllUsers();
978 return "true";
979 } else if (name == "getWindowOwnerId") {
980 chrome::MultiUserWindowManager* const window_manager =
981 chrome::MultiUserWindowManager::GetInstance();
982 apps::AppWindowRegistry* const app_window_registry =
983 apps::AppWindowRegistry::Get(profile());
984 DCHECK(window_manager);
985 DCHECK(app_window_registry);
987 const apps::AppWindowRegistry::AppWindowList& list =
988 app_window_registry->GetAppWindowsForApp(
989 file_manager::kFileManagerAppId);
990 return list.size() == 1u ?
991 window_manager->GetUserPresentingWindow(
992 list.front()->GetNativeWindow()) : "";
994 return FileManagerBrowserTestBase::OnMessage(name, value);
997 std::string test_case_name_;
1000 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, PRE_BasicDownloads) {
1001 AddAllUsers();
1004 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, BasicDownloads) {
1005 AddAllUsers();
1007 // Sanity check that normal operations work in multi-profile setting as well.
1008 set_test_case_name("keyboardCopyDownloads");
1009 StartTest();
1012 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, PRE_BasicDrive) {
1013 AddAllUsers();
1016 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, BasicDrive) {
1017 AddAllUsers();
1019 // Sanity check that normal operations work in multi-profile setting as well.
1020 set_test_case_name("keyboardCopyDrive");
1021 StartTest();
1024 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, PRE_Badge) {
1025 AddAllUsers();
1028 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, Badge) {
1029 // Test the profile badge to be correctly shown and hidden.
1030 set_test_case_name("multiProfileBadge");
1031 StartTest();
1034 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
1035 PRE_VisitDesktopMenu) {
1036 AddAllUsers();
1039 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, VisitDesktopMenu) {
1040 // Test for the menu item for visiting other profile's desktop.
1041 set_test_case_name("multiProfileVisitDesktopMenu");
1042 StartTest();
1045 // TODO(kinaba): investigate the flakiness.
1046 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
1047 DISABLED_PRE_MaxUser) {
1048 AddAllUsers();
1049 AddExtraUsersForStressTesting();
1052 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest,
1053 DISABLED_MaxUser) {
1054 // Run the same test as VisitDesktopMenu with maximum number of users logged
1055 // in and checks that nothing goes wrong. Here, the primary user (alice) logs
1056 // in first, then the "extra" users follow, and then lastly the other users
1057 // (bob and charlie) are added in the test. Thus the existing test verifies
1058 // that the feature is effectively working with lastly logged in users.
1059 AddExtraUsersForStressTesting();
1061 set_test_case_name("multiProfileVisitDesktopMenu");
1062 StartTest();
1065 } // namespace
1066 } // namespace file_manager