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