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