1// Copyright (c) 2013 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 "chrome/browser/chromeos/drive/download_handler.h"
6
7#include "base/files/scoped_temp_dir.h"
8#include "chrome/browser/chromeos/drive/dummy_file_system.h"
9#include "chrome/browser/chromeos/drive/file_system_util.h"
10#include "chrome/test/base/testing_profile.h"
11#include "content/public/test/mock_download_item.h"
12#include "content/public/test/mock_download_manager.h"
13#include "content/public/test/test_browser_thread_bundle.h"
14#include "content/public/test/test_utils.h"
15#include "google_apis/drive/test_util.h"
16#include "testing/gtest/include/gtest/gtest.h"
17
18namespace drive {
19
20namespace {
21
22// Test file system for verifying the behavior of DownloadHandler, by simulating
23// various responses from FileSystem.
24class DownloadHandlerTestFileSystem : public DummyFileSystem {
25 public:
26  DownloadHandlerTestFileSystem() : error_(FILE_ERROR_FAILED) {}
27
28  void set_error(FileError error) { error_ = error; }
29
30  // FileSystemInterface overrides.
31  virtual void GetResourceEntry(
32      const base::FilePath& file_path,
33      const GetResourceEntryCallback& callback) OVERRIDE {
34    callback.Run(error_, scoped_ptr<ResourceEntry>(
35        error_ == FILE_ERROR_OK ? new ResourceEntry : NULL));
36  }
37
38  virtual void CreateDirectory(
39      const base::FilePath& directory_path,
40      bool is_exclusive,
41      bool is_recursive,
42      const FileOperationCallback& callback) OVERRIDE {
43    callback.Run(error_);
44  }
45
46 private:
47  FileError error_;
48};
49
50}  // namespace
51
52class DownloadHandlerTest : public testing::Test {
53 public:
54  DownloadHandlerTest()
55      : download_manager_(new content::MockDownloadManager) {}
56
57  virtual void SetUp() OVERRIDE {
58    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
59
60    // Set expectations for download item.
61    EXPECT_CALL(download_item_, GetState())
62        .WillRepeatedly(testing::Return(content::DownloadItem::IN_PROGRESS));
63
64    download_handler_.reset(new DownloadHandler(&test_file_system_));
65    download_handler_->Initialize(download_manager_.get(), temp_dir_.path());
66  }
67
68 protected:
69  base::ScopedTempDir temp_dir_;
70  content::TestBrowserThreadBundle thread_bundle_;
71  TestingProfile profile_;
72  scoped_ptr<content::MockDownloadManager> download_manager_;
73  DownloadHandlerTestFileSystem test_file_system_;
74  scoped_ptr<DownloadHandler> download_handler_;
75  content::MockDownloadItem download_item_;
76};
77
78TEST_F(DownloadHandlerTest, SubstituteDriveDownloadPathNonDrivePath) {
79  const base::FilePath non_drive_path(FILE_PATH_LITERAL("/foo/bar"));
80  ASSERT_FALSE(util::IsUnderDriveMountPoint(non_drive_path));
81
82  // Call SubstituteDriveDownloadPath()
83  base::FilePath substituted_path;
84  download_handler_->SubstituteDriveDownloadPath(
85      non_drive_path,
86      &download_item_,
87      google_apis::test_util::CreateCopyResultCallback(&substituted_path));
88  content::RunAllBlockingPoolTasksUntilIdle();
89
90  // Check the result.
91  EXPECT_EQ(non_drive_path, substituted_path);
92  EXPECT_FALSE(download_handler_->IsDriveDownload(&download_item_));
93}
94
95TEST_F(DownloadHandlerTest, SubstituteDriveDownloadPath) {
96  const base::FilePath drive_path =
97      util::GetDriveMountPointPath(&profile_).AppendASCII("test.dat");
98
99  // Test the case that the download target directory already exists.
100  test_file_system_.set_error(FILE_ERROR_OK);
101
102  // Call SubstituteDriveDownloadPath()
103  base::FilePath substituted_path;
104  download_handler_->SubstituteDriveDownloadPath(
105      drive_path,
106      &download_item_,
107      google_apis::test_util::CreateCopyResultCallback(&substituted_path));
108  content::RunAllBlockingPoolTasksUntilIdle();
109
110  // Check the result.
111  EXPECT_TRUE(temp_dir_.path().IsParent(substituted_path));
112  ASSERT_TRUE(download_handler_->IsDriveDownload(&download_item_));
113  EXPECT_EQ(drive_path, download_handler_->GetTargetPath(&download_item_));
114}
115
116TEST_F(DownloadHandlerTest, SubstituteDriveDownloadPathGetEntryFailure) {
117  const base::FilePath drive_path =
118      util::GetDriveMountPointPath(&profile_).AppendASCII("test.dat");
119
120  // Test the case that access to the download target directory failed for some
121  // reason.
122  test_file_system_.set_error(FILE_ERROR_FAILED);
123
124  // Call SubstituteDriveDownloadPath()
125  base::FilePath substituted_path;
126  download_handler_->SubstituteDriveDownloadPath(
127      drive_path,
128      &download_item_,
129      google_apis::test_util::CreateCopyResultCallback(&substituted_path));
130  content::RunAllBlockingPoolTasksUntilIdle();
131
132  // Check the result.
133  EXPECT_TRUE(substituted_path.empty());
134}
135
136// content::SavePackage calls SubstituteDriveDownloadPath before creating
137// DownloadItem.
138TEST_F(DownloadHandlerTest, SubstituteDriveDownloadPathForSavePackage) {
139  const base::FilePath drive_path =
140      util::GetDriveMountPointPath(&profile_).AppendASCII("test.dat");
141  test_file_system_.set_error(FILE_ERROR_OK);
142
143  // Call SubstituteDriveDownloadPath()
144  base::FilePath substituted_path;
145  download_handler_->SubstituteDriveDownloadPath(
146      drive_path,
147      NULL,  // DownloadItem is not available at this moment.
148      google_apis::test_util::CreateCopyResultCallback(&substituted_path));
149  content::RunAllBlockingPoolTasksUntilIdle();
150
151  // Check the result of SubstituteDriveDownloadPath().
152  EXPECT_TRUE(temp_dir_.path().IsParent(substituted_path));
153
154  // |download_item_| is not a drive download yet.
155  EXPECT_FALSE(download_handler_->IsDriveDownload(&download_item_));
156
157  // Call SetDownloadParams().
158  download_handler_->SetDownloadParams(drive_path, &download_item_);
159
160  // |download_item_| is a drive download now.
161  ASSERT_TRUE(download_handler_->IsDriveDownload(&download_item_));
162  EXPECT_EQ(drive_path, download_handler_->GetTargetPath(&download_item_));
163}
164
165TEST_F(DownloadHandlerTest, CheckForFileExistence) {
166  const base::FilePath drive_path =
167      util::GetDriveMountPointPath(&profile_).AppendASCII("test.dat");
168
169  // Make |download_item_| a drive download.
170  download_handler_->SetDownloadParams(drive_path, &download_item_);
171  ASSERT_TRUE(download_handler_->IsDriveDownload(&download_item_));
172  EXPECT_EQ(drive_path, download_handler_->GetTargetPath(&download_item_));
173
174  // Test for the case when the path exists.
175  test_file_system_.set_error(FILE_ERROR_OK);
176
177  // Call CheckForFileExistence.
178  bool file_exists = false;
179  download_handler_->CheckForFileExistence(
180      &download_item_,
181      google_apis::test_util::CreateCopyResultCallback(&file_exists));
182  content::RunAllBlockingPoolTasksUntilIdle();
183
184  // Check the result.
185  EXPECT_TRUE(file_exists);
186
187  // Test for the case when the path does not exist.
188  test_file_system_.set_error(FILE_ERROR_NOT_FOUND);
189
190  // Call CheckForFileExistence again.
191  download_handler_->CheckForFileExistence(
192      &download_item_,
193      google_apis::test_util::CreateCopyResultCallback(&file_exists));
194  content::RunAllBlockingPoolTasksUntilIdle();
195
196  // Check the result.
197  EXPECT_FALSE(file_exists);
198}
199
200}  // namespace drive
201