2416ac875b9fb96e627e7b0a2bbcc4632ebf8933
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / drive / file_system / copy_operation_unittest.cc
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 "base/task_runner_util.h"
9 #include "chrome/browser/chromeos/drive/file_cache.h"
10 #include "chrome/browser/chromeos/drive/file_system/operation_test_base.h"
11 #include "chrome/browser/chromeos/drive/file_system_util.h"
12 #include "chrome/browser/drive/drive_api_util.h"
13 #include "chrome/browser/drive/fake_drive_service.h"
14 #include "google_apis/drive/test_util.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace drive {
18 namespace file_system {
19
20 class CopyOperationTest : public OperationTestBase {
21  protected:
22   virtual void SetUp() OVERRIDE {
23    OperationTestBase::SetUp();
24    operation_.reset(new CopyOperation(
25        blocking_task_runner(),
26        observer(),
27        scheduler(),
28        metadata(),
29        cache(),
30        util::GetIdentityResourceIdCanonicalizer()));
31   }
32
33   scoped_ptr<CopyOperation> operation_;
34 };
35
36 TEST_F(CopyOperationTest, TransferFileFromLocalToRemote_RegularFile) {
37   const base::FilePath local_src_path = temp_dir().AppendASCII("local.txt");
38   const base::FilePath remote_dest_path(
39       FILE_PATH_LITERAL("drive/root/remote.txt"));
40
41   // Prepare a local file.
42   ASSERT_TRUE(
43       google_apis::test_util::WriteStringToFile(local_src_path, "hello"));
44   // Confirm that the remote file does not exist.
45   ResourceEntry entry;
46   ASSERT_EQ(FILE_ERROR_NOT_FOUND,
47             GetLocalResourceEntry(remote_dest_path, &entry));
48
49   // Transfer the local file to Drive.
50   FileError error = FILE_ERROR_FAILED;
51   operation_->TransferFileFromLocalToRemote(
52       local_src_path,
53       remote_dest_path,
54       google_apis::test_util::CreateCopyResultCallback(&error));
55   test_util::RunBlockingPoolTask();
56   EXPECT_EQ(FILE_ERROR_OK, error);
57
58   // TransferFileFromLocalToRemote stores a copy of the local file in the cache,
59   // marks it dirty and requests the observer to upload the file.
60   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_dest_path, &entry));
61   EXPECT_EQ(1U, observer()->updated_local_ids().count(
62       GetLocalId(remote_dest_path)));
63   FileCacheEntry cache_entry;
64   bool found = false;
65   base::PostTaskAndReplyWithResult(
66       blocking_task_runner(),
67       FROM_HERE,
68       base::Bind(&internal::FileCache::GetCacheEntry,
69                  base::Unretained(cache()),
70                  GetLocalId(remote_dest_path),
71                  &cache_entry),
72       google_apis::test_util::CreateCopyResultCallback(&found));
73   test_util::RunBlockingPoolTask();
74   EXPECT_TRUE(found);
75   EXPECT_TRUE(cache_entry.is_present());
76   EXPECT_TRUE(cache_entry.is_dirty());
77
78   EXPECT_EQ(1U, observer()->get_changed_paths().size());
79   EXPECT_TRUE(observer()->get_changed_paths().count(
80       remote_dest_path.DirName()));
81 }
82
83 TEST_F(CopyOperationTest, TransferFileFromLocalToRemote_Overwrite) {
84   const base::FilePath local_src_path = temp_dir().AppendASCII("local.txt");
85   const base::FilePath remote_dest_path(
86       FILE_PATH_LITERAL("drive/root/File 1.txt"));
87
88   // Prepare a local file.
89   EXPECT_TRUE(
90       google_apis::test_util::WriteStringToFile(local_src_path, "hello"));
91   // Confirm that the remote file exists.
92   ResourceEntry entry;
93   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_dest_path, &entry));
94
95   // Transfer the local file to Drive.
96   FileError error = FILE_ERROR_FAILED;
97   operation_->TransferFileFromLocalToRemote(
98       local_src_path,
99       remote_dest_path,
100       google_apis::test_util::CreateCopyResultCallback(&error));
101   test_util::RunBlockingPoolTask();
102   EXPECT_EQ(FILE_ERROR_OK, error);
103
104   // TransferFileFromLocalToRemote stores a copy of the local file in the cache,
105   // marks it dirty and requests the observer to upload the file.
106   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_dest_path, &entry));
107   EXPECT_EQ(1U, observer()->updated_local_ids().count(entry.local_id()));
108   FileCacheEntry cache_entry;
109   bool found = false;
110   base::PostTaskAndReplyWithResult(
111       blocking_task_runner(),
112       FROM_HERE,
113       base::Bind(&internal::FileCache::GetCacheEntry,
114                  base::Unretained(cache()), entry.local_id(), &cache_entry),
115       google_apis::test_util::CreateCopyResultCallback(&found));
116   test_util::RunBlockingPoolTask();
117   EXPECT_TRUE(found);
118   EXPECT_TRUE(cache_entry.is_present());
119   EXPECT_TRUE(cache_entry.is_dirty());
120
121   EXPECT_EQ(1U, observer()->get_changed_paths().size());
122   EXPECT_TRUE(observer()->get_changed_paths().count(
123       remote_dest_path.DirName()));
124 }
125
126 TEST_F(CopyOperationTest, TransferFileFromLocalToRemote_HostedDocument) {
127   const base::FilePath local_src_path = temp_dir().AppendASCII("local.gdoc");
128   const base::FilePath remote_dest_path(FILE_PATH_LITERAL(
129       "drive/root/Directory 1/Document 1 excludeDir-test.gdoc"));
130
131   // Prepare a local file, which is a json file of a hosted document, which
132   // matches "Document 1" in root_feed.json.
133   ASSERT_TRUE(util::CreateGDocFile(
134       local_src_path,
135       GURL("https://3_document_self_link/document:5_document_resource_id"),
136       "document:5_document_resource_id"));
137
138   ResourceEntry entry;
139   ASSERT_EQ(FILE_ERROR_NOT_FOUND,
140             GetLocalResourceEntry(remote_dest_path, &entry));
141
142   // Transfer the local file to Drive.
143   FileError error = FILE_ERROR_FAILED;
144   operation_->TransferFileFromLocalToRemote(
145       local_src_path,
146       remote_dest_path,
147       google_apis::test_util::CreateCopyResultCallback(&error));
148   test_util::RunBlockingPoolTask();
149   EXPECT_EQ(FILE_ERROR_OK, error);
150
151   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_dest_path, &entry));
152
153   EXPECT_EQ(1U, observer()->get_changed_paths().size());
154   EXPECT_TRUE(
155       observer()->get_changed_paths().count(remote_dest_path.DirName()));
156 }
157
158
159 TEST_F(CopyOperationTest, CopyNotExistingFile) {
160   base::FilePath src_path(FILE_PATH_LITERAL("drive/root/Dummy file.txt"));
161   base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/Test.log"));
162
163   ResourceEntry entry;
164   ASSERT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(src_path, &entry));
165
166   FileError error = FILE_ERROR_OK;
167   operation_->Copy(src_path,
168                    dest_path,
169                    false,
170                    google_apis::test_util::CreateCopyResultCallback(&error));
171   test_util::RunBlockingPoolTask();
172   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
173
174   EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(src_path, &entry));
175   EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry));
176   EXPECT_TRUE(observer()->get_changed_paths().empty());
177 }
178
179 TEST_F(CopyOperationTest, CopyFileToNonExistingDirectory) {
180   base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
181   base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/Dummy/Test.log"));
182
183   ResourceEntry entry;
184   ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
185   ASSERT_EQ(FILE_ERROR_NOT_FOUND,
186             GetLocalResourceEntry(dest_path.DirName(), &entry));
187
188   FileError error = FILE_ERROR_OK;
189   operation_->Copy(src_path,
190                    dest_path,
191                    false,
192                    google_apis::test_util::CreateCopyResultCallback(&error));
193   test_util::RunBlockingPoolTask();
194   EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
195
196   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
197   EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry));
198   EXPECT_TRUE(observer()->get_changed_paths().empty());
199 }
200
201 // Test the case where the parent of the destination path is an existing file,
202 // not a directory.
203 TEST_F(CopyOperationTest, CopyFileToInvalidPath) {
204   base::FilePath src_path(FILE_PATH_LITERAL(
205       "drive/root/Document 1 excludeDir-test.gdoc"));
206   base::FilePath dest_path(FILE_PATH_LITERAL(
207       "drive/root/Duplicate Name.txt/Document 1 excludeDir-test.gdoc"));
208
209   ResourceEntry entry;
210   ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
211   ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path.DirName(), &entry));
212   ASSERT_FALSE(entry.file_info().is_directory());
213
214   FileError error = FILE_ERROR_OK;
215   operation_->Copy(src_path,
216                    dest_path,
217                    false,
218                    google_apis::test_util::CreateCopyResultCallback(&error));
219   test_util::RunBlockingPoolTask();
220   EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, error);
221
222   EXPECT_EQ(FILE_ERROR_OK, 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
227 TEST_F(CopyOperationTest, CopyDirtyFile) {
228   base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
229   base::FilePath dest_path(FILE_PATH_LITERAL(
230       "drive/root/Directory 1/New File.txt"));
231
232   ResourceEntry src_entry;
233   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &src_entry));
234
235   // Store a dirty cache file.
236   base::FilePath temp_file;
237   EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir(), &temp_file));
238   std::string contents = "test content";
239   EXPECT_TRUE(google_apis::test_util::WriteStringToFile(temp_file, contents));
240   FileError error = FILE_ERROR_FAILED;
241   base::PostTaskAndReplyWithResult(
242       blocking_task_runner(),
243       FROM_HERE,
244       base::Bind(&internal::FileCache::Store,
245                  base::Unretained(cache()),
246                  src_entry.local_id(),
247                  std::string(),
248                  temp_file,
249                  internal::FileCache::FILE_OPERATION_MOVE),
250       google_apis::test_util::CreateCopyResultCallback(&error));
251   test_util::RunBlockingPoolTask();
252   EXPECT_EQ(FILE_ERROR_OK, error);
253
254   // Copy.
255   operation_->Copy(src_path,
256                    dest_path,
257                    false,
258                    google_apis::test_util::CreateCopyResultCallback(&error));
259   test_util::RunBlockingPoolTask();
260   EXPECT_EQ(FILE_ERROR_OK, error);
261
262   ResourceEntry dest_entry;
263   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));
264   EXPECT_EQ(ResourceEntry::DIRTY, dest_entry.metadata_edit_state());
265
266   EXPECT_EQ(1u, observer()->updated_local_ids().size());
267   EXPECT_TRUE(observer()->updated_local_ids().count(dest_entry.local_id()));
268   EXPECT_EQ(1u, observer()->get_changed_paths().size());
269   EXPECT_TRUE(observer()->get_changed_paths().count(dest_path.DirName()));
270
271   // Copied cache file should be dirty.
272   bool success = false;
273   FileCacheEntry cache_entry;
274   base::PostTaskAndReplyWithResult(
275       blocking_task_runner(),
276       FROM_HERE,
277       base::Bind(&internal::FileCache::GetCacheEntry,
278                  base::Unretained(cache()),
279                  dest_entry.local_id(),
280                  &cache_entry),
281       google_apis::test_util::CreateCopyResultCallback(&success));
282   test_util::RunBlockingPoolTask();
283   EXPECT_TRUE(success);
284   EXPECT_TRUE(cache_entry.is_dirty());
285
286   // File contents should match.
287   base::FilePath cache_file_path;
288   base::PostTaskAndReplyWithResult(
289       blocking_task_runner(),
290       FROM_HERE,
291       base::Bind(&internal::FileCache::GetFile,
292                  base::Unretained(cache()),
293                  dest_entry.local_id(),
294                  &cache_file_path),
295       google_apis::test_util::CreateCopyResultCallback(&error));
296   test_util::RunBlockingPoolTask();
297   EXPECT_EQ(FILE_ERROR_OK, error);
298
299   std::string copied_contents;
300   EXPECT_TRUE(base::ReadFileToString(cache_file_path, &copied_contents));
301   EXPECT_EQ(contents, copied_contents);
302 }
303
304 TEST_F(CopyOperationTest, CopyFileOverwriteFile) {
305   base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
306   base::FilePath dest_path(FILE_PATH_LITERAL(
307       "drive/root/Directory 1/SubDirectory File 1.txt"));
308
309   ResourceEntry old_dest_entry;
310   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &old_dest_entry));
311
312   FileError error = FILE_ERROR_OK;
313   operation_->Copy(src_path,
314                    dest_path,
315                    false,
316                    google_apis::test_util::CreateCopyResultCallback(&error));
317   test_util::RunBlockingPoolTask();
318   EXPECT_EQ(FILE_ERROR_OK, error);
319
320   ResourceEntry new_dest_entry;
321   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &new_dest_entry));
322
323   EXPECT_EQ(1u, observer()->updated_local_ids().size());
324   EXPECT_TRUE(observer()->updated_local_ids().count(old_dest_entry.local_id()));
325   EXPECT_EQ(1u, observer()->get_changed_paths().size());
326   EXPECT_TRUE(observer()->get_changed_paths().count(dest_path.DirName()));
327 }
328
329 TEST_F(CopyOperationTest, CopyFileOverwriteDirectory) {
330   base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
331   base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/Directory 1"));
332
333   FileError error = FILE_ERROR_OK;
334   operation_->Copy(src_path,
335                    dest_path,
336                    false,
337                    google_apis::test_util::CreateCopyResultCallback(&error));
338   test_util::RunBlockingPoolTask();
339   EXPECT_EQ(FILE_ERROR_INVALID_OPERATION, error);
340 }
341
342 TEST_F(CopyOperationTest, CopyDirectory) {
343   base::FilePath src_path(FILE_PATH_LITERAL("drive/root/Directory 1"));
344   base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/New Directory"));
345
346   ResourceEntry entry;
347   ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
348   ASSERT_TRUE(entry.file_info().is_directory());
349   ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path.DirName(), &entry));
350   ASSERT_TRUE(entry.file_info().is_directory());
351
352   FileError error = FILE_ERROR_OK;
353   operation_->Copy(src_path,
354                    dest_path,
355                    false,
356                    google_apis::test_util::CreateCopyResultCallback(&error));
357   test_util::RunBlockingPoolTask();
358   EXPECT_EQ(FILE_ERROR_NOT_A_FILE, error);
359 }
360
361 TEST_F(CopyOperationTest, PreserveLastModified) {
362   base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
363   base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/File 2.txt"));
364
365   ResourceEntry entry;
366   ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
367   ASSERT_EQ(FILE_ERROR_OK,
368             GetLocalResourceEntry(dest_path.DirName(), &entry));
369
370   FileError error = FILE_ERROR_OK;
371   operation_->Copy(src_path,
372                    dest_path,
373                    true,  // Preserve last modified.
374                    google_apis::test_util::CreateCopyResultCallback(&error));
375   test_util::RunBlockingPoolTask();
376   EXPECT_EQ(FILE_ERROR_OK, error);
377
378   ResourceEntry entry2;
379   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
380   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &entry2));
381   EXPECT_EQ(entry.file_info().last_modified(),
382             entry2.file_info().last_modified());
383 }
384
385 }  // namespace file_system
386 }  // namespace drive