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