copy_operation_unittest.cc revision 58e6fbe4ee35d65e14b626c557d37565bf8ad179
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(), std::string(),
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_HostedDocument) {
76  const base::FilePath local_src_path = temp_dir().AppendASCII("local.gdoc");
77  const base::FilePath remote_dest_path(FILE_PATH_LITERAL(
78      "drive/root/Directory 1/Document 1 excludeDir-test.gdoc"));
79
80  // Prepare a local file, which is a json file of a hosted document, which
81  // matches "Document 1" in root_feed.json.
82  ASSERT_TRUE(util::CreateGDocFile(
83      local_src_path,
84      GURL("https://3_document_self_link/document:5_document_resource_id"),
85      "document:5_document_resource_id"));
86
87  ResourceEntry entry;
88  ASSERT_EQ(FILE_ERROR_NOT_FOUND,
89            GetLocalResourceEntry(remote_dest_path, &entry));
90
91  // Transfer the local file to Drive.
92  FileError error = FILE_ERROR_FAILED;
93  operation_->TransferFileFromLocalToRemote(
94      local_src_path,
95      remote_dest_path,
96      google_apis::test_util::CreateCopyResultCallback(&error));
97  test_util::RunBlockingPoolTask();
98  EXPECT_EQ(FILE_ERROR_OK, error);
99
100  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_dest_path, &entry));
101
102  // We added a file to the Drive root and then moved to "Directory 1".
103  EXPECT_EQ(2U, observer()->get_changed_paths().size());
104  EXPECT_TRUE(observer()->get_changed_paths().count(
105      base::FilePath(FILE_PATH_LITERAL("drive/root"))));
106  EXPECT_TRUE(observer()->get_changed_paths().count(
107      remote_dest_path.DirName()));
108}
109
110TEST_F(CopyOperationTest, TransferFileFromRemoteToLocal_RegularFile) {
111  base::FilePath remote_src_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
112  base::FilePath local_dest_path = temp_dir().AppendASCII("local_copy.txt");
113
114  ResourceEntry entry;
115  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_src_path, &entry));
116
117  FileError error = FILE_ERROR_FAILED;
118  operation_->TransferFileFromRemoteToLocal(
119      remote_src_path,
120      local_dest_path,
121      google_apis::test_util::CreateCopyResultCallback(&error));
122  test_util::RunBlockingPoolTask();
123  EXPECT_EQ(FILE_ERROR_OK, error);
124
125  // The content is "x"s of the file size.
126  base::FilePath cache_path;
127  cache()->GetFileOnUIThread(entry.resource_id(),
128                             google_apis::test_util::CreateCopyResultCallback(
129                                 &error, &cache_path));
130  test_util::RunBlockingPoolTask();
131  EXPECT_EQ(FILE_ERROR_OK, error);
132
133  const std::string kExpectedContent = "This is some test content.";
134  std::string cache_file_data;
135  EXPECT_TRUE(file_util::ReadFileToString(cache_path, &cache_file_data));
136  EXPECT_EQ(kExpectedContent, cache_file_data);
137
138  std::string local_dest_file_data;
139  EXPECT_TRUE(file_util::ReadFileToString(local_dest_path,
140                                          &local_dest_file_data));
141  EXPECT_EQ(kExpectedContent, local_dest_file_data);
142
143  // The transfered file is cached and the change of "offline available"
144  // attribute is notified.
145  EXPECT_EQ(1U, observer()->get_changed_paths().size());
146  EXPECT_TRUE(observer()->get_changed_paths().count(remote_src_path.DirName()));
147}
148
149TEST_F(CopyOperationTest, TransferFileFromRemoteToLocal_HostedDocument) {
150  base::FilePath local_dest_path = temp_dir().AppendASCII("local_copy.txt");
151  base::FilePath remote_src_path(
152      FILE_PATH_LITERAL("drive/root/Document 1 excludeDir-test.gdoc"));
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  ResourceEntry entry;
163  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_src_path, &entry));
164  EXPECT_EQ(GURL(entry.file_specific_info().alternate_url()),
165            util::ReadUrlFromGDocFile(local_dest_path));
166  EXPECT_EQ(entry.resource_id(),
167            util::ReadResourceIdFromGDocFile(local_dest_path));
168  EXPECT_TRUE(observer()->get_changed_paths().empty());
169}
170
171TEST_F(CopyOperationTest, CopyNotExistingFile) {
172  base::FilePath src_path(FILE_PATH_LITERAL("drive/root/Dummy file.txt"));
173  base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/Test.log"));
174
175  ResourceEntry entry;
176  ASSERT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(src_path, &entry));
177
178  FileError error = FILE_ERROR_OK;
179  operation_->Copy(src_path,
180                   dest_path,
181                   google_apis::test_util::CreateCopyResultCallback(&error));
182  test_util::RunBlockingPoolTask();
183  EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
184
185  EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(src_path, &entry));
186  EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry));
187  EXPECT_TRUE(observer()->get_changed_paths().empty());
188}
189
190TEST_F(CopyOperationTest, CopyFileToNonExistingDirectory) {
191  base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
192  base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/Dummy/Test.log"));
193
194  ResourceEntry entry;
195  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
196  ASSERT_EQ(FILE_ERROR_NOT_FOUND,
197            GetLocalResourceEntry(dest_path.DirName(), &entry));
198
199  FileError error = FILE_ERROR_OK;
200  operation_->Copy(src_path,
201                   dest_path,
202                   google_apis::test_util::CreateCopyResultCallback(&error));
203  test_util::RunBlockingPoolTask();
204  EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
205
206  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
207  EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry));
208  EXPECT_TRUE(observer()->get_changed_paths().empty());
209}
210
211// Test the case where the parent of the destination path is an existing file,
212// not a directory.
213TEST_F(CopyOperationTest, CopyFileToInvalidPath) {
214  base::FilePath src_path(FILE_PATH_LITERAL(
215      "drive/root/Document 1 excludeDir-test.gdoc"));
216  base::FilePath dest_path(FILE_PATH_LITERAL(
217      "drive/root/Duplicate Name.txt/Document 1 excludeDir-test.gdoc"));
218
219  ResourceEntry entry;
220  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
221  ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path.DirName(), &entry));
222  ASSERT_FALSE(entry.file_info().is_directory());
223
224  FileError error = FILE_ERROR_OK;
225  operation_->Copy(src_path,
226                   dest_path,
227                   google_apis::test_util::CreateCopyResultCallback(&error));
228  test_util::RunBlockingPoolTask();
229  EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, error);
230
231  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
232  EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry));
233  EXPECT_TRUE(observer()->get_changed_paths().empty());
234}
235
236}  // namespace file_system
237}  // namespace drive
238