Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / file_manager / external_filesystem_apitest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/bind.h"
6 #include "base/files/file_path.h"
7 #include "base/files/file_util.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/path_service.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
12 #include "chrome/browser/chromeos/file_manager/drive_test_util.h"
13 #include "chrome/browser/chromeos/file_manager/volume_manager.h"
14 #include "chrome/browser/chromeos/profiles/profile_helper.h"
15 #include "chrome/browser/drive/fake_drive_service.h"
16 #include "chrome/browser/extensions/extension_apitest.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/common/chrome_constants.h"
21 #include "chrome/common/chrome_paths.h"
22 #include "components/user_manager/user_manager.h"
23 #include "content/public/browser/browser_context.h"
24 #include "content/public/browser/notification_service.h"
25 #include "content/public/test/test_utils.h"
26 #include "extensions/browser/notification_types.h"
27 #include "extensions/test/result_catcher.h"
28 #include "google_apis/drive/drive_api_parser.h"
29 #include "google_apis/drive/test_util.h"
30 #include "google_apis/drive/time_util.h"
31 #include "storage/browser/fileapi/external_mount_points.h"
32 #include "ui/shell_dialogs/select_file_dialog_factory.h"
33
34 // Tests for access to external file systems (as defined in
35 // storage/common/fileapi/file_system_types.h) from extensions with
36 // fileManagerPrivate and fileBrowserHandler extension permissions.
37 // The tests cover following external file system types:
38 // - local (kFileSystemTypeLocalNative): a local file system on which files are
39 //   accessed using native local path.
40 // - restricted (kFileSystemTypeRestrictedLocalNative): a *read-only* local file
41 //   system which can only be accessed by extensions that have full access to
42 //   external file systems (i.e. extensions with fileManagerPrivate permission).
43 // - drive (kFileSystemTypeDrive): a file system that provides access to Google
44 //   Drive.
45 //
46 // The tests cover following scenarios:
47 // - Performing file system operations on external file systems from an
48 //   app with fileManagerPrivate permission (i.e. Files.app).
49 // - Performing read/write operations from file handler extensions. These
50 //   extensions need a file browser extension to give them permissions to access
51 //   files. This also includes file handler extensions in filesystem API.
52 // - Observing directory changes from a file browser extension (using
53 //   fileManagerPrivate API).
54 // - Doing searches on drive file system from file browser extension (using
55 //   fileManagerPrivate API).
56
57 using drive::DriveIntegrationServiceFactory;
58 using extensions::Extension;
59
60 namespace file_manager {
61 namespace {
62
63 // Root dirs for file systems expected by the test extensions.
64 // NOTE: Root dir for drive file system is set by Chrome's drive implementation,
65 // but the test will have to make sure the mount point is added before
66 // starting a test extension using WaitUntilDriveMountPointIsAdded().
67 const char kLocalMountPointName[] = "local";
68 const char kRestrictedMountPointName[] = "restricted";
69
70 // Default file content for the test files.
71 const char kTestFileContent[] = "This is some test content.";
72
73 // User account email and directory hash for secondary account for multi-profile
74 // sensitive test cases.
75 const char kSecondProfileAccount[] = "profile2@test.com";
76 const char kSecondProfileHash[] = "fileBrowserApiTestProfile2";
77
78 class FakeSelectFileDialog : public ui::SelectFileDialog {
79  public:
80   FakeSelectFileDialog(ui::SelectFileDialog::Listener* listener,
81                        ui::SelectFilePolicy* policy)
82       : ui::SelectFileDialog(listener, policy) {}
83
84   virtual void SelectFileImpl(
85       Type type,
86       const base::string16& title,
87       const base::FilePath& default_path,
88       const FileTypeInfo* file_types,
89       int file_type_index,
90       const base::FilePath::StringType& default_extension,
91       gfx::NativeWindow owning_window,
92       void* params) override {
93     listener_->FileSelected(
94         base::FilePath("/special/drive-user/root/test_dir"), 0, NULL);
95   }
96
97   virtual bool IsRunning(gfx::NativeWindow owning_window) const override {
98     return false;
99   }
100
101   virtual void ListenerDestroyed() override {}
102
103   virtual bool HasMultipleFileTypeChoicesImpl() override { return false; }
104
105  private:
106   virtual ~FakeSelectFileDialog() {}
107 };
108
109 class FakeSelectFileDialogFactory : public ui::SelectFileDialogFactory {
110  private:
111   virtual ui::SelectFileDialog* Create(ui::SelectFileDialog::Listener* listener,
112                                        ui::SelectFilePolicy* policy) override {
113     return new FakeSelectFileDialog(listener, policy);
114   }
115 };
116
117 // Sets up the initial file system state for native local and restricted native
118 // local file systems. The hierarchy is the same as for the drive file system.
119 // The directory is created at unique_temp_dir/|mount_point_name| path.
120 bool InitializeLocalFileSystem(std::string mount_point_name,
121                                base::ScopedTempDir* tmp_dir,
122                                base::FilePath* mount_point_dir) {
123   if (!tmp_dir->CreateUniqueTempDir())
124     return false;
125
126   *mount_point_dir = tmp_dir->path().AppendASCII(mount_point_name);
127   // Create the mount point.
128   if (!base::CreateDirectory(*mount_point_dir))
129     return false;
130
131   base::FilePath test_dir = mount_point_dir->AppendASCII("test_dir");
132   if (!base::CreateDirectory(test_dir))
133     return false;
134
135   base::FilePath test_subdir = test_dir.AppendASCII("empty_test_dir");
136   if (!base::CreateDirectory(test_subdir))
137     return false;
138
139   test_subdir = test_dir.AppendASCII("subdir");
140   if (!base::CreateDirectory(test_subdir))
141     return false;
142
143   base::FilePath test_file = test_dir.AppendASCII("test_file.xul");
144   if (!google_apis::test_util::WriteStringToFile(test_file, kTestFileContent))
145     return false;
146
147   test_file = test_dir.AppendASCII("test_file.xul.foo");
148   if (!google_apis::test_util::WriteStringToFile(test_file, kTestFileContent))
149     return false;
150
151   test_file = test_dir.AppendASCII("test_file.tiff");
152   if (!google_apis::test_util::WriteStringToFile(test_file, kTestFileContent))
153     return false;
154
155   test_file = test_dir.AppendASCII("test_file.tiff.foo");
156   if (!google_apis::test_util::WriteStringToFile(test_file, kTestFileContent))
157     return false;
158
159   test_file = test_dir.AppendASCII("empty_test_file.foo");
160   if (!google_apis::test_util::WriteStringToFile(test_file, ""))
161     return false;
162
163   return true;
164 }
165
166 scoped_ptr<google_apis::FileResource> UpdateDriveEntryTime(
167     drive::FakeDriveService* fake_drive_service,
168     const std::string& resource_id,
169     const std::string& last_modified,
170     const std::string& last_viewed_by_me) {
171   base::Time last_modified_time, last_viewed_by_me_time;
172   if (!google_apis::util::GetTimeFromString(last_modified,
173                                             &last_modified_time) ||
174       !google_apis::util::GetTimeFromString(last_viewed_by_me,
175                                             &last_viewed_by_me_time))
176     return scoped_ptr<google_apis::FileResource>();
177
178   google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
179   scoped_ptr<google_apis::FileResource> entry;
180   fake_drive_service->UpdateResource(
181       resource_id,
182       std::string(),  // parent_resource_id
183       std::string(),  // title
184       last_modified_time,
185       last_viewed_by_me_time,
186       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
187   base::RunLoop().RunUntilIdle();
188   if (error != google_apis::HTTP_SUCCESS)
189     return scoped_ptr<google_apis::FileResource>();
190
191   return entry.Pass();
192 }
193
194 scoped_ptr<google_apis::FileResource> AddFileToDriveService(
195     drive::FakeDriveService* fake_drive_service,
196     const std::string& mime_type,
197     const std::string& content,
198     const std::string& parent_resource_id,
199     const std::string& title,
200     const std::string& last_modified,
201     const std::string& last_viewed_by_me) {
202   google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
203   scoped_ptr<google_apis::FileResource> entry;
204   fake_drive_service->AddNewFile(
205       mime_type,
206       content,
207       parent_resource_id,
208       title,
209       false,  // shared_with_me
210       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
211   base::RunLoop().RunUntilIdle();
212   if (error != google_apis::HTTP_CREATED)
213     return scoped_ptr<google_apis::FileResource>();
214
215   return UpdateDriveEntryTime(fake_drive_service, entry->file_id(),
216                               last_modified, last_viewed_by_me);
217 }
218
219 scoped_ptr<google_apis::FileResource> AddDirectoryToDriveService(
220     drive::FakeDriveService* fake_drive_service,
221     const std::string& parent_resource_id,
222     const std::string& title,
223     const std::string& last_modified,
224     const std::string& last_viewed_by_me) {
225   google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
226   scoped_ptr<google_apis::FileResource> entry;
227   fake_drive_service->AddNewDirectory(
228       parent_resource_id,
229       title,
230       drive::DriveServiceInterface::AddNewDirectoryOptions(),
231       google_apis::test_util::CreateCopyResultCallback(&error, &entry));
232   base::RunLoop().RunUntilIdle();
233   if (error != google_apis::HTTP_CREATED)
234     return scoped_ptr<google_apis::FileResource>();
235
236   return UpdateDriveEntryTime(fake_drive_service, entry->file_id(),
237                               last_modified, last_viewed_by_me);
238 }
239
240 // Sets up the drive service state.
241 // The hierarchy is the same as for the local file system.
242 bool InitializeDriveService(
243     drive::FakeDriveService* fake_drive_service,
244     std::map<std::string, std::string>* out_resource_ids) {
245   scoped_ptr<google_apis::FileResource> entry;
246
247   entry = AddDirectoryToDriveService(fake_drive_service,
248                                      fake_drive_service->GetRootResourceId(),
249                                      "test_dir",
250                                      "2012-01-02T00:00:00.000Z",
251                                      "2012-01-02T00:00:01.000Z");
252   if (!entry)
253     return false;
254   (*out_resource_ids)[entry->title()] = entry->file_id();
255
256   entry = AddDirectoryToDriveService(fake_drive_service,
257                                      (*out_resource_ids)["test_dir"],
258                                      "empty_test_dir",
259                                      "2011-11-02T04:00:00.000Z",
260                                      "2011-11-02T04:00:00.000Z");
261   if (!entry)
262     return false;
263   (*out_resource_ids)[entry->title()] = entry->file_id();
264
265   entry = AddDirectoryToDriveService(fake_drive_service,
266                                      (*out_resource_ids)["test_dir"],
267                                      "subdir",
268                                      "2011-04-01T18:34:08.234Z",
269                                      "2012-01-02T00:00:01.000Z");
270   if (!entry)
271     return false;
272   (*out_resource_ids)[entry->title()] = entry->file_id();
273
274   entry = AddFileToDriveService(fake_drive_service,
275                                 "application/vnd.mozilla.xul+xml",
276                                 kTestFileContent,
277                                 (*out_resource_ids)["test_dir"],
278                                 "test_file.xul",
279                                 "2011-12-14T00:40:47.330Z",
280                                 "2012-01-02T00:00:00.000Z");
281   if (!entry)
282     return false;
283   (*out_resource_ids)[entry->title()] = entry->file_id();
284
285   entry = AddFileToDriveService(fake_drive_service,
286                                 "test/ro",
287                                 kTestFileContent,
288                                 (*out_resource_ids)["test_dir"],
289                                 "test_file.xul.foo",
290                                 "2012-01-01T10:00:30.000Z",
291                                 "2012-01-01T00:00:00.000Z");
292   if (!entry)
293     return false;
294   (*out_resource_ids)[entry->title()] = entry->file_id();
295
296   entry = AddFileToDriveService(fake_drive_service,
297                                 "image/tiff",
298                                 kTestFileContent,
299                                 (*out_resource_ids)["test_dir"],
300                                 "test_file.tiff",
301                                 "2011-04-03T11:11:10.000Z",
302                                 "2012-01-02T00:00:00.000Z");
303   if (!entry)
304     return false;
305   (*out_resource_ids)[entry->title()] = entry->file_id();
306
307   entry = AddFileToDriveService(fake_drive_service,
308                                 "test/rw",
309                                 kTestFileContent,
310                                 (*out_resource_ids)["test_dir"],
311                                 "test_file.tiff.foo",
312                                 "2011-12-14T00:40:47.330Z",
313                                 "2010-01-02T00:00:00.000Z");
314   if (!entry)
315     return false;
316   (*out_resource_ids)[entry->title()] = entry->file_id();
317
318   entry = AddFileToDriveService(fake_drive_service,
319                                 "test/rw",
320                                 "",
321                                 (*out_resource_ids)["test_dir"],
322                                 "empty_test_file.foo",
323                                 "2011-12-14T00:40:47.330Z",
324                                 "2011-12-14T00:40:47.330Z");
325   if (!entry)
326     return false;
327   (*out_resource_ids)[entry->title()] = entry->file_id();
328
329   return true;
330 }
331
332 // Helper class to wait for a background page to load or close again.
333 class BackgroundObserver {
334  public:
335   BackgroundObserver()
336       : page_created_(extensions::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY,
337                       content::NotificationService::AllSources()),
338         page_closed_(extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED,
339                      content::NotificationService::AllSources()) {}
340
341   void WaitUntilLoaded() {
342     page_created_.Wait();
343   }
344
345   void WaitUntilClosed() {
346     page_closed_.Wait();
347   }
348
349  private:
350   content::WindowedNotificationObserver page_created_;
351   content::WindowedNotificationObserver page_closed_;
352 };
353
354 // Base class for FileSystemExtensionApi tests.
355 class FileSystemExtensionApiTestBase : public ExtensionApiTest {
356  public:
357   enum Flags {
358     FLAGS_NONE = 0,
359     FLAGS_USE_FILE_HANDLER = 1 << 1,
360     FLAGS_LAZY_FILE_HANDLER = 1 << 2
361   };
362
363   FileSystemExtensionApiTestBase() {}
364   virtual ~FileSystemExtensionApiTestBase() {}
365
366   virtual void SetUp() override {
367     InitTestFileSystem();
368     ExtensionApiTest::SetUp();
369   }
370
371   virtual void SetUpOnMainThread() override {
372     AddTestMountPoint();
373     ExtensionApiTest::SetUpOnMainThread();
374   }
375
376   // Runs a file system extension API test.
377   // It loads test component extension at |filebrowser_path| with manifest
378   // at |filebrowser_manifest|. The |filebrowser_manifest| should be a path
379   // relative to |filebrowser_path|. The method waits until the test extension
380   // sends test succeed or fail message. It returns true if the test succeeds.
381   // If |FLAGS_USE_FILE_HANDLER| flag is set, the file handler extension at path
382   // |filehandler_path| will be loaded before the file browser extension.
383   // If the flag FLAGS_LAZY_FILE_HANDLER is set, the file handler extension must
384   // not have persistent background page. The test will wait until the file
385   // handler's background page is closed after initial load before the file
386   // browser extension is loaded.
387   // If |RunFileSystemExtensionApiTest| fails, |message_| will contain a failure
388   // message.
389   bool RunFileSystemExtensionApiTest(
390       const std::string& filebrowser_path,
391       const base::FilePath::CharType* filebrowser_manifest,
392       const std::string& filehandler_path,
393       int flags) {
394     if (flags & FLAGS_USE_FILE_HANDLER) {
395       if (filehandler_path.empty()) {
396         message_ = "Missing file handler path.";
397         return false;
398       }
399
400       BackgroundObserver page_complete;
401       const Extension* file_handler =
402           LoadExtension(test_data_dir_.AppendASCII(filehandler_path));
403       if (!file_handler)
404         return false;
405
406       if (flags & FLAGS_LAZY_FILE_HANDLER) {
407         page_complete.WaitUntilClosed();
408       } else {
409         page_complete.WaitUntilLoaded();
410       }
411     }
412
413     extensions::ResultCatcher catcher;
414
415     const Extension* file_browser = LoadExtensionAsComponentWithManifest(
416         test_data_dir_.AppendASCII(filebrowser_path),
417         filebrowser_manifest);
418     if (!file_browser)
419       return false;
420
421     if (!catcher.GetNextResult()) {
422       message_ = catcher.message();
423       return false;
424     }
425
426     return true;
427   }
428
429  protected:
430   // Sets up initial test file system hierarchy.
431   virtual void InitTestFileSystem() = 0;
432   // Registers mount point used in the test.
433   virtual void AddTestMountPoint() = 0;
434 };
435
436 // Tests for a native local file system.
437 class LocalFileSystemExtensionApiTest : public FileSystemExtensionApiTestBase {
438  public:
439   LocalFileSystemExtensionApiTest() {}
440   virtual ~LocalFileSystemExtensionApiTest() {}
441
442   // FileSystemExtensionApiTestBase override.
443   virtual void InitTestFileSystem() override {
444     ASSERT_TRUE(InitializeLocalFileSystem(
445         kLocalMountPointName, &tmp_dir_, &mount_point_dir_))
446         << "Failed to initialize file system.";
447   }
448
449   // FileSystemExtensionApiTestBase override.
450   virtual void AddTestMountPoint() override {
451     EXPECT_TRUE(content::BrowserContext::GetMountPoints(browser()->profile())
452                     ->RegisterFileSystem(kLocalMountPointName,
453                                          storage::kFileSystemTypeNativeLocal,
454                                          storage::FileSystemMountOption(),
455                                          mount_point_dir_));
456     VolumeManager::Get(browser()->profile())->AddVolumeInfoForTesting(
457         mount_point_dir_, VOLUME_TYPE_TESTING, chromeos::DEVICE_TYPE_UNKNOWN);
458   }
459
460  private:
461   base::ScopedTempDir tmp_dir_;
462   base::FilePath mount_point_dir_;
463 };
464
465 // Tests for restricted native local file systems.
466 class RestrictedFileSystemExtensionApiTest
467     : public FileSystemExtensionApiTestBase {
468  public:
469   RestrictedFileSystemExtensionApiTest() {}
470   virtual ~RestrictedFileSystemExtensionApiTest() {}
471
472   // FileSystemExtensionApiTestBase override.
473   virtual void InitTestFileSystem() override {
474     ASSERT_TRUE(InitializeLocalFileSystem(
475         kRestrictedMountPointName, &tmp_dir_, &mount_point_dir_))
476         << "Failed to initialize file system.";
477   }
478
479   // FileSystemExtensionApiTestBase override.
480   virtual void AddTestMountPoint() override {
481     EXPECT_TRUE(
482         content::BrowserContext::GetMountPoints(browser()->profile())
483             ->RegisterFileSystem(kRestrictedMountPointName,
484                                  storage::kFileSystemTypeRestrictedNativeLocal,
485                                  storage::FileSystemMountOption(),
486                                  mount_point_dir_));
487     VolumeManager::Get(browser()->profile())->AddVolumeInfoForTesting(
488         mount_point_dir_, VOLUME_TYPE_TESTING, chromeos::DEVICE_TYPE_UNKNOWN);
489   }
490
491  private:
492   base::ScopedTempDir tmp_dir_;
493   base::FilePath mount_point_dir_;
494 };
495
496 // Tests for a drive file system.
497 class DriveFileSystemExtensionApiTest : public FileSystemExtensionApiTestBase {
498  public:
499   DriveFileSystemExtensionApiTest() : fake_drive_service_(NULL) {}
500   virtual ~DriveFileSystemExtensionApiTest() {}
501
502   // FileSystemExtensionApiTestBase override.
503   virtual void InitTestFileSystem() override {
504     // Set up cache root to be used by DriveIntegrationService. This has to be
505     // done before the browser is created because the service instance is
506     // initialized by EventRouter.
507     ASSERT_TRUE(test_cache_root_.CreateUniqueTempDir());
508
509     // This callback will get called during Profile creation.
510     create_drive_integration_service_ = base::Bind(
511         &DriveFileSystemExtensionApiTest::CreateDriveIntegrationService,
512         base::Unretained(this));
513     service_factory_for_test_.reset(
514         new DriveIntegrationServiceFactory::ScopedFactoryForTest(
515             &create_drive_integration_service_));
516   }
517
518   // FileSystemExtensionApiTestBase override.
519   virtual void AddTestMountPoint() override {
520     test_util::WaitUntilDriveMountPointIsAdded(browser()->profile());
521   }
522
523   // FileSystemExtensionApiTestBase override.
524   virtual void TearDown() override {
525     FileSystemExtensionApiTestBase::TearDown();
526     ui::SelectFileDialog::SetFactory(NULL);
527   }
528
529  protected:
530   // DriveIntegrationService factory function for this test.
531   drive::DriveIntegrationService* CreateDriveIntegrationService(
532       Profile* profile) {
533     fake_drive_service_ = new drive::FakeDriveService;
534     fake_drive_service_->LoadAppListForDriveApi("drive/applist.json");
535
536     std::map<std::string, std::string> resource_ids;
537     EXPECT_TRUE(InitializeDriveService(fake_drive_service_, &resource_ids));
538
539     return new drive::DriveIntegrationService(
540         profile, NULL, fake_drive_service_, "", test_cache_root_.path(), NULL);
541   }
542
543   base::ScopedTempDir test_cache_root_;
544   drive::FakeDriveService* fake_drive_service_;
545   DriveIntegrationServiceFactory::FactoryCallback
546       create_drive_integration_service_;
547   scoped_ptr<DriveIntegrationServiceFactory::ScopedFactoryForTest>
548       service_factory_for_test_;
549 };
550
551 // Tests for Drive file systems in multi-profile setting.
552 class MultiProfileDriveFileSystemExtensionApiTest :
553     public FileSystemExtensionApiTestBase {
554  public:
555   MultiProfileDriveFileSystemExtensionApiTest() : second_profile(NULL) {}
556
557   virtual void SetUpOnMainThread() override {
558     base::FilePath user_data_directory;
559     PathService::Get(chrome::DIR_USER_DATA, &user_data_directory);
560     user_manager::UserManager::Get()->UserLoggedIn(
561         kSecondProfileAccount, kSecondProfileHash, false);
562     // Set up the secondary profile.
563     base::FilePath profile_dir =
564         user_data_directory.Append(
565             chromeos::ProfileHelper::GetUserProfileDir(
566                 kSecondProfileHash).BaseName());
567     second_profile =
568         g_browser_process->profile_manager()->GetProfile(profile_dir);
569
570     FileSystemExtensionApiTestBase::SetUpOnMainThread();
571   }
572
573   virtual void InitTestFileSystem() override {
574     // This callback will get called during Profile creation.
575     create_drive_integration_service_ = base::Bind(
576         &MultiProfileDriveFileSystemExtensionApiTest::
577             CreateDriveIntegrationService,
578         base::Unretained(this));
579     service_factory_for_test_.reset(
580         new DriveIntegrationServiceFactory::ScopedFactoryForTest(
581             &create_drive_integration_service_));
582   }
583
584   virtual void AddTestMountPoint() override {
585     test_util::WaitUntilDriveMountPointIsAdded(browser()->profile());
586     test_util::WaitUntilDriveMountPointIsAdded(second_profile);
587   }
588
589  protected:
590   // DriveIntegrationService factory function for this test.
591   drive::DriveIntegrationService* CreateDriveIntegrationService(
592       Profile* profile) {
593     base::FilePath cache_dir;
594     base::CreateNewTempDirectory(base::FilePath::StringType(), &cache_dir);
595
596     drive::FakeDriveService* const fake_drive_service =
597         new drive::FakeDriveService;
598     fake_drive_service->LoadAppListForDriveApi("drive/applist.json");
599     EXPECT_TRUE(InitializeDriveService(fake_drive_service, &resource_ids_));
600
601     return new drive::DriveIntegrationService(
602         profile, NULL, fake_drive_service, std::string(), cache_dir, NULL);
603   }
604
605   bool AddTestHostedDocuments() {
606     const char kResourceId[] = "unique-id-for-multiprofile-copy-test";
607     drive::FakeDriveService* const main_service =
608         static_cast<drive::FakeDriveService*>(
609             drive::util::GetDriveServiceByProfile(browser()->profile()));
610     drive::FakeDriveService* const sub_service =
611         static_cast<drive::FakeDriveService*>(
612             drive::util::GetDriveServiceByProfile(second_profile));
613
614     google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
615     scoped_ptr<google_apis::FileResource> entry;
616
617     // Place a hosted document under root/test_dir of the sub profile.
618     sub_service->AddNewFileWithResourceId(
619         kResourceId,
620         "application/vnd.google-apps.document", "",
621         resource_ids_["test_dir"], "hosted_doc", true,
622         google_apis::test_util::CreateCopyResultCallback(&error, &entry));
623     content::RunAllBlockingPoolTasksUntilIdle();
624     if (error != google_apis::HTTP_CREATED)
625       return false;
626
627     // Place the hosted document with no parent in the main profile, for
628     // simulating the situation that the document is shared to the main profile.
629     error = google_apis::GDATA_OTHER_ERROR;
630     main_service->AddNewFileWithResourceId(
631         kResourceId,
632         "application/vnd.google-apps.document", "", "", "hosted_doc", true,
633         google_apis::test_util::CreateCopyResultCallback(&error, &entry));
634     content::RunAllBlockingPoolTasksUntilIdle();
635     return (error == google_apis::HTTP_CREATED);
636   }
637
638   DriveIntegrationServiceFactory::FactoryCallback
639       create_drive_integration_service_;
640   scoped_ptr<DriveIntegrationServiceFactory::ScopedFactoryForTest>
641       service_factory_for_test_;
642   Profile* second_profile;
643   std::map<std::string, std::string> resource_ids_;
644 };
645
646 class LocalAndDriveFileSystemExtensionApiTest
647     : public FileSystemExtensionApiTestBase {
648  public:
649   LocalAndDriveFileSystemExtensionApiTest() {}
650   virtual ~LocalAndDriveFileSystemExtensionApiTest() {}
651
652   // FileSystemExtensionApiTestBase override.
653   virtual void InitTestFileSystem() override {
654     ASSERT_TRUE(InitializeLocalFileSystem(
655         kLocalMountPointName, &local_tmp_dir_, &local_mount_point_dir_))
656         << "Failed to initialize file system.";
657
658     // Set up cache root to be used by DriveIntegrationService. This has to be
659     // done before the browser is created because the service instance is
660     // initialized by EventRouter.
661     ASSERT_TRUE(test_cache_root_.CreateUniqueTempDir());
662
663     // This callback will get called during Profile creation.
664     create_drive_integration_service_ = base::Bind(
665         &LocalAndDriveFileSystemExtensionApiTest::CreateDriveIntegrationService,
666         base::Unretained(this));
667     service_factory_for_test_.reset(
668         new DriveIntegrationServiceFactory::ScopedFactoryForTest(
669             &create_drive_integration_service_));
670   }
671
672   // FileSystemExtensionApiTestBase override.
673   virtual void AddTestMountPoint() override {
674     EXPECT_TRUE(content::BrowserContext::GetMountPoints(browser()->profile())
675                     ->RegisterFileSystem(kLocalMountPointName,
676                                          storage::kFileSystemTypeNativeLocal,
677                                          storage::FileSystemMountOption(),
678                                          local_mount_point_dir_));
679     VolumeManager::Get(browser()->profile())
680         ->AddVolumeInfoForTesting(local_mount_point_dir_,
681                                   VOLUME_TYPE_TESTING,
682                                   chromeos::DEVICE_TYPE_UNKNOWN);
683     test_util::WaitUntilDriveMountPointIsAdded(browser()->profile());
684   }
685
686  protected:
687   // DriveIntegrationService factory function for this test.
688   drive::DriveIntegrationService* CreateDriveIntegrationService(
689       Profile* profile) {
690     fake_drive_service_ = new drive::FakeDriveService;
691     fake_drive_service_->LoadAppListForDriveApi("drive/applist.json");
692
693     std::map<std::string, std::string> resource_ids;
694     EXPECT_TRUE(InitializeDriveService(fake_drive_service_, &resource_ids));
695
696     return new drive::DriveIntegrationService(profile,
697                                               NULL,
698                                               fake_drive_service_,
699                                               "drive",
700                                               test_cache_root_.path(),
701                                               NULL);
702   }
703
704  private:
705   // For local volume.
706   base::ScopedTempDir local_tmp_dir_;
707   base::FilePath local_mount_point_dir_;
708
709   // For drive volume.
710   base::ScopedTempDir test_cache_root_;
711   drive::FakeDriveService* fake_drive_service_;
712   DriveIntegrationServiceFactory::FactoryCallback
713       create_drive_integration_service_;
714   scoped_ptr<DriveIntegrationServiceFactory::ScopedFactoryForTest>
715       service_factory_for_test_;
716 };
717
718 //
719 // LocalFileSystemExtensionApiTests.
720 //
721
722 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest, FileSystemOperations) {
723   EXPECT_TRUE(RunFileSystemExtensionApiTest(
724       "file_browser/filesystem_operations_test",
725       FILE_PATH_LITERAL("manifest.json"),
726       "",
727       FLAGS_NONE)) << message_;
728 }
729
730 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest, FileWatch) {
731   EXPECT_TRUE(RunFileSystemExtensionApiTest(
732       "file_browser/file_watcher_test",
733       FILE_PATH_LITERAL("manifest.json"),
734       "",
735       FLAGS_NONE)) << message_;
736 }
737
738 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest, FileBrowserHandlers) {
739   EXPECT_TRUE(RunFileSystemExtensionApiTest(
740       "file_browser/handler_test_runner",
741       FILE_PATH_LITERAL("manifest.json"),
742       "file_browser/file_browser_handler",
743       FLAGS_USE_FILE_HANDLER)) << message_;
744 }
745
746 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest,
747                        FileBrowserHandlersLazy) {
748   EXPECT_TRUE(RunFileSystemExtensionApiTest(
749       "file_browser/handler_test_runner",
750       FILE_PATH_LITERAL("manifest.json"),
751       "file_browser/file_browser_handler_lazy",
752       FLAGS_USE_FILE_HANDLER | FLAGS_LAZY_FILE_HANDLER)) << message_;
753 }
754
755 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest, AppFileHandler) {
756   EXPECT_TRUE(RunFileSystemExtensionApiTest(
757       "file_browser/handler_test_runner",
758       FILE_PATH_LITERAL("manifest.json"),
759       "file_browser/app_file_handler",
760       FLAGS_USE_FILE_HANDLER)) << message_;
761 }
762
763 //
764 // RestrictedFileSystemExtensionApiTests.
765 //
766 IN_PROC_BROWSER_TEST_F(RestrictedFileSystemExtensionApiTest,
767                        FileSystemOperations) {
768   EXPECT_TRUE(RunFileSystemExtensionApiTest(
769       "file_browser/filesystem_operations_test",
770       FILE_PATH_LITERAL("manifest.json"),
771       "",
772       FLAGS_NONE)) << message_;
773 }
774
775 //
776 // DriveFileSystemExtensionApiTests.
777 //
778 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, FileSystemOperations) {
779   EXPECT_TRUE(RunFileSystemExtensionApiTest(
780       "file_browser/filesystem_operations_test",
781       FILE_PATH_LITERAL("manifest.json"),
782       "",
783       FLAGS_NONE)) << message_;
784 }
785
786 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, FileWatch) {
787   EXPECT_TRUE(RunFileSystemExtensionApiTest(
788       "file_browser/file_watcher_test",
789       FILE_PATH_LITERAL("manifest.json"),
790       "",
791       FLAGS_NONE)) << message_;
792 }
793
794 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, FileBrowserHandlers) {
795   EXPECT_TRUE(RunFileSystemExtensionApiTest(
796       "file_browser/handler_test_runner",
797       FILE_PATH_LITERAL("manifest.json"),
798       "file_browser/file_browser_handler",
799       FLAGS_USE_FILE_HANDLER)) << message_;
800 }
801
802 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, Search) {
803   // Configure the drive service to return only one search result at a time
804   // to simulate paginated searches.
805   fake_drive_service_->set_default_max_results(1);
806   EXPECT_TRUE(RunFileSystemExtensionApiTest(
807       "file_browser/drive_search_test",
808       FILE_PATH_LITERAL("manifest.json"),
809       "",
810       FLAGS_NONE)) << message_;
811 }
812
813 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, AppFileHandler) {
814   EXPECT_TRUE(RunFileSystemExtensionApiTest(
815       "file_browser/handler_test_runner",
816       FILE_PATH_LITERAL("manifest.json"),
817       "file_browser/app_file_handler",
818       FLAGS_USE_FILE_HANDLER)) << message_;
819 }
820
821 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, RetainEntry) {
822   ui::SelectFileDialog::SetFactory(new FakeSelectFileDialogFactory());
823   EXPECT_TRUE(RunFileSystemExtensionApiTest("file_browser/retain_entry",
824                                             FILE_PATH_LITERAL("manifest.json"),
825                                             "",
826                                             FLAGS_NONE))
827       << message_;
828 }
829
830 IN_PROC_BROWSER_TEST_F(MultiProfileDriveFileSystemExtensionApiTest,
831                        CrossProfileCopy) {
832   ASSERT_TRUE(AddTestHostedDocuments());
833   EXPECT_TRUE(RunFileSystemExtensionApiTest(
834       "file_browser/multi_profile_copy",
835       FILE_PATH_LITERAL("manifest.json"),
836       "",
837       FLAGS_NONE)) << message_;
838 }
839
840 //
841 // LocalAndDriveFileSystemExtensionApiTests.
842 //
843 IN_PROC_BROWSER_TEST_F(LocalAndDriveFileSystemExtensionApiTest,
844                        AppFileHandlerMulti) {
845   EXPECT_TRUE(
846       RunFileSystemExtensionApiTest("file_browser/app_file_handler_multi",
847                                     FILE_PATH_LITERAL("manifest.json"),
848                                     "",
849                                     FLAGS_NONE))
850       << message_;
851 }
852 }  // namespace
853 }  // namespace file_manager