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.
4
5#include "base/path_service.h"
6#include "chrome/browser/apps/app_browsertest_util.h"
7#include "chrome/browser/chromeos/drive/drive_integration_service.h"
8#include "chrome/browser/chromeos/drive/file_system_interface.h"
9#include "chrome/browser/chromeos/drive/file_system_util.h"
10#include "chrome/browser/chromeos/drive/test_util.h"
11#include "chrome/browser/drive/fake_drive_service.h"
12#include "chrome/browser/extensions/api/file_system/file_system_api.h"
13#include "chrome/browser/extensions/component_loader.h"
14#include "chrome/common/chrome_paths.h"
15#include "content/public/test/test_utils.h"
16#include "google_apis/drive/drive_api_parser.h"
17#include "google_apis/drive/test_util.h"
18
19namespace extensions {
20
21// This class contains chrome.filesystem API test specific to Chrome OS, namely,
22// the integrated Google Drive support.
23class FileSystemApiTestForDrive : public PlatformAppBrowserTest {
24 public:
25  FileSystemApiTestForDrive()
26      : fake_drive_service_(NULL),
27        integration_service_(NULL) {
28  }
29
30  // Sets up fake Drive service for tests (this has to be injected before the
31  // real DriveIntegrationService instance is created.)
32  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
33    PlatformAppBrowserTest::SetUpInProcessBrowserTestFixture();
34    extensions::ComponentLoader::EnableBackgroundExtensionsForTesting();
35
36    ASSERT_TRUE(test_cache_root_.CreateUniqueTempDir());
37
38    create_drive_integration_service_ =
39        base::Bind(&FileSystemApiTestForDrive::CreateDriveIntegrationService,
40                   base::Unretained(this));
41    service_factory_for_test_.reset(
42        new drive::DriveIntegrationServiceFactory::ScopedFactoryForTest(
43            &create_drive_integration_service_));
44  }
45
46  // Ensure the fake service's data is fetch in the local file system. This is
47  // necessary because the fetch starts lazily upon the first read operation.
48  virtual void SetUpOnMainThread() OVERRIDE {
49    PlatformAppBrowserTest::SetUpOnMainThread();
50
51    scoped_ptr<drive::ResourceEntry> entry;
52    drive::FileError error = drive::FILE_ERROR_FAILED;
53    integration_service_->file_system()->GetResourceEntry(
54        base::FilePath::FromUTF8Unsafe("drive/root"),  // whatever
55        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
56    drive::test_util::RunBlockingPoolTask();
57    ASSERT_EQ(drive::FILE_ERROR_OK, error);
58  }
59
60  virtual void TearDown() OVERRIDE {
61    FileSystemChooseEntryFunction::StopSkippingPickerForTest();
62    PlatformAppBrowserTest::TearDown();
63  };
64
65 private:
66  drive::DriveIntegrationService* CreateDriveIntegrationService(
67      Profile* profile) {
68    fake_drive_service_ = new drive::FakeDriveService;
69    fake_drive_service_->LoadAppListForDriveApi("drive/applist.json");
70
71    SetUpTestFileHierarchy();
72
73    integration_service_ = new drive::DriveIntegrationService(
74        profile, NULL, fake_drive_service_, std::string(),
75        test_cache_root_.path(), NULL);
76    return integration_service_;
77  }
78
79  void SetUpTestFileHierarchy() {
80    const std::string root = fake_drive_service_->GetRootResourceId();
81    ASSERT_TRUE(AddTestFile("open_existing.txt", "Can you see me?", root));
82    ASSERT_TRUE(AddTestFile("open_existing1.txt", "Can you see me?", root));
83    ASSERT_TRUE(AddTestFile("open_existing2.txt", "Can you see me?", root));
84    ASSERT_TRUE(AddTestFile("save_existing.txt", "Can you see me?", root));
85    const std::string subdir = AddTestDirectory("subdir", root);
86    ASSERT_FALSE(subdir.empty());
87    ASSERT_TRUE(AddTestFile("open_existing.txt", "Can you see me?", subdir));
88  }
89
90  bool AddTestFile(const std::string& title,
91                   const std::string& data,
92                   const std::string& parent_id) {
93    scoped_ptr<google_apis::FileResource> entry;
94    google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
95    fake_drive_service_->AddNewFile(
96        "text/plain", data, parent_id, title, false,
97        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
98    content::RunAllPendingInMessageLoop();
99    return error == google_apis::HTTP_CREATED && entry;
100  }
101
102  std::string AddTestDirectory(const std::string& title,
103                               const std::string& parent_id) {
104    scoped_ptr<google_apis::FileResource> entry;
105    google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
106    fake_drive_service_->AddNewDirectory(
107        parent_id, title,
108        drive::DriveServiceInterface::AddNewDirectoryOptions(),
109        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
110    content::RunAllPendingInMessageLoop();
111    return error == google_apis::HTTP_CREATED && entry ? entry->file_id() : "";
112  }
113
114  base::ScopedTempDir test_cache_root_;
115  drive::FakeDriveService* fake_drive_service_;
116  drive::DriveIntegrationService* integration_service_;
117  drive::DriveIntegrationServiceFactory::FactoryCallback
118      create_drive_integration_service_;
119  scoped_ptr<drive::DriveIntegrationServiceFactory::ScopedFactoryForTest>
120      service_factory_for_test_;
121};
122
123IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
124                       FileSystemApiOpenExistingFileTest) {
125  base::FilePath test_file = drive::util::GetDriveMountPointPath(
126      browser()->profile()).AppendASCII("root/open_existing.txt");
127  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
128      &test_file);
129  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_existing"))
130      << message_;
131}
132
133IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
134                       FileSystemApiOpenExistingFileWithWriteTest) {
135  base::FilePath test_file = drive::util::GetDriveMountPointPath(
136      browser()->profile()).AppendASCII("root/open_existing.txt");
137  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
138      &test_file);
139  ASSERT_TRUE(RunPlatformAppTest(
140      "api_test/file_system/open_existing_with_write")) << message_;
141}
142
143IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
144                       FileSystemApiOpenMultipleSuggested) {
145  base::FilePath test_file = drive::util::GetDriveMountPointPath(
146      browser()->profile()).AppendASCII("root/open_existing.txt");
147  ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded(
148      chrome::DIR_USER_DOCUMENTS, test_file.DirName(), true, false));
149  FileSystemChooseEntryFunction::SkipPickerAndSelectSuggestedPathForTest();
150  ASSERT_TRUE(RunPlatformAppTest(
151      "api_test/file_system/open_multiple_with_suggested_name"))
152      << message_;
153}
154
155IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
156                       FileSystemApiOpenMultipleExistingFilesTest) {
157  base::FilePath test_file1 = drive::util::GetDriveMountPointPath(
158      browser()->profile()).AppendASCII("root/open_existing1.txt");
159  base::FilePath test_file2 = drive::util::GetDriveMountPointPath(
160      browser()->profile()).AppendASCII("root/open_existing2.txt");
161  std::vector<base::FilePath> test_files;
162  test_files.push_back(test_file1);
163  test_files.push_back(test_file2);
164  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathsForTest(
165      &test_files);
166  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_multiple_existing"))
167      << message_;
168}
169
170IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
171                       FileSystemApiOpenDirectoryTest) {
172  base::FilePath test_directory =
173      drive::util::GetDriveMountPointPath(browser()->profile()).AppendASCII(
174          "root/subdir");
175  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
176      &test_directory);
177  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_directory"))
178      << message_;
179}
180
181IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
182                       FileSystemApiOpenDirectoryWithWriteTest) {
183  base::FilePath test_directory =
184      drive::util::GetDriveMountPointPath(browser()->profile()).AppendASCII(
185          "root/subdir");
186  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
187      &test_directory);
188  ASSERT_TRUE(
189      RunPlatformAppTest("api_test/file_system/open_directory_with_write"))
190      << message_;
191}
192
193IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
194                       FileSystemApiOpenDirectoryWithoutPermissionTest) {
195  base::FilePath test_directory =
196      drive::util::GetDriveMountPointPath(browser()->profile()).AppendASCII(
197          "root/subdir");
198  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
199      &test_directory);
200  ASSERT_TRUE(RunPlatformAppTest(
201      "api_test/file_system/open_directory_without_permission"))
202      << message_;
203}
204
205IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
206                       FileSystemApiOpenDirectoryWithOnlyWritePermissionTest) {
207  base::FilePath test_directory =
208      drive::util::GetDriveMountPointPath(browser()->profile()).AppendASCII(
209          "root/subdir");
210  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
211      &test_directory);
212  ASSERT_TRUE(RunPlatformAppTest(
213      "api_test/file_system/open_directory_with_only_write"))
214      << message_;
215}
216
217IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
218                       FileSystemApiSaveNewFileTest) {
219  base::FilePath test_file = drive::util::GetDriveMountPointPath(
220      browser()->profile()).AppendASCII("root/save_new.txt");
221  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
222      &test_file);
223  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_new"))
224      << message_;
225}
226
227IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
228                       FileSystemApiSaveExistingFileTest) {
229  base::FilePath test_file = drive::util::GetDriveMountPointPath(
230      browser()->profile()).AppendASCII("root/save_existing.txt");
231  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
232      &test_file);
233  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_existing"))
234      << message_;
235}
236
237IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
238    FileSystemApiSaveNewFileWithWriteTest) {
239  base::FilePath test_file = drive::util::GetDriveMountPointPath(
240      browser()->profile()).AppendASCII("root/save_new.txt");
241  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
242      &test_file);
243  ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_new_with_write"))
244      << message_;
245}
246
247IN_PROC_BROWSER_TEST_F(FileSystemApiTestForDrive,
248    FileSystemApiSaveExistingFileWithWriteTest) {
249  base::FilePath test_file = drive::util::GetDriveMountPointPath(
250      browser()->profile()).AppendASCII("root/save_existing.txt");
251  FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
252      &test_file);
253  ASSERT_TRUE(RunPlatformAppTest(
254      "api_test/file_system/save_existing_with_write")) << message_;
255}
256
257}  // namespace extensions
258