- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / drive / change_list_processor_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/change_list_processor.h"
6
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/message_loop/message_loop_proxy.h"
9 #include "base/values.h"
10 #include "chrome/browser/chromeos/drive/drive.pb.h"
11 #include "chrome/browser/chromeos/drive/file_system_util.h"
12 #include "chrome/browser/chromeos/drive/resource_metadata.h"
13 #include "chrome/browser/chromeos/drive/test_util.h"
14 #include "chrome/browser/google_apis/drive_api_parser.h"
15 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
16 #include "chrome/browser/google_apis/test_util.h"
17 #include "content/public/test/test_browser_thread_bundle.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 namespace drive {
21 namespace internal {
22
23 namespace {
24
25 const int64 kBaseResourceListChangestamp = 123;
26 const char kBaseResourceListFile[] = "gdata/root_feed.json";
27 const char kRootId[] = "fake_root";
28
29 enum FileOrDirectory {
30   FILE,
31   DIRECTORY,
32 };
33
34 struct EntryExpectation {
35   std::string path;
36   std::string id;
37   std::string parent_id;
38   FileOrDirectory type;
39 };
40
41 typedef std::map<std::string, ResourceEntry> ResourceEntryMap;
42 typedef std::map<std::string, std::string> ParentResourceIdMap;
43 void ConvertToMap(ScopedVector<ChangeList> change_lists,
44                   ResourceEntryMap* entry_map,
45                   ParentResourceIdMap* parent_resource_id_map) {
46   for (size_t i = 0; i < change_lists.size(); ++i) {
47     const std::vector<ResourceEntry>& entries = change_lists[i]->entries();
48     const std::vector<std::string>& parent_resource_ids =
49         change_lists[i]->parent_resource_ids();
50     EXPECT_EQ(entries.size(), parent_resource_ids.size());
51
52     for (size_t i = 0; i < entries.size(); ++i) {
53       const std::string& resource_id = entries[i].resource_id();
54       (*parent_resource_id_map)[resource_id] = parent_resource_ids[i];
55       (*entry_map)[resource_id] = entries[i];
56     }
57   }
58 }
59
60 class ChangeListProcessorTest : public testing::Test {
61  protected:
62   virtual void SetUp() OVERRIDE {
63     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
64
65     metadata_storage_.reset(new ResourceMetadataStorage(
66         temp_dir_.path(), base::MessageLoopProxy::current().get()));
67     ASSERT_TRUE(metadata_storage_->Initialize());
68
69     metadata_.reset(new internal::ResourceMetadata(
70         metadata_storage_.get(), base::MessageLoopProxy::current()));
71     ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize());
72   }
73
74   // Parses a json file at |test_data_path| relative to Chrome test directory
75   // into a ScopedVector<drive::internal::ChangeList>.
76   ScopedVector<ChangeList> ParseChangeList(const std::string& test_data_path) {
77     ScopedVector<ChangeList> changes;
78     changes.push_back(new ChangeList(
79         *google_apis::ResourceList::ExtractAndParse(
80             *google_apis::test_util::LoadJSONFile(
81                 test_data_path))));
82     return changes.Pass();
83   }
84
85   // Applies the |changes| to |metadata_| as a full resource list of changestamp
86   // |kBaseResourceListChangestamp|.
87   FileError ApplyFullResourceList(ScopedVector<ChangeList> changes) {
88     scoped_ptr<google_apis::AboutResource> about_resource(
89         new google_apis::AboutResource);
90     about_resource->set_largest_change_id(kBaseResourceListChangestamp);
91     about_resource->set_root_folder_id(kRootId);
92
93     ChangeListProcessor processor(metadata_.get());
94     return processor.Apply(about_resource.Pass(),
95                            changes.Pass(),
96                            false /* is_delta_update */);
97   }
98
99   // Applies the |changes| to |metadata_| as a delta update. Delta changelists
100   // should contain their changestamp in themselves.
101   FileError ApplyChangeList(ScopedVector<ChangeList> changes,
102                             std::set<base::FilePath>* changed_dirs) {
103     scoped_ptr<google_apis::AboutResource> about_resource(
104         new google_apis::AboutResource);
105     about_resource->set_largest_change_id(kBaseResourceListChangestamp);
106     about_resource->set_root_folder_id(kRootId);
107
108     ChangeListProcessor processor(metadata_.get());
109     FileError error = processor.Apply(about_resource.Pass(),
110                                       changes.Pass(),
111                                       true /* is_delta_update */);
112     *changed_dirs = processor.changed_dirs();
113     return error;
114   }
115
116   // Gets the resource entry for the path from |metadata_| synchronously.
117   // Returns null if the entry does not exist.
118   scoped_ptr<ResourceEntry> GetResourceEntry(const std::string& path) {
119     scoped_ptr<ResourceEntry> entry(new ResourceEntry);
120     FileError error = metadata_->GetResourceEntryByPath(
121         base::FilePath::FromUTF8Unsafe(path), entry.get());
122     if (error != FILE_ERROR_OK)
123       entry.reset();
124     return entry.Pass();
125   }
126
127   content::TestBrowserThreadBundle thread_bundle_;
128   base::ScopedTempDir temp_dir_;
129   scoped_ptr<ResourceMetadataStorage,
130              test_util::DestroyHelperForTests> metadata_storage_;
131   scoped_ptr<ResourceMetadata, test_util::DestroyHelperForTests> metadata_;
132 };
133
134 }  // namespace
135
136 TEST_F(ChangeListProcessorTest, ApplyFullResourceList) {
137   EXPECT_EQ(FILE_ERROR_OK,
138             ApplyFullResourceList(ParseChangeList(kBaseResourceListFile)));
139
140   const EntryExpectation kExpected[] = {
141       // Root files
142       {"drive/root",
143           kRootId, util::kDriveGrandRootSpecialResourceId, DIRECTORY},
144       {"drive/root/File 1.txt",
145           "file:2_file_resource_id", kRootId, FILE},
146       {"drive/root/Slash \xE2\x88\x95 in file 1.txt",
147           "file:slash_file_resource_id", kRootId, FILE},
148       {"drive/root/Document 1 excludeDir-test.gdoc",
149           "document:5_document_resource_id", kRootId, FILE},
150       // Subdirectory files
151       {"drive/root/Directory 1",
152           "folder:1_folder_resource_id", kRootId, DIRECTORY},
153       {"drive/root/Directory 1/SubDirectory File 1.txt",
154           "file:subdirectory_file_1_id", "folder:1_folder_resource_id", FILE},
155       {"drive/root/Directory 1/Shared To The Account Owner.txt",
156           "file:subdirectory_unowned_file_1_id",
157           "folder:1_folder_resource_id", FILE},
158       {"drive/root/Directory 2 excludeDir-test",
159           "folder:sub_dir_folder_2_self_link", kRootId, DIRECTORY},
160       {"drive/root/Slash \xE2\x88\x95 in directory",
161           "folder:slash_dir_folder_resource_id", kRootId, DIRECTORY},
162       {"drive/root/Slash \xE2\x88\x95 in directory/Slash SubDir File.txt",
163           "file:slash_subdir_file",
164           "folder:slash_dir_folder_resource_id", FILE},
165       // Deeper
166       {"drive/root/Directory 1/Sub Directory Folder",
167           "folder:sub_dir_folder_resource_id",
168           "folder:1_folder_resource_id", DIRECTORY},
169       {"drive/root/Directory 1/Sub Directory Folder/Sub Sub Directory Folder",
170           "folder:sub_sub_directory_folder_id",
171           "folder:sub_dir_folder_resource_id", DIRECTORY},
172       // Orphan
173       {"drive/other/Orphan File 1.txt",
174           "file:1_orphanfile_resource_id",
175           util::kDriveOtherDirSpecialResourceId, FILE},
176   };
177
178   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kExpected); ++i) {
179     scoped_ptr<ResourceEntry> entry = GetResourceEntry(kExpected[i].path);
180     ASSERT_TRUE(entry) << "for path: " << kExpected[i].path;
181     EXPECT_EQ(kExpected[i].id, entry->resource_id());
182
183     ResourceEntry parent_entry;
184     EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryById(
185         entry->parent_local_id(), &parent_entry));
186     EXPECT_EQ(kExpected[i].parent_id, parent_entry.resource_id());
187     EXPECT_EQ(kExpected[i].type,
188               entry->file_info().is_directory() ? DIRECTORY : FILE);
189   }
190
191   EXPECT_EQ(kBaseResourceListChangestamp, metadata_->GetLargestChangestamp());
192 }
193
194 TEST_F(ChangeListProcessorTest, DeltaFileAddedInNewDirectory) {
195   const char kTestJson[] =
196       "gdata/delta_file_added_in_new_directory.json";
197
198   ResourceEntryMap entry_map;
199   ParentResourceIdMap parent_resource_id_map;
200   ConvertToMap(ParseChangeList(kTestJson), &entry_map, &parent_resource_id_map);
201
202   const std::string kNewFolderId("folder:new_folder_resource_id");
203   const std::string kNewFileId("document:file_added_in_new_dir_id");
204
205   // Check the content of parsed ResourceEntryMap.
206   EXPECT_EQ(2U, entry_map.size());
207   EXPECT_TRUE(entry_map.count(kNewFolderId));
208   EXPECT_TRUE(entry_map.count(kNewFileId));
209   EXPECT_EQ(kRootId, parent_resource_id_map[kNewFolderId]);
210   EXPECT_EQ(kNewFolderId, parent_resource_id_map[kNewFileId]);
211   EXPECT_TRUE(entry_map[kNewFolderId].file_info().is_directory());
212   EXPECT_FALSE(entry_map[kNewFileId].file_info().is_directory());
213   EXPECT_EQ("New Directory", entry_map[kNewFolderId].title());
214   EXPECT_EQ("File in new dir", entry_map[kNewFileId].title());
215
216   // Apply the changelist and check the effect.
217   EXPECT_EQ(FILE_ERROR_OK,
218             ApplyFullResourceList(ParseChangeList(kBaseResourceListFile)));
219   std::set<base::FilePath> changed_dirs;
220   EXPECT_EQ(FILE_ERROR_OK,
221             ApplyChangeList(ParseChangeList(kTestJson), &changed_dirs));
222
223   // The value is written in kTestJson.
224   EXPECT_EQ(16730, metadata_->GetLargestChangestamp());
225   EXPECT_TRUE(GetResourceEntry("drive/root/New Directory"));
226   EXPECT_TRUE(GetResourceEntry(
227       "drive/root/New Directory/File in new dir.gdoc"));
228
229   EXPECT_EQ(2U, changed_dirs.size());
230   EXPECT_TRUE(changed_dirs.count(
231       base::FilePath::FromUTF8Unsafe("drive/root")));
232   EXPECT_TRUE(changed_dirs.count(
233       base::FilePath::FromUTF8Unsafe("drive/root/New Directory")));
234 }
235
236 TEST_F(ChangeListProcessorTest, DeltaDirMovedFromRootToDirectory) {
237   const char kTestJson[] =
238       "gdata/delta_dir_moved_from_root_to_directory.json";
239
240   ResourceEntryMap entry_map;
241   ParentResourceIdMap parent_resource_id_map;
242   ConvertToMap(ParseChangeList(kTestJson), &entry_map, &parent_resource_id_map);
243
244   const std::string kMovedId("folder:1_folder_resource_id");
245   const std::string kDestId("folder:sub_dir_folder_2_self_link");
246
247   // Check the content of parsed ResourceEntryMap.
248   EXPECT_EQ(2U, entry_map.size());
249   EXPECT_TRUE(entry_map.count(kMovedId));
250   EXPECT_TRUE(entry_map.count(kDestId));
251   EXPECT_EQ(kDestId, parent_resource_id_map[kMovedId]);
252
253   // Apply the changelist and check the effect.
254   EXPECT_EQ(FILE_ERROR_OK,
255             ApplyFullResourceList(ParseChangeList(kBaseResourceListFile)));
256   std::set<base::FilePath> changed_dirs;
257   EXPECT_EQ(FILE_ERROR_OK,
258             ApplyChangeList(ParseChangeList(kTestJson), &changed_dirs));
259
260   // The value is written in kTestJson.
261   EXPECT_EQ(16809, metadata_->GetLargestChangestamp());
262   EXPECT_FALSE(GetResourceEntry("drive/root/Directory 1"));
263   EXPECT_TRUE(GetResourceEntry(
264       "drive/root/Directory 2 excludeDir-test/Directory 1"));
265
266   EXPECT_EQ(4U, changed_dirs.size());
267   EXPECT_TRUE(changed_dirs.count(
268       base::FilePath::FromUTF8Unsafe("drive/root")));
269   EXPECT_TRUE(changed_dirs.count(
270       base::FilePath::FromUTF8Unsafe("drive/root/Directory 1")));
271   EXPECT_TRUE(changed_dirs.count(
272       base::FilePath::FromUTF8Unsafe(
273           "drive/root/Directory 2 excludeDir-test")));
274   EXPECT_TRUE(changed_dirs.count(
275       base::FilePath::FromUTF8Unsafe(
276           "drive/root/Directory 2 excludeDir-test/Directory 1")));
277 }
278
279 TEST_F(ChangeListProcessorTest, DeltaFileMovedFromDirectoryToRoot) {
280   const char kTestJson[] =
281       "gdata/delta_file_moved_from_directory_to_root.json";
282
283   ResourceEntryMap entry_map;
284   ParentResourceIdMap parent_resource_id_map;
285   ConvertToMap(ParseChangeList(kTestJson), &entry_map, &parent_resource_id_map);
286
287   const std::string kMovedId("file:subdirectory_file_1_id");
288   const std::string kSrcId("folder:1_folder_resource_id");
289
290   // Check the content of parsed ResourceEntryMap.
291   EXPECT_EQ(2U, entry_map.size());
292   EXPECT_TRUE(entry_map.count(kMovedId));
293   EXPECT_TRUE(entry_map.count(kSrcId));
294   EXPECT_EQ(kRootId, parent_resource_id_map[kMovedId]);
295
296   // Apply the changelist and check the effect.
297   EXPECT_EQ(FILE_ERROR_OK,
298             ApplyFullResourceList(ParseChangeList(kBaseResourceListFile)));
299   std::set<base::FilePath> changed_dirs;
300   EXPECT_EQ(FILE_ERROR_OK,
301             ApplyChangeList(ParseChangeList(kTestJson), &changed_dirs));
302
303   // The value is written in kTestJson.
304   EXPECT_EQ(16815, metadata_->GetLargestChangestamp());
305   EXPECT_FALSE(GetResourceEntry(
306       "drive/root/Directory 1/SubDirectory File 1.txt"));
307   EXPECT_TRUE(GetResourceEntry("drive/root/SubDirectory File 1.txt"));
308
309   EXPECT_EQ(2U, changed_dirs.size());
310   EXPECT_TRUE(changed_dirs.count(
311       base::FilePath::FromUTF8Unsafe("drive/root")));
312   EXPECT_TRUE(changed_dirs.count(
313       base::FilePath::FromUTF8Unsafe("drive/root/Directory 1")));
314 }
315
316 TEST_F(ChangeListProcessorTest, DeltaFileRenamedInDirectory) {
317   const char kTestJson[] =
318       "gdata/delta_file_renamed_in_directory.json";
319
320   ResourceEntryMap entry_map;
321   ParentResourceIdMap parent_resource_id_map;
322   ConvertToMap(ParseChangeList(kTestJson), &entry_map, &parent_resource_id_map);
323
324   const std::string kRenamedId("file:subdirectory_file_1_id");
325   const std::string kParentId("folder:1_folder_resource_id");
326
327   // Check the content of parsed ResourceEntryMap.
328   EXPECT_EQ(2U, entry_map.size());
329   EXPECT_TRUE(entry_map.count(kRenamedId));
330   EXPECT_TRUE(entry_map.count(kParentId));
331   EXPECT_EQ(kParentId, parent_resource_id_map[kRenamedId]);
332   EXPECT_EQ("New SubDirectory File 1.txt", entry_map[kRenamedId].title());
333
334   // Apply the changelist and check the effect.
335   EXPECT_EQ(FILE_ERROR_OK,
336             ApplyFullResourceList(ParseChangeList(kBaseResourceListFile)));
337   std::set<base::FilePath> changed_dirs;
338   EXPECT_EQ(FILE_ERROR_OK,
339             ApplyChangeList(ParseChangeList(kTestJson), &changed_dirs));
340
341   // The value is written in kTestJson.
342   EXPECT_EQ(16767, metadata_->GetLargestChangestamp());
343   EXPECT_FALSE(GetResourceEntry(
344       "drive/root/Directory 1/SubDirectory File 1.txt"));
345   EXPECT_TRUE(GetResourceEntry(
346       "drive/root/Directory 1/New SubDirectory File 1.txt"));
347
348   EXPECT_EQ(2U, changed_dirs.size());
349   EXPECT_TRUE(changed_dirs.count(
350       base::FilePath::FromUTF8Unsafe("drive/root")));
351   EXPECT_TRUE(changed_dirs.count(
352       base::FilePath::FromUTF8Unsafe("drive/root/Directory 1")));
353 }
354
355 TEST_F(ChangeListProcessorTest, DeltaAddAndDeleteFileInRoot) {
356   const char kTestJsonAdd[] =
357       "gdata/delta_file_added_in_root.json";
358   const char kTestJsonDelete[] =
359       "gdata/delta_file_deleted_in_root.json";
360
361   const std::string kParentId(kRootId);
362   const std::string kFileId("document:added_in_root_id");
363
364   ResourceEntryMap entry_map;
365   ParentResourceIdMap parent_resource_id_map;
366
367   // Check the content of kTestJsonAdd.
368   ConvertToMap(ParseChangeList(kTestJsonAdd),
369                &entry_map, &parent_resource_id_map);
370   EXPECT_EQ(1U, entry_map.size());
371   EXPECT_TRUE(entry_map.count(kFileId));
372   EXPECT_EQ(kParentId, parent_resource_id_map[kFileId]);
373   EXPECT_EQ("Added file", entry_map[kFileId].title());
374   EXPECT_FALSE(entry_map[kFileId].deleted());
375
376   // Apply.
377   EXPECT_EQ(FILE_ERROR_OK,
378             ApplyFullResourceList(ParseChangeList(kBaseResourceListFile)));
379   std::set<base::FilePath> changed_dirs;
380   EXPECT_EQ(FILE_ERROR_OK,
381             ApplyChangeList(ParseChangeList(kTestJsonAdd), &changed_dirs));
382   EXPECT_EQ(16683, metadata_->GetLargestChangestamp());
383   EXPECT_TRUE(GetResourceEntry("drive/root/Added file.gdoc"));
384   EXPECT_EQ(1U, changed_dirs.size());
385   EXPECT_TRUE(changed_dirs.count(
386       base::FilePath::FromUTF8Unsafe("drive/root")));
387
388   // Check the content of kTestJsonDelete.
389   entry_map.clear();
390   parent_resource_id_map.clear();
391   ConvertToMap(ParseChangeList(kTestJsonDelete),
392                &entry_map, &parent_resource_id_map);
393   EXPECT_EQ(1U, entry_map.size());
394   EXPECT_TRUE(entry_map.count(kFileId));
395   EXPECT_EQ(kParentId, parent_resource_id_map[kFileId]);
396   EXPECT_EQ("Added file", entry_map[kFileId].title());
397   EXPECT_TRUE(entry_map[kFileId].deleted());
398
399   // Apply.
400   EXPECT_EQ(FILE_ERROR_OK,
401             ApplyChangeList(ParseChangeList(kTestJsonDelete), &changed_dirs));
402   EXPECT_EQ(16687, metadata_->GetLargestChangestamp());
403   EXPECT_FALSE(GetResourceEntry("drive/root/Added file.gdoc"));
404   EXPECT_EQ(1U, changed_dirs.size());
405   EXPECT_TRUE(changed_dirs.count(
406       base::FilePath::FromUTF8Unsafe("drive/root")));
407 }
408
409
410 TEST_F(ChangeListProcessorTest, DeltaAddAndDeleteFileFromExistingDirectory) {
411   const char kTestJsonAdd[] =
412       "gdata/delta_file_added_in_directory.json";
413   const char kTestJsonDelete[] =
414       "gdata/delta_file_deleted_in_directory.json";
415
416   const std::string kParentId("folder:1_folder_resource_id");
417   const std::string kFileId("document:added_in_root_id");
418
419   ResourceEntryMap entry_map;
420   ParentResourceIdMap parent_resource_id_map;
421
422   // Check the content of kTestJsonAdd.
423   ConvertToMap(ParseChangeList(kTestJsonAdd),
424                &entry_map, &parent_resource_id_map);
425   EXPECT_EQ(2U, entry_map.size());
426   EXPECT_TRUE(entry_map.count(kFileId));
427   EXPECT_TRUE(entry_map.count(kParentId));
428   EXPECT_EQ(kParentId, parent_resource_id_map[kFileId]);
429   EXPECT_EQ("Added file", entry_map[kFileId].title());
430   EXPECT_FALSE(entry_map[kFileId].deleted());
431
432   // Apply.
433   EXPECT_EQ(FILE_ERROR_OK,
434             ApplyFullResourceList(ParseChangeList(kBaseResourceListFile)));
435   std::set<base::FilePath> changed_dirs;
436   EXPECT_EQ(FILE_ERROR_OK,
437             ApplyChangeList(ParseChangeList(kTestJsonAdd), &changed_dirs));
438   EXPECT_EQ(16730, metadata_->GetLargestChangestamp());
439   EXPECT_TRUE(GetResourceEntry("drive/root/Directory 1/Added file.gdoc"));
440
441   EXPECT_EQ(2U, changed_dirs.size());
442   EXPECT_TRUE(changed_dirs.count(
443       base::FilePath::FromUTF8Unsafe("drive/root")));
444   EXPECT_TRUE(changed_dirs.count(
445       base::FilePath::FromUTF8Unsafe("drive/root/Directory 1")));
446
447   // Check the content of kTestJsonDelete.
448   entry_map.clear();
449   parent_resource_id_map.clear();
450   ConvertToMap(ParseChangeList(kTestJsonDelete),
451                &entry_map, &parent_resource_id_map);
452   EXPECT_EQ(1U, entry_map.size());
453   EXPECT_TRUE(entry_map.count(kFileId));
454   EXPECT_EQ(kParentId, parent_resource_id_map[kFileId]);
455   EXPECT_EQ("Added file", entry_map[kFileId].title());
456   EXPECT_TRUE(entry_map[kFileId].deleted());
457
458   // Apply.
459   EXPECT_EQ(FILE_ERROR_OK,
460             ApplyChangeList(ParseChangeList(kTestJsonDelete), &changed_dirs));
461   EXPECT_EQ(16770, metadata_->GetLargestChangestamp());
462   EXPECT_FALSE(GetResourceEntry("drive/root/Directory 1/Added file.gdoc"));
463
464   EXPECT_EQ(1U, changed_dirs.size());
465   EXPECT_TRUE(changed_dirs.count(
466       base::FilePath::FromUTF8Unsafe("drive/root/Directory 1")));
467 }
468
469 TEST_F(ChangeListProcessorTest, DeltaAddFileToNewButDeletedDirectory) {
470   // This file contains the following updates:
471   // 1) A new PDF file is added to a new directory
472   // 2) but the new directory is marked "deleted" (i.e. moved to Trash)
473   // Hence, the PDF file should be just ignored.
474   const char kTestJson[] =
475       "gdata/delta_file_added_in_new_but_deleted_directory.json";
476
477   ResourceEntryMap entry_map;
478   ParentResourceIdMap parent_resource_id_map;
479   ConvertToMap(ParseChangeList(kTestJson), &entry_map, &parent_resource_id_map);
480
481   const std::string kDirId("folder:new_folder_resource_id");
482   const std::string kFileId("pdf:file_added_in_deleted_dir_id");
483
484   // Check the content of parsed ResourceEntryMap.
485   EXPECT_EQ(2U, entry_map.size());
486   EXPECT_TRUE(entry_map.count(kDirId));
487   EXPECT_TRUE(entry_map.count(kFileId));
488   EXPECT_EQ(kDirId, parent_resource_id_map[kFileId]);
489   EXPECT_TRUE(entry_map[kDirId].deleted());
490
491   // Apply the changelist and check the effect.
492   EXPECT_EQ(FILE_ERROR_OK,
493             ApplyFullResourceList(ParseChangeList(kBaseResourceListFile)));
494   std::set<base::FilePath> changed_dirs;
495   EXPECT_EQ(FILE_ERROR_OK,
496             ApplyChangeList(ParseChangeList(kTestJson), &changed_dirs));
497
498   // The value is written in kTestJson.
499   EXPECT_EQ(16730, metadata_->GetLargestChangestamp());
500   EXPECT_FALSE(GetResourceEntry("drive/root/New Directory/new_pdf_file.pdf"));
501
502   EXPECT_TRUE(changed_dirs.empty());
503 }
504
505 TEST_F(ChangeListProcessorTest, RefreshDirectory) {
506   // Prepare metadata.
507   EXPECT_EQ(FILE_ERROR_OK,
508             ApplyFullResourceList(ParseChangeList(kBaseResourceListFile)));
509
510   // Create change lists.
511   ScopedVector<ChangeList> change_lists;
512   change_lists.push_back(new ChangeList);
513
514   // Add a new file to the change lists.
515   ResourceEntry new_file;
516   new_file.set_title("new_file");
517   new_file.set_resource_id("new_file_id");
518   change_lists[0]->mutable_entries()->push_back(new_file);
519   change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId);
520
521   // Add "Directory 1" to the map with a new name.
522   ResourceEntry dir1;
523   EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath(
524       util::GetDriveMyDriveRootPath().AppendASCII("Directory 1"), &dir1));
525   dir1.set_title(dir1.title() + " (renamed)");
526   change_lists[0]->mutable_entries()->push_back(dir1);
527   change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId);
528
529   // Update the directory with the map.
530   const int64 kNewChangestamp = 12345;
531   base::FilePath file_path;
532   EXPECT_EQ(FILE_ERROR_OK, ChangeListProcessor::RefreshDirectory(
533       metadata_.get(),
534       DirectoryFetchInfo(kRootId, kNewChangestamp),
535       change_lists.Pass(),
536       &file_path));
537   EXPECT_EQ(util::GetDriveMyDriveRootPath().value(), file_path.value());
538
539   // The new changestamp should be set.
540   ResourceEntry entry;
541   EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath(
542       util::GetDriveMyDriveRootPath(), &entry));
543   EXPECT_EQ(kNewChangestamp, entry.directory_specific_info().changestamp());
544
545   // "new_file" should be added.
546   EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath(
547       util::GetDriveMyDriveRootPath().AppendASCII(new_file.title()), &entry));
548
549   // "Directory 1" should be renamed.
550   EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath(
551       util::GetDriveMyDriveRootPath().AppendASCII(dir1.title()), &entry));
552 }
553
554 TEST_F(ChangeListProcessorTest, RefreshDirectory_WrongParentId) {
555   // Prepare metadata.
556   EXPECT_EQ(FILE_ERROR_OK,
557             ApplyFullResourceList(ParseChangeList(kBaseResourceListFile)));
558
559   // Create change lists and add a new file to it.
560   ScopedVector<ChangeList> change_lists;
561   change_lists.push_back(new ChangeList);
562   ResourceEntry new_file;
563   new_file.set_title("new_file");
564   new_file.set_resource_id("new_file_id");
565   // This entry should not be added because the parent ID does not match.
566   change_lists[0]->mutable_parent_resource_ids()->push_back(
567       "some-random-resource-id");
568   change_lists[0]->mutable_entries()->push_back(new_file);
569
570
571   // Update the directory.
572   const int64 kNewChangestamp = 12345;
573   base::FilePath file_path;
574   EXPECT_EQ(FILE_ERROR_OK, ChangeListProcessor::RefreshDirectory(
575       metadata_.get(),
576       DirectoryFetchInfo(kRootId, kNewChangestamp),
577       change_lists.Pass(),
578       &file_path));
579   EXPECT_EQ(util::GetDriveMyDriveRootPath().value(), file_path.value());
580
581   // "new_file" should not be added.
582   ResourceEntry entry;
583   EXPECT_EQ(FILE_ERROR_NOT_FOUND, metadata_->GetResourceEntryByPath(
584       util::GetDriveMyDriveRootPath().AppendASCII(new_file.title()), &entry));
585 }
586
587 }  // namespace internal
588 }  // namespace drive