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/browser/chromeos/drive/file_write_helper.h" 11 #include "chrome/browser/chromeos/drive/test_util.h" 12 #include "content/public/test/mock_download_item.h" 13 #include "content/public/test/mock_download_manager.h" 14 #include "content/public/test/test_browser_thread_bundle.h" 15 #include "testing/gtest/include/gtest/gtest.h" 16 17 namespace drive { 18 19 namespace { 20 21 // Flags to control the state of the test file system. 22 enum DownloadPathState { 23 // Simulates the state that requested path just simply exists. 24 PATH_EXISTS, 25 // Simulates the state that requested path fails to be accessed. 26 PATH_INVALID, 27 // Simulates the state that the requested path does not exist. 28 PATH_NOT_EXIST, 29 // Simulates the state that the path does not exist nor be able to be created. 30 PATH_NOT_EXIST_AND_CREATE_FAIL, 31 }; 32 33 // Test file system for verifying the behavior of DownloadHandler, by simulating 34 // various responses from FileSystem. 35 class DownloadHandlerTestFileSystem : public DummyFileSystem { 36 public: 37 DownloadHandlerTestFileSystem() : state_(PATH_INVALID) {} 38 39 void set_download_path_state(DownloadPathState state) { state_ = state; } 40 41 // FileSystemInterface overrides. 42 virtual void GetResourceEntryByPath( 43 const base::FilePath& file_path, 44 const GetResourceEntryCallback& callback) OVERRIDE { 45 if (state_ == PATH_EXISTS) { 46 callback.Run(FILE_ERROR_OK, make_scoped_ptr(new ResourceEntry)); 47 return; 48 } 49 callback.Run( 50 state_ == PATH_INVALID ? FILE_ERROR_FAILED : FILE_ERROR_NOT_FOUND, 51 scoped_ptr<ResourceEntry>()); 52 } 53 54 virtual void CreateDirectory( 55 const base::FilePath& directory_path, 56 bool is_exclusive, 57 bool is_recursive, 58 const FileOperationCallback& callback) OVERRIDE { 59 callback.Run(state_ == PATH_NOT_EXIST ? FILE_ERROR_OK : FILE_ERROR_FAILED); 60 } 61 62 private: 63 DownloadPathState state_; 64 }; 65 66 } // namespace 67 68 class DownloadHandlerTest : public testing::Test { 69 public: 70 DownloadHandlerTest() 71 : download_manager_(new content::MockDownloadManager) {} 72 73 virtual void SetUp() OVERRIDE { 74 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 75 76 // Set expectations for download item. 77 EXPECT_CALL(download_item_, GetState()) 78 .WillRepeatedly(testing::Return(content::DownloadItem::IN_PROGRESS)); 79 80 file_write_helper_.reset(new FileWriteHelper(&test_file_system_)); 81 download_handler_.reset( 82 new DownloadHandler(file_write_helper_.get(), &test_file_system_)); 83 download_handler_->Initialize(download_manager_.get(), temp_dir_.path()); 84 } 85 86 protected: 87 base::ScopedTempDir temp_dir_; 88 content::TestBrowserThreadBundle thread_bundle_; 89 scoped_ptr<content::MockDownloadManager> download_manager_; 90 DownloadHandlerTestFileSystem test_file_system_; 91 scoped_ptr<FileWriteHelper> file_write_helper_; 92 scoped_ptr<DownloadHandler> download_handler_; 93 content::MockDownloadItem download_item_; 94 }; 95 96 TEST_F(DownloadHandlerTest, SubstituteDriveDownloadPathNonDrivePath) { 97 const base::FilePath non_drive_path(FILE_PATH_LITERAL("/foo/bar")); 98 ASSERT_FALSE(util::IsUnderDriveMountPoint(non_drive_path)); 99 100 // Call SubstituteDriveDownloadPath() 101 base::FilePath substituted_path; 102 download_handler_->SubstituteDriveDownloadPath( 103 non_drive_path, 104 &download_item_, 105 google_apis::test_util::CreateCopyResultCallback(&substituted_path)); 106 test_util::RunBlockingPoolTask(); 107 108 // Check the result. 109 EXPECT_EQ(non_drive_path, substituted_path); 110 EXPECT_FALSE(download_handler_->IsDriveDownload(&download_item_)); 111 } 112 113 TEST_F(DownloadHandlerTest, SubstituteDriveDownloadPath) { 114 const base::FilePath drive_path = 115 util::GetDriveMountPointPath().AppendASCII("test.dat"); 116 117 // Test the case that the download target directory already exists. 118 test_file_system_.set_download_path_state(PATH_EXISTS); 119 120 // Call SubstituteDriveDownloadPath() 121 base::FilePath substituted_path; 122 download_handler_->SubstituteDriveDownloadPath( 123 drive_path, 124 &download_item_, 125 google_apis::test_util::CreateCopyResultCallback(&substituted_path)); 126 test_util::RunBlockingPoolTask(); 127 128 // Check the result. 129 EXPECT_TRUE(temp_dir_.path().IsParent(substituted_path)); 130 ASSERT_TRUE(download_handler_->IsDriveDownload(&download_item_)); 131 EXPECT_EQ(drive_path, download_handler_->GetTargetPath(&download_item_)); 132 } 133 134 TEST_F(DownloadHandlerTest, SubstituteDriveDownloadPathGetEntryFailure) { 135 const base::FilePath drive_path = 136 util::GetDriveMountPointPath().AppendASCII("test.dat"); 137 138 // Test the case that access to the download target directory failed for some 139 // reason. 140 test_file_system_.set_download_path_state(PATH_INVALID); 141 142 // Call SubstituteDriveDownloadPath() 143 base::FilePath substituted_path; 144 download_handler_->SubstituteDriveDownloadPath( 145 drive_path, 146 &download_item_, 147 google_apis::test_util::CreateCopyResultCallback(&substituted_path)); 148 test_util::RunBlockingPoolTask(); 149 150 // Check the result. 151 EXPECT_TRUE(substituted_path.empty()); 152 } 153 154 TEST_F(DownloadHandlerTest, SubstituteDriveDownloadPathCreateDirectory) { 155 const base::FilePath drive_path = 156 util::GetDriveMountPointPath().AppendASCII("test.dat"); 157 158 // Test the case that access to the download target directory does not exist, 159 // and thus will be created in DownloadHandler. 160 test_file_system_.set_download_path_state(PATH_NOT_EXIST); 161 162 // Call SubstituteDriveDownloadPath() 163 base::FilePath substituted_path; 164 download_handler_->SubstituteDriveDownloadPath( 165 drive_path, 166 &download_item_, 167 google_apis::test_util::CreateCopyResultCallback(&substituted_path)); 168 test_util::RunBlockingPoolTask(); 169 170 // Check the result. 171 EXPECT_TRUE(temp_dir_.path().IsParent(substituted_path)); 172 ASSERT_TRUE(download_handler_->IsDriveDownload(&download_item_)); 173 EXPECT_EQ(drive_path, download_handler_->GetTargetPath(&download_item_)); 174 } 175 176 TEST_F(DownloadHandlerTest, 177 SubstituteDriveDownloadPathCreateDirectoryFailure) { 178 const base::FilePath drive_path = 179 util::GetDriveMountPointPath().AppendASCII("test.dat"); 180 181 // Test the case that access to the download target directory does not exist, 182 // and creation fails for some reason. 183 test_file_system_.set_download_path_state(PATH_NOT_EXIST_AND_CREATE_FAIL); 184 185 // Call SubstituteDriveDownloadPath() 186 base::FilePath substituted_path; 187 download_handler_->SubstituteDriveDownloadPath( 188 drive_path, 189 &download_item_, 190 google_apis::test_util::CreateCopyResultCallback(&substituted_path)); 191 test_util::RunBlockingPoolTask(); 192 193 // Check the result. 194 EXPECT_TRUE(substituted_path.empty()); 195 } 196 197 // content::SavePackage calls SubstituteDriveDownloadPath before creating 198 // DownloadItem. 199 TEST_F(DownloadHandlerTest, SubstituteDriveDownloadPathForSavePackage) { 200 const base::FilePath drive_path = 201 util::GetDriveMountPointPath().AppendASCII("test.dat"); 202 test_file_system_.set_download_path_state(PATH_EXISTS); 203 204 // Call SubstituteDriveDownloadPath() 205 base::FilePath substituted_path; 206 download_handler_->SubstituteDriveDownloadPath( 207 drive_path, 208 NULL, // DownloadItem is not available at this moment. 209 google_apis::test_util::CreateCopyResultCallback(&substituted_path)); 210 test_util::RunBlockingPoolTask(); 211 212 // Check the result of SubstituteDriveDownloadPath(). 213 EXPECT_TRUE(temp_dir_.path().IsParent(substituted_path)); 214 215 // |download_item_| is not a drive download yet. 216 EXPECT_FALSE(download_handler_->IsDriveDownload(&download_item_)); 217 218 // Call SetDownloadParams(). 219 download_handler_->SetDownloadParams(drive_path, &download_item_); 220 221 // |download_item_| is a drive download now. 222 ASSERT_TRUE(download_handler_->IsDriveDownload(&download_item_)); 223 EXPECT_EQ(drive_path, download_handler_->GetTargetPath(&download_item_)); 224 } 225 226 TEST_F(DownloadHandlerTest, CheckForFileExistence) { 227 const base::FilePath drive_path = 228 util::GetDriveMountPointPath().AppendASCII("test.dat"); 229 230 // Make |download_item_| a drive download. 231 download_handler_->SetDownloadParams(drive_path, &download_item_); 232 ASSERT_TRUE(download_handler_->IsDriveDownload(&download_item_)); 233 EXPECT_EQ(drive_path, download_handler_->GetTargetPath(&download_item_)); 234 235 // Test for the case when the path exists. 236 test_file_system_.set_download_path_state(PATH_EXISTS); 237 238 // Call CheckForFileExistence. 239 bool file_exists = false; 240 download_handler_->CheckForFileExistence( 241 &download_item_, 242 google_apis::test_util::CreateCopyResultCallback(&file_exists)); 243 test_util::RunBlockingPoolTask(); 244 245 // Check the result. 246 EXPECT_TRUE(file_exists); 247 248 // Test for the case when the path does not exist. 249 test_file_system_.set_download_path_state(PATH_NOT_EXIST); 250 251 // Call CheckForFileExistence again. 252 download_handler_->CheckForFileExistence( 253 &download_item_, 254 google_apis::test_util::CreateCopyResultCallback(&file_exists)); 255 test_util::RunBlockingPoolTask(); 256 257 // Check the result. 258 EXPECT_FALSE(file_exists); 259 } 260 261 } // namespace drive 262