Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / extensions / api / file_system / file_system_apitest_chromeos.cc
blobca86c43deabb5c967ac635cde4340f3c8606456a
1 // Copyright 2014 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.
5 #include "chrome/browser/extensions/api/file_system/file_system_api.h"
7 #include "base/callback.h"
8 #include "base/files/file_util.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/location.h"
11 #include "base/path_service.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "chrome/browser/apps/app_browsertest_util.h"
14 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
15 #include "chrome/browser/chromeos/drive/file_system_util.h"
16 #include "chrome/browser/chromeos/file_manager/volume_manager.h"
17 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
18 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
19 #include "chrome/browser/chromeos/profiles/profile_helper.h"
20 #include "chrome/browser/extensions/component_loader.h"
21 #include "chrome/common/chrome_paths.h"
22 #include "chrome/common/extensions/api/file_system.h"
23 #include "components/drive/file_system_interface.h"
24 #include "components/drive/service/fake_drive_service.h"
25 #include "content/public/test/test_utils.h"
26 #include "extensions/browser/event_router.h"
27 #include "google_apis/drive/drive_api_parser.h"
28 #include "google_apis/drive/test_util.h"
29 #include "storage/browser/fileapi/external_mount_points.h"
30 #include "ui/base/ui_base_types.h"
32 using file_manager::VolumeManager;
34 namespace extensions {
35 namespace {
37 // Mount point names for chrome.fileSystem.requestFileSystem() tests.
38 const char kWritableMountPointName[] = "writable";
39 const char kReadOnlyMountPointName[] = "read-only";
41 // Child directory created in each of the mount points.
42 const char kChildDirectory[] = "child-dir";
44 // ID of a testing extension.
45 const char kTestingExtensionId[] = "pkplfbidichfdicaijlchgnapepdginl";
47 } // namespace
49 // Skips the user consent dialog for chrome.fileSystem.requestFileSystem() and
50 // simulates clicking of the specified dialog button.
51 class ScopedSkipRequestFileSystemDialog {
52 public:
53 explicit ScopedSkipRequestFileSystemDialog(ui::DialogButton button) {
54 file_system_api::ConsentProviderDelegate::SetAutoDialogButtonForTest(
55 button);
57 ~ScopedSkipRequestFileSystemDialog() {
58 file_system_api::ConsentProviderDelegate::SetAutoDialogButtonForTest(
59 ui::DIALOG_BUTTON_NONE);
62 private:
63 DISALLOW_COPY_AND_ASSIGN(ScopedSkipRequestFileSystemDialog);
66 // Observers adding a listener to the |event_name| event by |extension|, and
67 // then fires the |callback|.
68 class ScopedAddListenerObserver : public EventRouter::Observer {
69 public:
70 ScopedAddListenerObserver(Profile* profile,
71 const std::string& event_name,
72 const std::string& extension_id,
73 const base::Closure& callback)
74 : extension_id_(extension_id),
75 callback_(callback),
76 event_router_(EventRouter::EventRouter::Get(profile)) {
77 DCHECK(profile);
78 DCHECK(event_router_);
79 event_router_->RegisterObserver(this, event_name);
82 ~ScopedAddListenerObserver() { event_router_->UnregisterObserver(this); }
84 // EventRouter::Observer overrides.
85 void OnListenerAdded(const EventListenerInfo& details) override {
86 // Call the callback only once, as the listener may be added multiple times.
87 if (details.extension_id == extension_id_ && !callback_.is_null()) {
88 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback_);
89 callback_ = base::Closure();
93 private:
94 const std::string extension_id_;
95 base::Closure callback_;
96 EventRouter* const event_router_;
98 DISALLOW_COPY_AND_ASSIGN(ScopedAddListenerObserver);
101 // This class contains chrome.filesystem API test specific to Chrome OS, namely,
102 // the integrated Google Drive support.
103 class FileSystemApiTestForDrive : public PlatformAppBrowserTest {
104 public:
105 FileSystemApiTestForDrive()
106 : fake_drive_service_(NULL),
107 integration_service_(NULL) {
110 // Sets up fake Drive service for tests (this has to be injected before the
111 // real DriveIntegrationService instance is created.)
112 void SetUpInProcessBrowserTestFixture() override {
113 PlatformAppBrowserTest::SetUpInProcessBrowserTestFixture();
114 extensions::ComponentLoader::EnableBackgroundExtensionsForTesting();
116 ASSERT_TRUE(test_cache_root_.CreateUniqueTempDir());
118 create_drive_integration_service_ =
119 base::Bind(&FileSystemApiTestForDrive::CreateDriveIntegrationService,
120 base::Unretained(this));
121 service_factory_for_test_.reset(
122 new drive::DriveIntegrationServiceFactory::ScopedFactoryForTest(
123 &create_drive_integration_service_));
126 // Ensure the fake service's data is fetch in the local file system. This is
127 // necessary because the fetch starts lazily upon the first read operation.
128 void SetUpOnMainThread() override {
129 PlatformAppBrowserTest::SetUpOnMainThread();
131 scoped_ptr<drive::ResourceEntry> entry;
132 drive::FileError error = drive::FILE_ERROR_FAILED;
133 integration_service_->file_system()->GetResourceEntry(
134 base::FilePath::FromUTF8Unsafe("drive/root"), // whatever
135 google_apis::test_util::CreateCopyResultCallback(&error, &entry));
136 content::RunAllBlockingPoolTasksUntilIdle();
137 ASSERT_EQ(drive::FILE_ERROR_OK, error);
140 void TearDown() override {
141 FileSystemChooseEntryFunction::StopSkippingPickerForTest();
142 PlatformAppBrowserTest::TearDown();
145 private:
146 drive::DriveIntegrationService* CreateDriveIntegrationService(
147 Profile* profile) {
148 // Ignore signin profile.
149 if (profile->GetPath() == chromeos::ProfileHelper::GetSigninProfileDir())
150 return NULL;
152 // FileSystemApiTestForDrive doesn't expect that several user profiles could
153 // exist simultaneously.
154 DCHECK(fake_drive_service_ == NULL);
155 fake_drive_service_ = new drive::FakeDriveService;
156 fake_drive_service_->LoadAppListForDriveApi("drive/applist.json");
158 SetUpTestFileHierarchy();
160 integration_service_ = new drive::DriveIntegrationService(
161 profile, NULL, fake_drive_service_, std::string(),
162 test_cache_root_.path(), NULL);
163 return integration_service_;
166 void SetUpTestFileHierarchy() {
167 const std::string root = fake_drive_service_->GetRootResourceId();
168 ASSERT_TRUE(AddTestFile("open_existing.txt", "Can you see me?", root));
169 ASSERT_TRUE(AddTestFile("open_existing1.txt", "Can you see me?", root));
170 ASSERT_TRUE(AddTestFile("open_existing2.txt", "Can you see me?", root));
171 ASSERT_TRUE(AddTestFile("save_existing.txt", "Can you see me?", root));
172 const std::string subdir = AddTestDirectory("subdir", root);
173 ASSERT_FALSE(subdir.empty());
174 ASSERT_TRUE(AddTestFile("open_existing.txt", "Can you see me?", subdir));
177 bool AddTestFile(const std::string& title,
178 const std::string& data,
179 const std::string& parent_id) {
180 scoped_ptr<google_apis::FileResource> entry;
181 google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
182 fake_drive_service_->AddNewFile(
183 "text/plain", data, parent_id, title, false,
184 google_apis::test_util::CreateCopyResultCallback(&error, &entry));
185 content::RunAllPendingInMessageLoop();
186 return error == google_apis::HTTP_CREATED && entry;
189 std::string AddTestDirectory(const std::string& title,
190 const std::string& parent_id) {
191 scoped_ptr<google_apis::FileResource> entry;
192 google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
193 fake_drive_service_->AddNewDirectory(
194 parent_id, title, drive::AddNewDirectoryOptions(),
195 google_apis::test_util::CreateCopyResultCallback(&error, &entry));
196 content::RunAllPendingInMessageLoop();
197 return error == google_apis::HTTP_CREATED && entry ? entry->file_id() : "";
200 base::ScopedTempDir test_cache_root_;
201 drive::FakeDriveService* fake_drive_service_;
202 drive::DriveIntegrationService* integration_service_;
203 drive::DriveIntegrationServiceFactory::FactoryCallback
204 create_drive_integration_service_;
205 scoped_ptr<drive::DriveIntegrationServiceFactory::ScopedFactoryForTest>
206 service_factory_for_test_;
209 // This class contains chrome.filesystem.requestFileSystem API tests.
210 class FileSystemApiTestForRequestFileSystem : public PlatformAppBrowserTest {
211 public:
212 FileSystemApiTestForRequestFileSystem() : fake_user_manager_(nullptr) {}
214 void SetUpOnMainThread() override {
215 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
216 CreateTestingFileSystem(kWritableMountPointName, false /* read_only */);
217 CreateTestingFileSystem(kReadOnlyMountPointName, true /* read_only */);
218 PlatformAppBrowserTest::SetUpOnMainThread();
221 void TearDownOnMainThread() override {
222 PlatformAppBrowserTest::TearDownOnMainThread();
223 user_manager_enabler_.reset();
224 fake_user_manager_ = nullptr;
227 // Simulates mounting a removable volume.
228 void MountFakeVolume() {
229 VolumeManager* const volume_manager =
230 VolumeManager::Get(browser()->profile());
231 ASSERT_TRUE(volume_manager);
232 volume_manager->AddVolumeForTesting(
233 base::FilePath("/a/b/c"), file_manager::VOLUME_TYPE_TESTING,
234 chromeos::DEVICE_TYPE_UNKNOWN, false /* read_only */);
237 protected:
238 base::ScopedTempDir temp_dir_;
239 chromeos::FakeChromeUserManager* fake_user_manager_;
240 scoped_ptr<chromeos::ScopedUserManagerEnabler> user_manager_enabler_;
242 // Creates a testing file system in a testing directory.
243 void CreateTestingFileSystem(const std::string& mount_point_name,
244 bool read_only) {
245 const base::FilePath mount_point_path =
246 temp_dir_.path().Append(mount_point_name);
247 ASSERT_TRUE(base::CreateDirectory(mount_point_path));
248 ASSERT_TRUE(
249 base::CreateDirectory(mount_point_path.Append(kChildDirectory)));
250 ASSERT_TRUE(content::BrowserContext::GetMountPoints(browser()->profile())
251 ->RegisterFileSystem(
252 mount_point_name, storage::kFileSystemTypeNativeLocal,
253 storage::FileSystemMountOption(), mount_point_path));
254 VolumeManager* const volume_manager =
255 VolumeManager::Get(browser()->profile());
256 ASSERT_TRUE(volume_manager);
257 volume_manager->AddVolumeForTesting(
258 mount_point_path, file_manager::VOLUME_TYPE_TESTING,
259 chromeos::DEVICE_TYPE_UNKNOWN, read_only);
262 // Simulates entering the kiosk session.
263 void EnterKioskSession() {
264 fake_user_manager_ = new chromeos::FakeChromeUserManager();
265 user_manager_enabler_.reset(
266 new chromeos::ScopedUserManagerEnabler(fake_user_manager_));
268 const std::string kKioskLogin = "kiosk@foobar.com";
269 fake_user_manager_->AddKioskAppUser(kKioskLogin);
270 fake_user_manager_->LoginUser(kKioskLogin);
274 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
275 FileSystemApiOpenExistingFileTest) {
276 base::FilePath test_file = drive::util::GetDriveMountPointPath(
277 browser()->profile()).AppendASCII("root/open_existing.txt");
278 FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
279 &test_file);
280 ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_existing"))
281 << message_;
284 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
285 FileSystemApiOpenExistingFileWithWriteTest) {
286 base::FilePath test_file = drive::util::GetDriveMountPointPath(
287 browser()->profile()).AppendASCII("root/open_existing.txt");
288 FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
289 &test_file);
290 ASSERT_TRUE(RunPlatformAppTest(
291 "api_test/file_system/open_existing_with_write")) << message_;
294 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
295 FileSystemApiOpenMultipleSuggested) {
296 base::FilePath test_file = drive::util::GetDriveMountPointPath(
297 browser()->profile()).AppendASCII("root/open_existing.txt");
298 ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded(
299 chrome::DIR_USER_DOCUMENTS, test_file.DirName(), true, false));
300 FileSystemChooseEntryFunction::SkipPickerAndSelectSuggestedPathForTest();
301 ASSERT_TRUE(RunPlatformAppTest(
302 "api_test/file_system/open_multiple_with_suggested_name"))
303 << message_;
306 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
307 FileSystemApiOpenMultipleExistingFilesTest) {
308 base::FilePath test_file1 = drive::util::GetDriveMountPointPath(
309 browser()->profile()).AppendASCII("root/open_existing1.txt");
310 base::FilePath test_file2 = drive::util::GetDriveMountPointPath(
311 browser()->profile()).AppendASCII("root/open_existing2.txt");
312 std::vector<base::FilePath> test_files;
313 test_files.push_back(test_file1);
314 test_files.push_back(test_file2);
315 FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathsForTest(
316 &test_files);
317 ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_multiple_existing"))
318 << message_;
321 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
322 FileSystemApiOpenDirectoryTest) {
323 base::FilePath test_directory =
324 drive::util::GetDriveMountPointPath(browser()->profile()).AppendASCII(
325 "root/subdir");
326 FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
327 &test_directory);
328 ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_directory"))
329 << message_;
332 #if defined(ADDRESS_SANITIZER)
333 // Flaky when run under ASan: crbug.com/499233.
334 #define MAYBE_FileSystemApiOpenDirectoryWithWriteTest \
335 DISABLED_FileSystemApiOpenDirectoryWithWriteTest
336 #else
337 #define MAYBE_FileSystemApiOpenDirectoryWithWriteTest \
338 FileSystemApiOpenDirectoryWithWriteTest
339 #endif
340 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
341 MAYBE_FileSystemApiOpenDirectoryWithWriteTest) {
342 base::FilePath test_directory =
343 drive::util::GetDriveMountPointPath(browser()->profile()).AppendASCII(
344 "root/subdir");
345 FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
346 &test_directory);
347 ASSERT_TRUE(
348 RunPlatformAppTest("api_test/file_system/open_directory_with_write"))
349 << message_;
352 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
353 FileSystemApiOpenDirectoryWithoutPermissionTest) {
354 base::FilePath test_directory =
355 drive::util::GetDriveMountPointPath(browser()->profile()).AppendASCII(
356 "root/subdir");
357 FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
358 &test_directory);
359 ASSERT_TRUE(RunPlatformAppTest(
360 "api_test/file_system/open_directory_without_permission"))
361 << message_;
364 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
365 FileSystemApiOpenDirectoryWithOnlyWritePermissionTest) {
366 base::FilePath test_directory =
367 drive::util::GetDriveMountPointPath(browser()->profile()).AppendASCII(
368 "root/subdir");
369 FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
370 &test_directory);
371 ASSERT_TRUE(RunPlatformAppTest(
372 "api_test/file_system/open_directory_with_only_write"))
373 << message_;
376 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
377 FileSystemApiSaveNewFileTest) {
378 base::FilePath test_file = drive::util::GetDriveMountPointPath(
379 browser()->profile()).AppendASCII("root/save_new.txt");
380 FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
381 &test_file);
382 ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_new"))
383 << message_;
386 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
387 FileSystemApiSaveExistingFileTest) {
388 base::FilePath test_file = drive::util::GetDriveMountPointPath(
389 browser()->profile()).AppendASCII("root/save_existing.txt");
390 FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
391 &test_file);
392 ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_existing"))
393 << message_;
396 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
397 FileSystemApiSaveNewFileWithWriteTest) {
398 base::FilePath test_file = drive::util::GetDriveMountPointPath(
399 browser()->profile()).AppendASCII("root/save_new.txt");
400 FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
401 &test_file);
402 ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_new_with_write"))
403 << message_;
406 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
407 FileSystemApiSaveExistingFileWithWriteTest) {
408 base::FilePath test_file = drive::util::GetDriveMountPointPath(
409 browser()->profile()).AppendASCII("root/save_existing.txt");
410 FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
411 &test_file);
412 ASSERT_TRUE(RunPlatformAppTest(
413 "api_test/file_system/save_existing_with_write")) << message_;
416 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForRequestFileSystem, Background) {
417 EnterKioskSession();
418 ScopedSkipRequestFileSystemDialog dialog_skipper(ui::DIALOG_BUTTON_OK);
419 ASSERT_TRUE(
420 RunPlatformAppTest("api_test/file_system/request_file_system_background"))
421 << message_;
424 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForRequestFileSystem, ReadOnly) {
425 EnterKioskSession();
426 ScopedSkipRequestFileSystemDialog dialog_skipper(ui::DIALOG_BUTTON_OK);
427 ASSERT_TRUE(
428 RunPlatformAppTest("api_test/file_system/request_file_system_read_only"))
429 << message_;
432 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForRequestFileSystem, Writable) {
433 EnterKioskSession();
434 ScopedSkipRequestFileSystemDialog dialog_skipper(ui::DIALOG_BUTTON_OK);
435 ASSERT_TRUE(
436 RunPlatformAppTest("api_test/file_system/request_file_system_writable"))
437 << message_;
440 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForRequestFileSystem, UserReject) {
441 EnterKioskSession();
442 ScopedSkipRequestFileSystemDialog dialog_skipper(ui::DIALOG_BUTTON_CANCEL);
443 ASSERT_TRUE(RunPlatformAppTest(
444 "api_test/file_system/request_file_system_user_reject"))
445 << message_;
448 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForRequestFileSystem, NotKioskSession) {
449 ScopedSkipRequestFileSystemDialog dialog_skipper(ui::DIALOG_BUTTON_OK);
450 ASSERT_TRUE(RunPlatformAppTest(
451 "api_test/file_system/request_file_system_not_kiosk_session"))
452 << message_;
455 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForRequestFileSystem,
456 WhitelistedComponent) {
457 ScopedSkipRequestFileSystemDialog dialog_skipper(ui::DIALOG_BUTTON_CANCEL);
458 ASSERT_TRUE(RunPlatformAppTestWithFlags(
459 "api_test/file_system/request_file_system_whitelisted_component",
460 kFlagLoadAsComponent))
461 << message_;
464 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForRequestFileSystem,
465 NotWhitelistedComponent) {
466 ScopedSkipRequestFileSystemDialog dialog_skipper(ui::DIALOG_BUTTON_OK);
467 ASSERT_TRUE(RunPlatformAppTestWithFlags(
468 "api_test/file_system/request_file_system_not_whitelisted_component",
469 kFlagLoadAsComponent))
470 << message_;
473 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForRequestFileSystem, GetVolumeList) {
474 EnterKioskSession();
475 ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/get_volume_list"))
476 << message_;
479 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForRequestFileSystem,
480 GetVolumeList_NotKioskSession) {
481 ASSERT_TRUE(RunPlatformAppTest(
482 "api_test/file_system/get_volume_list_not_kiosk_session"))
483 << message_;
486 IN_PROC_BROWSER_TEST_F(FileSystemApiTestForRequestFileSystem,
487 OnVolumeListChanged) {
488 EnterKioskSession();
490 ScopedAddListenerObserver observer(
491 profile(), extensions::api::file_system::OnVolumeListChanged::kEventName,
492 kTestingExtensionId,
493 base::Bind(&FileSystemApiTestForRequestFileSystem::MountFakeVolume,
494 this));
496 ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/on_volume_list_changed"))
497 << message_;
500 } // namespace extensions