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.
6 #include "base/file_util.h"
7 #include "base/files/file_path.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
11 #include "chrome/browser/chromeos/file_manager/drive_test_util.h"
12 #include "chrome/browser/drive/fake_drive_service.h"
13 #include "chrome/browser/extensions/extension_apitest.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "content/public/browser/browser_context.h"
17 #include "content/public/browser/notification_service.h"
18 #include "content/public/test/test_utils.h"
19 #include "google_apis/drive/test_util.h"
20 #include "webkit/browser/fileapi/external_mount_points.h"
22 // Tests for access to external file systems (as defined in
23 // webkit/common/fileapi/file_system_types.h) from extensions with
24 // fileBrowserPrivate and fileBrowserHandler extension permissions.
25 // The tests cover following external file system types:
26 // - local (kFileSystemTypeLocalNative): a local file system on which files are
27 // accessed using native local path.
28 // - restricted (kFileSystemTypeRestrictedLocalNative): a *read-only* local file
29 // system which can only be accessed by extensions that have full access to
30 // external file systems (i.e. extensions with fileBrowserPrivate permission).
31 // - drive (kFileSystemTypeDrive): a file system that provides access to Google
34 // The tests cover following scenarios:
35 // - Performing file system operations on external file systems from an
36 // extension with fileBrowserPrivate permission (i.e. a file browser
38 // - Performing read/write operations from file handler extensions. These
39 // extensions need a file browser extension to give them permissions to access
40 // files. This also includes file handler extensions in filesystem API.
41 // - Observing directory changes from a file browser extension (using
42 // fileBrowserPrivate API).
43 // - Doing searches on drive file system from file browser extension (using
44 // fileBrowserPrivate API).
46 using drive::DriveIntegrationServiceFactory;
47 using extensions::Extension;
49 namespace file_manager {
52 // Root dirs for file systems expected by the test extensions.
53 // NOTE: Root dir for drive file system is set by Chrome's drive implementation,
54 // but the test will have to make sure the mount point is added before
55 // starting a test extension using WaitUntilDriveMountPointIsAdded().
56 const char kLocalMountPointName[] = "local";
57 const char kRestrictedMountPointName[] = "restricted";
59 // Default file content for the test files.
60 const char kTestFileContent[] = "This is some test content.";
62 // Contains feed for drive file system. The file system hierarchy is the same
63 // for local and restricted file systems:
64 // test_dir/ - - subdir/
68 // - empty_test_file.foo
72 // - test_file.xul.foo
76 // - test_file.tiff.foo
78 // All files except test_dir/empty_file.foo, which is empty, initially contain
80 const char kTestRootFeed[] =
81 "gdata/remote_file_system_apitest_root_feed.json";
83 // Sets up the initial file system state for native local and restricted native
84 // local file systems. The hierarchy is the same as for the drive file system.
85 bool InitializeLocalFileSystem(base::ScopedTempDir* tmp_dir,
86 base::FilePath* mount_point_dir) {
87 if (!tmp_dir->CreateUniqueTempDir())
90 *mount_point_dir = tmp_dir->path().AppendASCII("mount");
91 // Create the mount point.
92 if (!base::CreateDirectory(*mount_point_dir))
95 base::FilePath test_dir = mount_point_dir->AppendASCII("test_dir");
96 if (!base::CreateDirectory(test_dir))
99 base::FilePath test_subdir = test_dir.AppendASCII("empty_test_dir");
100 if (!base::CreateDirectory(test_subdir))
103 test_subdir = test_dir.AppendASCII("subdir");
104 if (!base::CreateDirectory(test_subdir))
107 base::FilePath test_file = test_dir.AppendASCII("test_file.xul");
108 if (!google_apis::test_util::WriteStringToFile(test_file, kTestFileContent))
111 test_file = test_dir.AppendASCII("test_file.xul.foo");
112 if (!google_apis::test_util::WriteStringToFile(test_file, kTestFileContent))
115 test_file = test_dir.AppendASCII("test_file.tiff");
116 if (!google_apis::test_util::WriteStringToFile(test_file, kTestFileContent))
119 test_file = test_dir.AppendASCII("test_file.tiff.foo");
120 if (!google_apis::test_util::WriteStringToFile(test_file, kTestFileContent))
123 test_file = test_dir.AppendASCII("empty_test_file.foo");
124 if (!google_apis::test_util::WriteStringToFile(test_file, ""))
130 // Helper class to wait for a background page to load or close again.
131 class BackgroundObserver {
134 : page_created_(chrome::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY,
135 content::NotificationService::AllSources()),
136 page_closed_(chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED,
137 content::NotificationService::AllSources()) {
140 void WaitUntilLoaded() {
141 page_created_.Wait();
144 void WaitUntilClosed() {
149 content::WindowedNotificationObserver page_created_;
150 content::WindowedNotificationObserver page_closed_;
153 // Base class for FileSystemExtensionApi tests.
154 class FileSystemExtensionApiTestBase : public ExtensionApiTest {
158 FLAGS_USE_FILE_HANDLER = 1 << 1,
159 FLAGS_LAZY_FILE_HANDLER = 1 << 2
162 FileSystemExtensionApiTestBase() {}
163 virtual ~FileSystemExtensionApiTestBase() {}
165 virtual void SetUp() OVERRIDE {
166 InitTestFileSystem();
167 ExtensionApiTest::SetUp();
170 virtual void SetUpOnMainThread() OVERRIDE {
172 ExtensionApiTest::SetUpOnMainThread();
175 // Runs a file system extension API test.
176 // It loads test component extension at |filebrowser_path| with manifest
177 // at |filebrowser_manifest|. The |filebrowser_manifest| should be a path
178 // relative to |filebrowser_path|. The method waits until the test extension
179 // sends test succeed or fail message. It returns true if the test succeeds.
180 // If |FLAGS_USE_FILE_HANDLER| flag is set, the file handler extension at path
181 // |filehandler_path| will be loaded before the file browser extension.
182 // If the flag FLAGS_LAZY_FILE_HANDLER is set, the file handler extension must
183 // not have persistent background page. The test will wait until the file
184 // handler's background page is closed after initial load before the file
185 // browser extension is loaded.
186 // If |RunFileSystemExtensionApiTest| fails, |message_| will contain a failure
188 bool RunFileSystemExtensionApiTest(
189 const std::string& filebrowser_path,
190 const base::FilePath::CharType* filebrowser_manifest,
191 const std::string& filehandler_path,
193 if (flags & FLAGS_USE_FILE_HANDLER) {
194 if (filehandler_path.empty()) {
195 message_ = "Missing file handler path.";
199 BackgroundObserver page_complete;
200 const Extension* file_handler =
201 LoadExtension(test_data_dir_.AppendASCII(filehandler_path));
205 if (flags & FLAGS_LAZY_FILE_HANDLER) {
206 page_complete.WaitUntilClosed();
208 page_complete.WaitUntilLoaded();
212 ResultCatcher catcher;
214 const Extension* file_browser = LoadExtensionAsComponentWithManifest(
215 test_data_dir_.AppendASCII(filebrowser_path),
216 filebrowser_manifest);
220 if (!catcher.GetNextResult()) {
221 message_ = catcher.message();
229 // Sets up initial test file system hierarchy. See comment for kTestRootFeed
230 // for the actual hierarchy.
231 virtual void InitTestFileSystem() = 0;
232 // Registers mount point used in the test.
233 virtual void AddTestMountPoint() = 0;
236 // Tests for a native local file system.
237 class LocalFileSystemExtensionApiTest : public FileSystemExtensionApiTestBase {
239 LocalFileSystemExtensionApiTest() {}
240 virtual ~LocalFileSystemExtensionApiTest() {}
242 // FileSystemExtensionApiTestBase OVERRIDE.
243 virtual void InitTestFileSystem() OVERRIDE {
244 ASSERT_TRUE(InitializeLocalFileSystem(&tmp_dir_, &mount_point_dir_))
245 << "Failed to initialize file system.";
248 // FileSystemExtensionApiTestBase OVERRIDE.
249 virtual void AddTestMountPoint() OVERRIDE {
250 EXPECT_TRUE(content::BrowserContext::GetMountPoints(browser()->profile())->
251 RegisterFileSystem(kLocalMountPointName,
252 fileapi::kFileSystemTypeNativeLocal,
253 fileapi::FileSystemMountOption(),
258 base::ScopedTempDir tmp_dir_;
259 base::FilePath mount_point_dir_;
262 // Tests for restricted native local file systems.
263 class RestrictedFileSystemExtensionApiTest
264 : public FileSystemExtensionApiTestBase {
266 RestrictedFileSystemExtensionApiTest() {}
267 virtual ~RestrictedFileSystemExtensionApiTest() {}
269 // FileSystemExtensionApiTestBase OVERRIDE.
270 virtual void InitTestFileSystem() OVERRIDE {
271 ASSERT_TRUE(InitializeLocalFileSystem(&tmp_dir_, &mount_point_dir_))
272 << "Failed to initialize file system.";
275 // FileSystemExtensionApiTestBase OVERRIDE.
276 virtual void AddTestMountPoint() OVERRIDE {
277 EXPECT_TRUE(content::BrowserContext::GetMountPoints(browser()->profile())->
278 RegisterFileSystem(kRestrictedMountPointName,
279 fileapi::kFileSystemTypeRestrictedNativeLocal,
280 fileapi::FileSystemMountOption(),
285 base::ScopedTempDir tmp_dir_;
286 base::FilePath mount_point_dir_;
289 // Tests for a drive file system.
290 class DriveFileSystemExtensionApiTest : public FileSystemExtensionApiTestBase {
292 DriveFileSystemExtensionApiTest() : fake_drive_service_(NULL) {}
293 virtual ~DriveFileSystemExtensionApiTest() {}
295 // FileSystemExtensionApiTestBase OVERRIDE.
296 virtual void InitTestFileSystem() OVERRIDE {
297 // Set up cache root to be used by DriveIntegrationService. This has to be
298 // done before the browser is created because the service instance is
299 // initialized by EventRouter.
300 ASSERT_TRUE(test_cache_root_.CreateUniqueTempDir());
302 // This callback will get called during Profile creation.
303 create_drive_integration_service_ = base::Bind(
304 &DriveFileSystemExtensionApiTest::CreateDriveIntegrationService,
305 base::Unretained(this));
306 service_factory_for_test_.reset(
307 new DriveIntegrationServiceFactory::ScopedFactoryForTest(
308 &create_drive_integration_service_));
311 // FileSystemExtensionApiTestBase OVERRIDE.
312 virtual void AddTestMountPoint() OVERRIDE {
313 test_util::WaitUntilDriveMountPointIsAdded(browser()->profile());
317 // DriveIntegrationService factory function for this test.
318 drive::DriveIntegrationService* CreateDriveIntegrationService(
320 fake_drive_service_ = new drive::FakeDriveService;
321 fake_drive_service_->LoadResourceListForWapi(kTestRootFeed);
322 fake_drive_service_->LoadAccountMetadataForWapi(
323 "gdata/account_metadata.json");
324 fake_drive_service_->LoadAppListForDriveApi("drive/applist.json");
326 return new drive::DriveIntegrationService(
328 fake_drive_service_, "drive", test_cache_root_.path(), NULL);
331 base::ScopedTempDir test_cache_root_;
332 drive::FakeDriveService* fake_drive_service_;
333 DriveIntegrationServiceFactory::FactoryCallback
334 create_drive_integration_service_;
335 scoped_ptr<DriveIntegrationServiceFactory::ScopedFactoryForTest>
336 service_factory_for_test_;
340 // LocalFileSystemExtensionApiTests.
343 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest, FileSystemOperations) {
344 EXPECT_TRUE(RunFileSystemExtensionApiTest(
345 "file_browser/filesystem_operations_test",
346 FILE_PATH_LITERAL("manifest.json"),
348 FLAGS_NONE)) << message_;
351 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest, FileWatch) {
352 EXPECT_TRUE(RunFileSystemExtensionApiTest(
353 "file_browser/file_watcher_test",
354 FILE_PATH_LITERAL("manifest.json"),
356 FLAGS_NONE)) << message_;
359 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest, FileBrowserHandlers) {
360 EXPECT_TRUE(RunFileSystemExtensionApiTest(
361 "file_browser/handler_test_runner",
362 FILE_PATH_LITERAL("manifest.json"),
363 "file_browser/file_browser_handler",
364 FLAGS_USE_FILE_HANDLER)) << message_;
367 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest,
368 FileBrowserHandlersLazy) {
369 EXPECT_TRUE(RunFileSystemExtensionApiTest(
370 "file_browser/handler_test_runner",
371 FILE_PATH_LITERAL("manifest.json"),
372 "file_browser/file_browser_handler_lazy",
373 FLAGS_USE_FILE_HANDLER | FLAGS_LAZY_FILE_HANDLER)) << message_;
376 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest, AppFileHandler) {
377 EXPECT_TRUE(RunFileSystemExtensionApiTest(
378 "file_browser/handler_test_runner",
379 FILE_PATH_LITERAL("manifest.json"),
380 "file_browser/app_file_handler",
381 FLAGS_USE_FILE_HANDLER)) << message_;
385 // RestrictedFileSystemExtensionApiTests.
387 IN_PROC_BROWSER_TEST_F(RestrictedFileSystemExtensionApiTest,
388 FileSystemOperations) {
389 EXPECT_TRUE(RunFileSystemExtensionApiTest(
390 "file_browser/filesystem_operations_test",
391 FILE_PATH_LITERAL("manifest.json"),
393 FLAGS_NONE)) << message_;
397 // DriveFileSystemExtensionApiTests.
399 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, FileSystemOperations) {
400 EXPECT_TRUE(RunFileSystemExtensionApiTest(
401 "file_browser/filesystem_operations_test",
402 FILE_PATH_LITERAL("manifest.json"),
404 FLAGS_NONE)) << message_;
407 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, FileWatch) {
408 EXPECT_TRUE(RunFileSystemExtensionApiTest(
409 "file_browser/file_watcher_test",
410 FILE_PATH_LITERAL("manifest.json"),
412 FLAGS_NONE)) << message_;
415 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, FileBrowserHandlers) {
416 EXPECT_TRUE(RunFileSystemExtensionApiTest(
417 "file_browser/handler_test_runner",
418 FILE_PATH_LITERAL("manifest.json"),
419 "file_browser/file_browser_handler",
420 FLAGS_USE_FILE_HANDLER)) << message_;
423 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, Search) {
424 // Configure the drive service to return only one search result at a time
425 // to simulate paginated searches.
426 fake_drive_service_->set_default_max_results(1);
427 EXPECT_TRUE(RunFileSystemExtensionApiTest(
428 "file_browser/drive_search_test",
429 FILE_PATH_LITERAL("manifest.json"),
431 FLAGS_NONE)) << message_;
434 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, AppFileHandler) {
435 fake_drive_service_->set_default_max_results(1);
436 EXPECT_TRUE(RunFileSystemExtensionApiTest(
437 "file_browser/handler_test_runner",
438 FILE_PATH_LITERAL("manifest.json"),
439 "file_browser/app_file_handler",
440 FLAGS_USE_FILE_HANDLER)) << message_;
444 } // namespace file_manager