1// Copyright 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/file_system/copy_operation.h" 6 7#include "base/file_util.h" 8#include "chrome/browser/chromeos/drive/file_system/operation_test_base.h" 9#include "chrome/browser/chromeos/drive/file_system_util.h" 10#include "chrome/browser/drive/fake_drive_service.h" 11#include "chrome/browser/google_apis/test_util.h" 12#include "testing/gtest/include/gtest/gtest.h" 13 14namespace drive { 15namespace file_system { 16 17class CopyOperationTest : public OperationTestBase { 18 protected: 19 virtual void SetUp() OVERRIDE { 20 OperationTestBase::SetUp(); 21 operation_.reset(new CopyOperation(blocking_task_runner(), 22 observer(), 23 scheduler(), 24 metadata(), 25 cache(), 26 fake_service(), 27 temp_dir())); 28 } 29 30 scoped_ptr<CopyOperation> operation_; 31}; 32 33TEST_F(CopyOperationTest, TransferFileFromLocalToRemote_RegularFile) { 34 const base::FilePath local_src_path = temp_dir().AppendASCII("local.txt"); 35 const base::FilePath remote_dest_path( 36 FILE_PATH_LITERAL("drive/root/remote.txt")); 37 38 // Prepare a local file. 39 ASSERT_TRUE( 40 google_apis::test_util::WriteStringToFile(local_src_path, "hello")); 41 // Confirm that the remote file does not exist. 42 ResourceEntry entry; 43 ASSERT_EQ(FILE_ERROR_NOT_FOUND, 44 GetLocalResourceEntry(remote_dest_path, &entry)); 45 46 // Transfer the local file to Drive. 47 FileError error = FILE_ERROR_FAILED; 48 operation_->TransferFileFromLocalToRemote( 49 local_src_path, 50 remote_dest_path, 51 google_apis::test_util::CreateCopyResultCallback(&error)); 52 test_util::RunBlockingPoolTask(); 53 EXPECT_EQ(FILE_ERROR_OK, error); 54 55 // TransferFileFromLocalToRemote stores a copy of the local file in the cache, 56 // marks it dirty and requests the observer to upload the file. 57 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_dest_path, &entry)); 58 EXPECT_EQ(1U, observer()->upload_needed_resource_ids().count( 59 entry.resource_id())); 60 FileCacheEntry cache_entry; 61 bool found = false; 62 cache()->GetCacheEntryOnUIThread( 63 entry.resource_id(), 64 google_apis::test_util::CreateCopyResultCallback(&found, &cache_entry)); 65 test_util::RunBlockingPoolTask(); 66 EXPECT_TRUE(found); 67 EXPECT_TRUE(cache_entry.is_present()); 68 EXPECT_TRUE(cache_entry.is_dirty()); 69 70 EXPECT_EQ(1U, observer()->get_changed_paths().size()); 71 EXPECT_TRUE(observer()->get_changed_paths().count( 72 remote_dest_path.DirName())); 73} 74 75TEST_F(CopyOperationTest, TransferFileFromLocalToRemote_QuotaCheck) { 76 const base::FilePath local_src_path = temp_dir().AppendASCII("local.txt"); 77 const base::FilePath remote_dest_path( 78 FILE_PATH_LITERAL("drive/root/remote.txt")); 79 80 const size_t kFileSize = 10; 81 82 // Prepare a local file. 83 ASSERT_TRUE( 84 google_apis::test_util::WriteStringToFile(local_src_path, 85 std::string(kFileSize, 'a'))); 86 87 // Set insufficient quota. 88 fake_service()->SetQuotaValue(100, 100 + kFileSize - 1); 89 90 // Transfer the local file to Drive. 91 FileError error = FILE_ERROR_FAILED; 92 operation_->TransferFileFromLocalToRemote( 93 local_src_path, 94 remote_dest_path, 95 google_apis::test_util::CreateCopyResultCallback(&error)); 96 test_util::RunBlockingPoolTask(); 97 EXPECT_EQ(FILE_ERROR_NO_SERVER_SPACE, error); 98 99 // Set sufficient quota. 100 fake_service()->SetQuotaValue(100, 100 + kFileSize); 101 102 // Transfer the local file to Drive. 103 error = FILE_ERROR_FAILED; 104 operation_->TransferFileFromLocalToRemote( 105 local_src_path, 106 remote_dest_path, 107 google_apis::test_util::CreateCopyResultCallback(&error)); 108 test_util::RunBlockingPoolTask(); 109 EXPECT_EQ(FILE_ERROR_OK, error); 110} 111 112TEST_F(CopyOperationTest, TransferFileFromLocalToRemote_HostedDocument) { 113 const base::FilePath local_src_path = temp_dir().AppendASCII("local.gdoc"); 114 const base::FilePath remote_dest_path(FILE_PATH_LITERAL( 115 "drive/root/Directory 1/Document 1 excludeDir-test.gdoc")); 116 117 // Prepare a local file, which is a json file of a hosted document, which 118 // matches "Document 1" in root_feed.json. 119 ASSERT_TRUE(util::CreateGDocFile( 120 local_src_path, 121 GURL("https://3_document_self_link/document:5_document_resource_id"), 122 "document:5_document_resource_id")); 123 124 ResourceEntry entry; 125 ASSERT_EQ(FILE_ERROR_NOT_FOUND, 126 GetLocalResourceEntry(remote_dest_path, &entry)); 127 128 // Transfer the local file to Drive. 129 FileError error = FILE_ERROR_FAILED; 130 operation_->TransferFileFromLocalToRemote( 131 local_src_path, 132 remote_dest_path, 133 google_apis::test_util::CreateCopyResultCallback(&error)); 134 test_util::RunBlockingPoolTask(); 135 EXPECT_EQ(FILE_ERROR_OK, error); 136 137 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_dest_path, &entry)); 138 139 // We added a file to the Drive root and then moved to "Directory 1". 140 EXPECT_EQ(2U, observer()->get_changed_paths().size()); 141 EXPECT_TRUE(observer()->get_changed_paths().count( 142 base::FilePath(FILE_PATH_LITERAL("drive/root")))); 143 EXPECT_TRUE(observer()->get_changed_paths().count( 144 remote_dest_path.DirName())); 145} 146 147TEST_F(CopyOperationTest, TransferFileFromRemoteToLocal_RegularFile) { 148 base::FilePath remote_src_path(FILE_PATH_LITERAL("drive/root/File 1.txt")); 149 base::FilePath local_dest_path = temp_dir().AppendASCII("local_copy.txt"); 150 151 ResourceEntry entry; 152 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_src_path, &entry)); 153 154 FileError error = FILE_ERROR_FAILED; 155 operation_->TransferFileFromRemoteToLocal( 156 remote_src_path, 157 local_dest_path, 158 google_apis::test_util::CreateCopyResultCallback(&error)); 159 test_util::RunBlockingPoolTask(); 160 EXPECT_EQ(FILE_ERROR_OK, error); 161 162 // The content is "x"s of the file size. 163 base::FilePath cache_path; 164 cache()->GetFileOnUIThread(entry.resource_id(), 165 google_apis::test_util::CreateCopyResultCallback( 166 &error, &cache_path)); 167 test_util::RunBlockingPoolTask(); 168 EXPECT_EQ(FILE_ERROR_OK, error); 169 170 const std::string kExpectedContent = "This is some test content."; 171 std::string cache_file_data; 172 EXPECT_TRUE(file_util::ReadFileToString(cache_path, &cache_file_data)); 173 EXPECT_EQ(kExpectedContent, cache_file_data); 174 175 std::string local_dest_file_data; 176 EXPECT_TRUE(file_util::ReadFileToString(local_dest_path, 177 &local_dest_file_data)); 178 EXPECT_EQ(kExpectedContent, local_dest_file_data); 179 180 // The transfered file is cached and the change of "offline available" 181 // attribute is notified. 182 EXPECT_EQ(1U, observer()->get_changed_paths().size()); 183 EXPECT_TRUE(observer()->get_changed_paths().count(remote_src_path.DirName())); 184} 185 186TEST_F(CopyOperationTest, TransferFileFromRemoteToLocal_HostedDocument) { 187 base::FilePath local_dest_path = temp_dir().AppendASCII("local_copy.txt"); 188 base::FilePath remote_src_path( 189 FILE_PATH_LITERAL("drive/root/Document 1 excludeDir-test.gdoc")); 190 191 FileError error = FILE_ERROR_FAILED; 192 operation_->TransferFileFromRemoteToLocal( 193 remote_src_path, 194 local_dest_path, 195 google_apis::test_util::CreateCopyResultCallback(&error)); 196 test_util::RunBlockingPoolTask(); 197 EXPECT_EQ(FILE_ERROR_OK, error); 198 199 ResourceEntry entry; 200 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_src_path, &entry)); 201 EXPECT_EQ(GURL(entry.file_specific_info().alternate_url()), 202 util::ReadUrlFromGDocFile(local_dest_path)); 203 EXPECT_EQ(entry.resource_id(), 204 util::ReadResourceIdFromGDocFile(local_dest_path)); 205 EXPECT_TRUE(observer()->get_changed_paths().empty()); 206} 207 208TEST_F(CopyOperationTest, CopyNotExistingFile) { 209 base::FilePath src_path(FILE_PATH_LITERAL("drive/root/Dummy file.txt")); 210 base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/Test.log")); 211 212 ResourceEntry entry; 213 ASSERT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(src_path, &entry)); 214 215 FileError error = FILE_ERROR_OK; 216 operation_->Copy(src_path, 217 dest_path, 218 google_apis::test_util::CreateCopyResultCallback(&error)); 219 test_util::RunBlockingPoolTask(); 220 EXPECT_EQ(FILE_ERROR_NOT_FOUND, error); 221 222 EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(src_path, &entry)); 223 EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry)); 224 EXPECT_TRUE(observer()->get_changed_paths().empty()); 225} 226 227TEST_F(CopyOperationTest, CopyFileToNonExistingDirectory) { 228 base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt")); 229 base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/Dummy/Test.log")); 230 231 ResourceEntry entry; 232 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry)); 233 ASSERT_EQ(FILE_ERROR_NOT_FOUND, 234 GetLocalResourceEntry(dest_path.DirName(), &entry)); 235 236 FileError error = FILE_ERROR_OK; 237 operation_->Copy(src_path, 238 dest_path, 239 google_apis::test_util::CreateCopyResultCallback(&error)); 240 test_util::RunBlockingPoolTask(); 241 EXPECT_EQ(FILE_ERROR_NOT_FOUND, error); 242 243 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry)); 244 EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry)); 245 EXPECT_TRUE(observer()->get_changed_paths().empty()); 246} 247 248// Test the case where the parent of the destination path is an existing file, 249// not a directory. 250TEST_F(CopyOperationTest, CopyFileToInvalidPath) { 251 base::FilePath src_path(FILE_PATH_LITERAL( 252 "drive/root/Document 1 excludeDir-test.gdoc")); 253 base::FilePath dest_path(FILE_PATH_LITERAL( 254 "drive/root/Duplicate Name.txt/Document 1 excludeDir-test.gdoc")); 255 256 ResourceEntry entry; 257 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry)); 258 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path.DirName(), &entry)); 259 ASSERT_FALSE(entry.file_info().is_directory()); 260 261 FileError error = FILE_ERROR_OK; 262 operation_->Copy(src_path, 263 dest_path, 264 google_apis::test_util::CreateCopyResultCallback(&error)); 265 test_util::RunBlockingPoolTask(); 266 EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, error); 267 268 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry)); 269 EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry)); 270 EXPECT_TRUE(observer()->get_changed_paths().empty()); 271} 272 273} // namespace file_system 274} // namespace drive 275