Upstream version 5.34.104.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/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"
21
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
32 //   Drive.
33 //
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
37 //   extension).
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).
45
46 using drive::DriveIntegrationServiceFactory;
47 using extensions::Extension;
48
49 namespace file_manager {
50 namespace {
51
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";
58
59 // Default file content for the test files.
60 const char kTestFileContent[] = "This is some test content.";
61
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/
65 //              |
66 //               - empty_test_dir/
67 //              |
68 //               - empty_test_file.foo
69 //              |
70 //               - test_file.xul
71 //              |
72 //               - test_file.xul.foo
73 //              |
74 //               - test_file.tiff
75 //              |
76 //               - test_file.tiff.foo
77 //
78 // All files except test_dir/empty_file.foo, which is empty, initially contain
79 // kTestFileContent.
80 const char kTestRootFeed[] =
81     "gdata/remote_file_system_apitest_root_feed.json";
82
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())
88     return false;
89
90   *mount_point_dir = tmp_dir->path().AppendASCII("mount");
91   // Create the mount point.
92   if (!base::CreateDirectory(*mount_point_dir))
93     return false;
94
95   base::FilePath test_dir = mount_point_dir->AppendASCII("test_dir");
96   if (!base::CreateDirectory(test_dir))
97     return false;
98
99   base::FilePath test_subdir = test_dir.AppendASCII("empty_test_dir");
100   if (!base::CreateDirectory(test_subdir))
101     return false;
102
103   test_subdir = test_dir.AppendASCII("subdir");
104   if (!base::CreateDirectory(test_subdir))
105     return false;
106
107   base::FilePath test_file = test_dir.AppendASCII("test_file.xul");
108   if (!google_apis::test_util::WriteStringToFile(test_file, kTestFileContent))
109     return false;
110
111   test_file = test_dir.AppendASCII("test_file.xul.foo");
112   if (!google_apis::test_util::WriteStringToFile(test_file, kTestFileContent))
113     return false;
114
115   test_file = test_dir.AppendASCII("test_file.tiff");
116   if (!google_apis::test_util::WriteStringToFile(test_file, kTestFileContent))
117     return false;
118
119   test_file = test_dir.AppendASCII("test_file.tiff.foo");
120   if (!google_apis::test_util::WriteStringToFile(test_file, kTestFileContent))
121     return false;
122
123   test_file = test_dir.AppendASCII("empty_test_file.foo");
124   if (!google_apis::test_util::WriteStringToFile(test_file, ""))
125     return false;
126
127   return true;
128 }
129
130 // Helper class to wait for a background page to load or close again.
131 class BackgroundObserver {
132  public:
133   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()) {
138   }
139
140   void WaitUntilLoaded() {
141     page_created_.Wait();
142   }
143
144   void WaitUntilClosed() {
145     page_closed_.Wait();
146   }
147
148  private:
149   content::WindowedNotificationObserver page_created_;
150   content::WindowedNotificationObserver page_closed_;
151 };
152
153 // Base class for FileSystemExtensionApi tests.
154 class FileSystemExtensionApiTestBase : public ExtensionApiTest {
155  public:
156   enum Flags {
157     FLAGS_NONE = 0,
158     FLAGS_USE_FILE_HANDLER = 1 << 1,
159     FLAGS_LAZY_FILE_HANDLER = 1 << 2
160   };
161
162   FileSystemExtensionApiTestBase() {}
163   virtual ~FileSystemExtensionApiTestBase() {}
164
165   virtual void SetUp() OVERRIDE {
166     InitTestFileSystem();
167     ExtensionApiTest::SetUp();
168   }
169
170   virtual void SetUpOnMainThread() OVERRIDE {
171     AddTestMountPoint();
172     ExtensionApiTest::SetUpOnMainThread();
173   }
174
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
187   // message.
188   bool RunFileSystemExtensionApiTest(
189       const std::string& filebrowser_path,
190       const base::FilePath::CharType* filebrowser_manifest,
191       const std::string& filehandler_path,
192       int flags) {
193     if (flags & FLAGS_USE_FILE_HANDLER) {
194       if (filehandler_path.empty()) {
195         message_ = "Missing file handler path.";
196         return false;
197       }
198
199       BackgroundObserver page_complete;
200       const Extension* file_handler =
201           LoadExtension(test_data_dir_.AppendASCII(filehandler_path));
202       if (!file_handler)
203         return false;
204
205       if (flags & FLAGS_LAZY_FILE_HANDLER) {
206         page_complete.WaitUntilClosed();
207       } else {
208         page_complete.WaitUntilLoaded();
209       }
210     }
211
212     ResultCatcher catcher;
213
214     const Extension* file_browser = LoadExtensionAsComponentWithManifest(
215         test_data_dir_.AppendASCII(filebrowser_path),
216         filebrowser_manifest);
217     if (!file_browser)
218       return false;
219
220     if (!catcher.GetNextResult()) {
221       message_ = catcher.message();
222       return false;
223     }
224
225     return true;
226   }
227
228  protected:
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;
234 };
235
236 // Tests for a native local file system.
237 class LocalFileSystemExtensionApiTest : public FileSystemExtensionApiTestBase {
238  public:
239   LocalFileSystemExtensionApiTest() {}
240   virtual ~LocalFileSystemExtensionApiTest() {}
241
242   // FileSystemExtensionApiTestBase OVERRIDE.
243   virtual void InitTestFileSystem() OVERRIDE {
244     ASSERT_TRUE(InitializeLocalFileSystem(&tmp_dir_, &mount_point_dir_))
245         << "Failed to initialize file system.";
246   }
247
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(),
254                            mount_point_dir_));
255   }
256
257  private:
258   base::ScopedTempDir tmp_dir_;
259   base::FilePath mount_point_dir_;
260 };
261
262 // Tests for restricted native local file systems.
263 class RestrictedFileSystemExtensionApiTest
264     : public FileSystemExtensionApiTestBase {
265  public:
266   RestrictedFileSystemExtensionApiTest() {}
267   virtual ~RestrictedFileSystemExtensionApiTest() {}
268
269   // FileSystemExtensionApiTestBase OVERRIDE.
270   virtual void InitTestFileSystem() OVERRIDE {
271     ASSERT_TRUE(InitializeLocalFileSystem(&tmp_dir_, &mount_point_dir_))
272         << "Failed to initialize file system.";
273   }
274
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(),
281                            mount_point_dir_));
282   }
283
284  private:
285   base::ScopedTempDir tmp_dir_;
286   base::FilePath mount_point_dir_;
287 };
288
289 // Tests for a drive file system.
290 class DriveFileSystemExtensionApiTest : public FileSystemExtensionApiTestBase {
291  public:
292   DriveFileSystemExtensionApiTest() : fake_drive_service_(NULL) {}
293   virtual ~DriveFileSystemExtensionApiTest() {}
294
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());
301
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_));
309   }
310
311   // FileSystemExtensionApiTestBase OVERRIDE.
312   virtual void AddTestMountPoint() OVERRIDE {
313     test_util::WaitUntilDriveMountPointIsAdded(browser()->profile());
314   }
315
316  protected:
317   // DriveIntegrationService factory function for this test.
318   drive::DriveIntegrationService* CreateDriveIntegrationService(
319       Profile* profile) {
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");
325
326     return new drive::DriveIntegrationService(
327         profile, NULL,
328         fake_drive_service_, "drive", test_cache_root_.path(), NULL);
329   }
330
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_;
337 };
338
339 //
340 // LocalFileSystemExtensionApiTests.
341 //
342
343 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest, FileSystemOperations) {
344   EXPECT_TRUE(RunFileSystemExtensionApiTest(
345       "file_browser/filesystem_operations_test",
346       FILE_PATH_LITERAL("manifest.json"),
347       "",
348       FLAGS_NONE)) << message_;
349 }
350
351 IN_PROC_BROWSER_TEST_F(LocalFileSystemExtensionApiTest, FileWatch) {
352   EXPECT_TRUE(RunFileSystemExtensionApiTest(
353       "file_browser/file_watcher_test",
354       FILE_PATH_LITERAL("manifest.json"),
355       "",
356       FLAGS_NONE)) << message_;
357 }
358
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_;
365 }
366
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_;
374 }
375
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_;
382 }
383
384 //
385 // RestrictedFileSystemExtensionApiTests.
386 //
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"),
392       "",
393       FLAGS_NONE)) << message_;
394 }
395
396 //
397 // DriveFileSystemExtensionApiTests.
398 //
399 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, FileSystemOperations) {
400   EXPECT_TRUE(RunFileSystemExtensionApiTest(
401       "file_browser/filesystem_operations_test",
402       FILE_PATH_LITERAL("manifest.json"),
403       "",
404       FLAGS_NONE)) << message_;
405 }
406
407 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest, FileWatch) {
408   EXPECT_TRUE(RunFileSystemExtensionApiTest(
409       "file_browser/file_watcher_test",
410       FILE_PATH_LITERAL("manifest.json"),
411       "",
412       FLAGS_NONE)) << message_;
413 }
414
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_;
421 }
422
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"),
430       "",
431       FLAGS_NONE)) << message_;
432 }
433
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_;
441 }
442
443 }  // namespace
444 }  // namespace file_manager