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(IN_GUEST_MODE
, "keyboardDeleteDownloads"),
759 TestParameter(NOT_IN_GUEST_MODE
,
760 "keyboardDeleteDownloads"),
761 TestParameter(NOT_IN_GUEST_MODE
, "keyboardDeleteDrive"),
762 TestParameter(IN_GUEST_MODE
, "keyboardCopyDownloads"),
763 TestParameter(NOT_IN_GUEST_MODE
, "keyboardCopyDownloads"),
764 TestParameter(NOT_IN_GUEST_MODE
, "keyboardCopyDrive"),
765 TestParameter(IN_GUEST_MODE
,
766 "createNewFolderDownloads"),
767 TestParameter(NOT_IN_GUEST_MODE
,
768 "createNewFolderDownloads"),
769 TestParameter(NOT_IN_GUEST_MODE
,
770 "createNewFolderDrive"),
771 TestParameter(IN_GUEST_MODE
,
772 "renameFileDownloads"),
773 TestParameter(NOT_IN_GUEST_MODE
,
774 "renameFileDownloads"),
775 TestParameter(NOT_IN_GUEST_MODE
,
776 "renameFileDrive")));
778 INSTANTIATE_TEST_CASE_P(
780 FileManagerBrowserTest
,
781 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE
, "openSidebarRecent"),
782 TestParameter(NOT_IN_GUEST_MODE
, "openSidebarOffline"),
783 TestParameter(NOT_IN_GUEST_MODE
,
784 "openSidebarSharedWithMe"),
785 TestParameter(NOT_IN_GUEST_MODE
, "autocomplete")));
787 INSTANTIATE_TEST_CASE_P(
789 FileManagerBrowserTest
,
790 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE
,
791 "transferFromDriveToDownloads"),
792 TestParameter(NOT_IN_GUEST_MODE
,
793 "transferFromDownloadsToDrive"),
794 TestParameter(NOT_IN_GUEST_MODE
,
795 "transferFromSharedToDownloads"),
796 TestParameter(NOT_IN_GUEST_MODE
,
797 "transferFromSharedToDrive"),
798 TestParameter(NOT_IN_GUEST_MODE
,
799 "transferFromRecentToDownloads"),
800 TestParameter(NOT_IN_GUEST_MODE
,
801 "transferFromRecentToDrive"),
802 TestParameter(NOT_IN_GUEST_MODE
,
803 "transferFromOfflineToDownloads"),
804 TestParameter(NOT_IN_GUEST_MODE
,
805 "transferFromOfflineToDrive")));
807 INSTANTIATE_TEST_CASE_P(
809 FileManagerBrowserTest
,
810 ::testing::Values(TestParameter(IN_GUEST_MODE
, "restoreSortColumn"),
811 TestParameter(NOT_IN_GUEST_MODE
, "restoreSortColumn"),
812 TestParameter(IN_GUEST_MODE
, "restoreCurrentView"),
813 TestParameter(NOT_IN_GUEST_MODE
, "restoreCurrentView")));
815 INSTANTIATE_TEST_CASE_P(
817 FileManagerBrowserTest
,
818 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE
, "shareFile"),
819 TestParameter(NOT_IN_GUEST_MODE
, "shareDirectory")));
821 INSTANTIATE_TEST_CASE_P(
823 FileManagerBrowserTest
,
824 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE
, "restoreGeometry"),
825 TestParameter(IN_GUEST_MODE
, "restoreGeometry")));
827 INSTANTIATE_TEST_CASE_P(
829 FileManagerBrowserTest
,
830 ::testing::Values(TestParameter(IN_GUEST_MODE
, "traverseDownloads"),
831 TestParameter(NOT_IN_GUEST_MODE
, "traverseDownloads"),
832 TestParameter(NOT_IN_GUEST_MODE
, "traverseDrive")));
834 INSTANTIATE_TEST_CASE_P(
836 FileManagerBrowserTest
,
837 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE
, "suggestAppDialog")));
839 INSTANTIATE_TEST_CASE_P(
840 ExecuteDefaultTaskOnDownloads
,
841 FileManagerBrowserTest
,
843 TestParameter(NOT_IN_GUEST_MODE
, "executeDefaultTaskOnDownloads"),
844 TestParameter(IN_GUEST_MODE
, "executeDefaultTaskOnDownloads")));
846 INSTANTIATE_TEST_CASE_P(
847 ExecuteDefaultTaskOnDrive
,
848 FileManagerBrowserTest
,
850 TestParameter(NOT_IN_GUEST_MODE
, "executeDefaultTaskOnDrive")));
852 INSTANTIATE_TEST_CASE_P(
854 FileManagerBrowserTest
,
855 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE
,
856 "traverseNavigationList")));
858 INSTANTIATE_TEST_CASE_P(
860 FileManagerBrowserTest
,
861 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE
, "searchBoxFocus")));
863 INSTANTIATE_TEST_CASE_P(
865 FileManagerBrowserTest
,
866 ::testing::Values(TestParameter(NOT_IN_GUEST_MODE
, "thumbnailsDownloads"),
867 TestParameter(IN_GUEST_MODE
, "thumbnailsDownloads")));
869 INSTANTIATE_TEST_CASE_P(
871 FileManagerBrowserTest
,
873 TestParameter(NOT_IN_GUEST_MODE
, "copyBetweenWindowsLocalToDrive"),
874 TestParameter(NOT_IN_GUEST_MODE
, "copyBetweenWindowsLocalToUsb"),
875 TestParameter(NOT_IN_GUEST_MODE
, "copyBetweenWindowsUsbToDrive")));
877 // Structure to describe an account info.
878 struct TestAccountInfo
{
879 const char* const email
;
880 const char* const hash
;
881 const char* const display_name
;
885 DUMMY_ACCOUNT_INDEX
= 0,
886 PRIMARY_ACCOUNT_INDEX
= 1,
887 SECONDARY_ACCOUNT_INDEX_START
= 2,
890 static const TestAccountInfo kTestAccounts
[] = {
891 {"__dummy__@invalid.domain", "hashdummy", "Dummy Account"},
892 {"alice@invalid.domain", "hashalice", "Alice"},
893 {"bob@invalid.domain", "hashbob", "Bob"},
894 {"charlie@invalid.domain", "hashcharlie", "Charlie"},
897 // Test fixture class for testing multi-profile features.
898 class MultiProfileFileManagerBrowserTest
: public FileManagerBrowserTestBase
{
900 // Enables multi-profiles.
901 virtual void SetUpCommandLine(CommandLine
* command_line
) OVERRIDE
{
902 FileManagerBrowserTestBase::SetUpCommandLine(command_line
);
903 command_line
->AppendSwitch(switches::kMultiProfiles
);
904 // Logs in to a dummy profile (For making MultiProfileWindowManager happy;
905 // browser test creates a default window and the manager tries to assign a
906 // user for it, and we need a profile connected to a user.)
907 command_line
->AppendSwitchASCII(chromeos::switches::kLoginUser
,
908 kTestAccounts
[DUMMY_ACCOUNT_INDEX
].email
);
909 command_line
->AppendSwitchASCII(chromeos::switches::kLoginProfile
,
910 kTestAccounts
[DUMMY_ACCOUNT_INDEX
].hash
);
913 // Logs in to the primary profile of this test.
914 virtual void SetUpOnMainThread() OVERRIDE
{
915 const TestAccountInfo
& info
= kTestAccounts
[PRIMARY_ACCOUNT_INDEX
];
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.
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()};
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();
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
);
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") {
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
) {
1004 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest
, BasicDownloads
) {
1007 // Sanity check that normal operations work in multi-profile setting as well.
1008 set_test_case_name("keyboardCopyDownloads");
1012 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest
, PRE_BasicDrive
) {
1016 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest
, BasicDrive
) {
1019 // Sanity check that normal operations work in multi-profile setting as well.
1020 set_test_case_name("keyboardCopyDrive");
1024 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest
, PRE_Badge
) {
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");
1034 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest
,
1035 PRE_VisitDesktopMenu
) {
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");
1045 // TODO(kinaba): investigate the flakiness.
1046 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest
,
1047 DISABLED_PRE_MaxUser
) {
1049 AddExtraUsersForStressTesting();
1052 IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest
,
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");
1066 } // namespace file_manager