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.
5 #include "chrome/browser/chromeos/drive/change_list_processor.h"
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 "content/public/test/test_browser_thread_bundle.h"
15 #include "google_apis/drive/drive_api_parser.h"
16 #include "google_apis/drive/gdata_wapi_parser.h"
17 #include "google_apis/drive/test_util.h"
18 #include "testing/gtest/include/gtest/gtest.h"
25 const int64 kBaseResourceListChangestamp
= 123;
26 const char kBaseResourceListFile
[] = "gdata/root_feed.json";
27 const char kRootId
[] = "fake_root";
29 enum FileOrDirectory
{
34 struct EntryExpectation
{
37 std::string parent_id
;
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());
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
];
60 class ChangeListProcessorTest
: public testing::Test
{
62 virtual void SetUp() OVERRIDE
{
63 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
65 metadata_storage_
.reset(new ResourceMetadataStorage(
66 temp_dir_
.path(), base::MessageLoopProxy::current().get()));
67 ASSERT_TRUE(metadata_storage_
->Initialize());
69 metadata_
.reset(new internal::ResourceMetadata(
70 metadata_storage_
.get(), base::MessageLoopProxy::current()));
71 ASSERT_EQ(FILE_ERROR_OK
, metadata_
->Initialize());
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(
82 return changes
.Pass();
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
);
93 ChangeListProcessor
processor(metadata_
.get());
94 return processor
.Apply(about_resource
.Pass(),
96 false /* is_delta_update */);
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
);
108 ChangeListProcessor
processor(metadata_
.get());
109 FileError error
= processor
.Apply(about_resource
.Pass(),
111 true /* is_delta_update */);
112 *changed_dirs
= processor
.changed_dirs();
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
)
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_
;
136 TEST_F(ChangeListProcessorTest
, ApplyFullResourceList
) {
137 EXPECT_EQ(FILE_ERROR_OK
,
138 ApplyFullResourceList(ParseChangeList(kBaseResourceListFile
)));
140 const EntryExpectation kExpected
[] = {
142 {"drive/root", kRootId
, "", DIRECTORY
},
143 {"drive/root/File 1.txt",
144 "file:2_file_resource_id", kRootId
, FILE},
145 {"drive/root/Slash _ in file 1.txt",
146 "file:slash_file_resource_id", kRootId
, FILE},
147 {"drive/root/Document 1 excludeDir-test.gdoc",
148 "document:5_document_resource_id", kRootId
, FILE},
149 // Subdirectory files
150 {"drive/root/Directory 1",
151 "folder:1_folder_resource_id", kRootId
, DIRECTORY
},
152 {"drive/root/Directory 1/SubDirectory File 1.txt",
153 "file:subdirectory_file_1_id", "folder:1_folder_resource_id", FILE},
154 {"drive/root/Directory 1/Shared To The Account Owner.txt",
155 "file:subdirectory_unowned_file_1_id",
156 "folder:1_folder_resource_id", FILE},
157 {"drive/root/Directory 2 excludeDir-test",
158 "folder:sub_dir_folder_2_self_link", kRootId
, DIRECTORY
},
159 {"drive/root/Slash _ in directory",
160 "folder:slash_dir_folder_resource_id", kRootId
, DIRECTORY
},
161 {"drive/root/Slash _ in directory/Slash SubDir File.txt",
162 "file:slash_subdir_file",
163 "folder:slash_dir_folder_resource_id", FILE},
165 {"drive/root/Directory 1/Sub Directory Folder",
166 "folder:sub_dir_folder_resource_id",
167 "folder:1_folder_resource_id", DIRECTORY
},
168 {"drive/root/Directory 1/Sub Directory Folder/Sub Sub Directory Folder",
169 "folder:sub_sub_directory_folder_id",
170 "folder:sub_dir_folder_resource_id", DIRECTORY
},
172 {"drive/other/Orphan File 1.txt", "file:1_orphanfile_resource_id",
176 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(kExpected
); ++i
) {
177 scoped_ptr
<ResourceEntry
> entry
= GetResourceEntry(kExpected
[i
].path
);
178 ASSERT_TRUE(entry
) << "for path: " << kExpected
[i
].path
;
179 EXPECT_EQ(kExpected
[i
].id
, entry
->resource_id());
181 ResourceEntry parent_entry
;
182 EXPECT_EQ(FILE_ERROR_OK
, metadata_
->GetResourceEntryById(
183 entry
->parent_local_id(), &parent_entry
));
184 EXPECT_EQ(kExpected
[i
].parent_id
, parent_entry
.resource_id());
185 EXPECT_EQ(kExpected
[i
].type
,
186 entry
->file_info().is_directory() ? DIRECTORY
: FILE);
189 EXPECT_EQ(kBaseResourceListChangestamp
, metadata_
->GetLargestChangestamp());
192 TEST_F(ChangeListProcessorTest
, DeltaFileAddedInNewDirectory
) {
193 const char kTestJson
[] =
194 "gdata/delta_file_added_in_new_directory.json";
196 ResourceEntryMap entry_map
;
197 ParentResourceIdMap parent_resource_id_map
;
198 ConvertToMap(ParseChangeList(kTestJson
), &entry_map
, &parent_resource_id_map
);
200 const std::string
kNewFolderId("folder:new_folder_resource_id");
201 const std::string
kNewFileId("document:file_added_in_new_dir_id");
203 // Check the content of parsed ResourceEntryMap.
204 EXPECT_EQ(2U, entry_map
.size());
205 EXPECT_TRUE(entry_map
.count(kNewFolderId
));
206 EXPECT_TRUE(entry_map
.count(kNewFileId
));
207 EXPECT_EQ(kRootId
, parent_resource_id_map
[kNewFolderId
]);
208 EXPECT_EQ(kNewFolderId
, parent_resource_id_map
[kNewFileId
]);
209 EXPECT_TRUE(entry_map
[kNewFolderId
].file_info().is_directory());
210 EXPECT_FALSE(entry_map
[kNewFileId
].file_info().is_directory());
211 EXPECT_EQ("New Directory", entry_map
[kNewFolderId
].title());
212 EXPECT_EQ("File in new dir", entry_map
[kNewFileId
].title());
214 // Apply the changelist and check the effect.
215 EXPECT_EQ(FILE_ERROR_OK
,
216 ApplyFullResourceList(ParseChangeList(kBaseResourceListFile
)));
217 std::set
<base::FilePath
> changed_dirs
;
218 EXPECT_EQ(FILE_ERROR_OK
,
219 ApplyChangeList(ParseChangeList(kTestJson
), &changed_dirs
));
221 // The value is written in kTestJson.
222 EXPECT_EQ(16730, metadata_
->GetLargestChangestamp());
223 EXPECT_TRUE(GetResourceEntry("drive/root/New Directory"));
224 EXPECT_TRUE(GetResourceEntry(
225 "drive/root/New Directory/File in new dir.gdoc"));
227 EXPECT_EQ(2U, changed_dirs
.size());
228 EXPECT_TRUE(changed_dirs
.count(
229 base::FilePath::FromUTF8Unsafe("drive/root")));
230 EXPECT_TRUE(changed_dirs
.count(
231 base::FilePath::FromUTF8Unsafe("drive/root/New Directory")));
234 TEST_F(ChangeListProcessorTest
, DeltaDirMovedFromRootToDirectory
) {
235 const char kTestJson
[] =
236 "gdata/delta_dir_moved_from_root_to_directory.json";
238 ResourceEntryMap entry_map
;
239 ParentResourceIdMap parent_resource_id_map
;
240 ConvertToMap(ParseChangeList(kTestJson
), &entry_map
, &parent_resource_id_map
);
242 const std::string
kMovedId("folder:1_folder_resource_id");
243 const std::string
kDestId("folder:sub_dir_folder_2_self_link");
245 // Check the content of parsed ResourceEntryMap.
246 EXPECT_EQ(2U, entry_map
.size());
247 EXPECT_TRUE(entry_map
.count(kMovedId
));
248 EXPECT_TRUE(entry_map
.count(kDestId
));
249 EXPECT_EQ(kDestId
, parent_resource_id_map
[kMovedId
]);
251 // Apply the changelist and check the effect.
252 EXPECT_EQ(FILE_ERROR_OK
,
253 ApplyFullResourceList(ParseChangeList(kBaseResourceListFile
)));
254 std::set
<base::FilePath
> changed_dirs
;
255 EXPECT_EQ(FILE_ERROR_OK
,
256 ApplyChangeList(ParseChangeList(kTestJson
), &changed_dirs
));
258 // The value is written in kTestJson.
259 EXPECT_EQ(16809, metadata_
->GetLargestChangestamp());
260 EXPECT_FALSE(GetResourceEntry("drive/root/Directory 1"));
261 EXPECT_TRUE(GetResourceEntry(
262 "drive/root/Directory 2 excludeDir-test/Directory 1"));
264 EXPECT_EQ(4U, changed_dirs
.size());
265 EXPECT_TRUE(changed_dirs
.count(
266 base::FilePath::FromUTF8Unsafe("drive/root")));
267 EXPECT_TRUE(changed_dirs
.count(
268 base::FilePath::FromUTF8Unsafe("drive/root/Directory 1")));
269 EXPECT_TRUE(changed_dirs
.count(
270 base::FilePath::FromUTF8Unsafe(
271 "drive/root/Directory 2 excludeDir-test")));
272 EXPECT_TRUE(changed_dirs
.count(
273 base::FilePath::FromUTF8Unsafe(
274 "drive/root/Directory 2 excludeDir-test/Directory 1")));
277 TEST_F(ChangeListProcessorTest
, DeltaFileMovedFromDirectoryToRoot
) {
278 const char kTestJson
[] =
279 "gdata/delta_file_moved_from_directory_to_root.json";
281 ResourceEntryMap entry_map
;
282 ParentResourceIdMap parent_resource_id_map
;
283 ConvertToMap(ParseChangeList(kTestJson
), &entry_map
, &parent_resource_id_map
);
285 const std::string
kMovedId("file:subdirectory_file_1_id");
286 const std::string
kSrcId("folder:1_folder_resource_id");
288 // Check the content of parsed ResourceEntryMap.
289 EXPECT_EQ(2U, entry_map
.size());
290 EXPECT_TRUE(entry_map
.count(kMovedId
));
291 EXPECT_TRUE(entry_map
.count(kSrcId
));
292 EXPECT_EQ(kRootId
, parent_resource_id_map
[kMovedId
]);
294 // Apply the changelist and check the effect.
295 EXPECT_EQ(FILE_ERROR_OK
,
296 ApplyFullResourceList(ParseChangeList(kBaseResourceListFile
)));
297 std::set
<base::FilePath
> changed_dirs
;
298 EXPECT_EQ(FILE_ERROR_OK
,
299 ApplyChangeList(ParseChangeList(kTestJson
), &changed_dirs
));
301 // The value is written in kTestJson.
302 EXPECT_EQ(16815, metadata_
->GetLargestChangestamp());
303 EXPECT_FALSE(GetResourceEntry(
304 "drive/root/Directory 1/SubDirectory File 1.txt"));
305 EXPECT_TRUE(GetResourceEntry("drive/root/SubDirectory File 1.txt"));
307 EXPECT_EQ(2U, changed_dirs
.size());
308 EXPECT_TRUE(changed_dirs
.count(
309 base::FilePath::FromUTF8Unsafe("drive/root")));
310 EXPECT_TRUE(changed_dirs
.count(
311 base::FilePath::FromUTF8Unsafe("drive/root/Directory 1")));
314 TEST_F(ChangeListProcessorTest
, DeltaFileRenamedInDirectory
) {
315 const char kTestJson
[] =
316 "gdata/delta_file_renamed_in_directory.json";
318 ResourceEntryMap entry_map
;
319 ParentResourceIdMap parent_resource_id_map
;
320 ConvertToMap(ParseChangeList(kTestJson
), &entry_map
, &parent_resource_id_map
);
322 const std::string
kRenamedId("file:subdirectory_file_1_id");
323 const std::string
kParentId("folder:1_folder_resource_id");
325 // Check the content of parsed ResourceEntryMap.
326 EXPECT_EQ(2U, entry_map
.size());
327 EXPECT_TRUE(entry_map
.count(kRenamedId
));
328 EXPECT_TRUE(entry_map
.count(kParentId
));
329 EXPECT_EQ(kParentId
, parent_resource_id_map
[kRenamedId
]);
330 EXPECT_EQ("New SubDirectory File 1.txt", entry_map
[kRenamedId
].title());
332 // Apply the changelist and check the effect.
333 EXPECT_EQ(FILE_ERROR_OK
,
334 ApplyFullResourceList(ParseChangeList(kBaseResourceListFile
)));
335 std::set
<base::FilePath
> changed_dirs
;
336 EXPECT_EQ(FILE_ERROR_OK
,
337 ApplyChangeList(ParseChangeList(kTestJson
), &changed_dirs
));
339 // The value is written in kTestJson.
340 EXPECT_EQ(16767, metadata_
->GetLargestChangestamp());
341 EXPECT_FALSE(GetResourceEntry(
342 "drive/root/Directory 1/SubDirectory File 1.txt"));
343 EXPECT_TRUE(GetResourceEntry(
344 "drive/root/Directory 1/New SubDirectory File 1.txt"));
346 EXPECT_EQ(2U, changed_dirs
.size());
347 EXPECT_TRUE(changed_dirs
.count(
348 base::FilePath::FromUTF8Unsafe("drive/root")));
349 EXPECT_TRUE(changed_dirs
.count(
350 base::FilePath::FromUTF8Unsafe("drive/root/Directory 1")));
353 TEST_F(ChangeListProcessorTest
, DeltaAddAndDeleteFileInRoot
) {
354 const char kTestJsonAdd
[] =
355 "gdata/delta_file_added_in_root.json";
356 const char kTestJsonDelete
[] =
357 "gdata/delta_file_deleted_in_root.json";
359 const std::string
kParentId(kRootId
);
360 const std::string
kFileId("document:added_in_root_id");
362 ResourceEntryMap entry_map
;
363 ParentResourceIdMap parent_resource_id_map
;
365 // Check the content of kTestJsonAdd.
366 ConvertToMap(ParseChangeList(kTestJsonAdd
),
367 &entry_map
, &parent_resource_id_map
);
368 EXPECT_EQ(1U, entry_map
.size());
369 EXPECT_TRUE(entry_map
.count(kFileId
));
370 EXPECT_EQ(kParentId
, parent_resource_id_map
[kFileId
]);
371 EXPECT_EQ("Added file", entry_map
[kFileId
].title());
372 EXPECT_FALSE(entry_map
[kFileId
].deleted());
375 EXPECT_EQ(FILE_ERROR_OK
,
376 ApplyFullResourceList(ParseChangeList(kBaseResourceListFile
)));
377 std::set
<base::FilePath
> changed_dirs
;
378 EXPECT_EQ(FILE_ERROR_OK
,
379 ApplyChangeList(ParseChangeList(kTestJsonAdd
), &changed_dirs
));
380 EXPECT_EQ(16683, metadata_
->GetLargestChangestamp());
381 EXPECT_TRUE(GetResourceEntry("drive/root/Added file.gdoc"));
382 EXPECT_EQ(1U, changed_dirs
.size());
383 EXPECT_TRUE(changed_dirs
.count(
384 base::FilePath::FromUTF8Unsafe("drive/root")));
386 // Check the content of kTestJsonDelete.
388 parent_resource_id_map
.clear();
389 ConvertToMap(ParseChangeList(kTestJsonDelete
),
390 &entry_map
, &parent_resource_id_map
);
391 EXPECT_EQ(1U, entry_map
.size());
392 EXPECT_TRUE(entry_map
.count(kFileId
));
393 EXPECT_EQ(kParentId
, parent_resource_id_map
[kFileId
]);
394 EXPECT_EQ("Added file", entry_map
[kFileId
].title());
395 EXPECT_TRUE(entry_map
[kFileId
].deleted());
398 EXPECT_EQ(FILE_ERROR_OK
,
399 ApplyChangeList(ParseChangeList(kTestJsonDelete
), &changed_dirs
));
400 EXPECT_EQ(16687, metadata_
->GetLargestChangestamp());
401 EXPECT_FALSE(GetResourceEntry("drive/root/Added file.gdoc"));
402 EXPECT_EQ(1U, changed_dirs
.size());
403 EXPECT_TRUE(changed_dirs
.count(
404 base::FilePath::FromUTF8Unsafe("drive/root")));
408 TEST_F(ChangeListProcessorTest
, DeltaAddAndDeleteFileFromExistingDirectory
) {
409 const char kTestJsonAdd
[] =
410 "gdata/delta_file_added_in_directory.json";
411 const char kTestJsonDelete
[] =
412 "gdata/delta_file_deleted_in_directory.json";
414 const std::string
kParentId("folder:1_folder_resource_id");
415 const std::string
kFileId("document:added_in_root_id");
417 ResourceEntryMap entry_map
;
418 ParentResourceIdMap parent_resource_id_map
;
420 // Check the content of kTestJsonAdd.
421 ConvertToMap(ParseChangeList(kTestJsonAdd
),
422 &entry_map
, &parent_resource_id_map
);
423 EXPECT_EQ(2U, entry_map
.size());
424 EXPECT_TRUE(entry_map
.count(kFileId
));
425 EXPECT_TRUE(entry_map
.count(kParentId
));
426 EXPECT_EQ(kParentId
, parent_resource_id_map
[kFileId
]);
427 EXPECT_EQ("Added file", entry_map
[kFileId
].title());
428 EXPECT_FALSE(entry_map
[kFileId
].deleted());
431 EXPECT_EQ(FILE_ERROR_OK
,
432 ApplyFullResourceList(ParseChangeList(kBaseResourceListFile
)));
433 std::set
<base::FilePath
> changed_dirs
;
434 EXPECT_EQ(FILE_ERROR_OK
,
435 ApplyChangeList(ParseChangeList(kTestJsonAdd
), &changed_dirs
));
436 EXPECT_EQ(16730, metadata_
->GetLargestChangestamp());
437 EXPECT_TRUE(GetResourceEntry("drive/root/Directory 1/Added file.gdoc"));
439 EXPECT_EQ(2U, changed_dirs
.size());
440 EXPECT_TRUE(changed_dirs
.count(
441 base::FilePath::FromUTF8Unsafe("drive/root")));
442 EXPECT_TRUE(changed_dirs
.count(
443 base::FilePath::FromUTF8Unsafe("drive/root/Directory 1")));
445 // Check the content of kTestJsonDelete.
447 parent_resource_id_map
.clear();
448 ConvertToMap(ParseChangeList(kTestJsonDelete
),
449 &entry_map
, &parent_resource_id_map
);
450 EXPECT_EQ(1U, entry_map
.size());
451 EXPECT_TRUE(entry_map
.count(kFileId
));
452 EXPECT_EQ(kParentId
, parent_resource_id_map
[kFileId
]);
453 EXPECT_EQ("Added file", entry_map
[kFileId
].title());
454 EXPECT_TRUE(entry_map
[kFileId
].deleted());
457 EXPECT_EQ(FILE_ERROR_OK
,
458 ApplyChangeList(ParseChangeList(kTestJsonDelete
), &changed_dirs
));
459 EXPECT_EQ(16770, metadata_
->GetLargestChangestamp());
460 EXPECT_FALSE(GetResourceEntry("drive/root/Directory 1/Added file.gdoc"));
462 EXPECT_EQ(1U, changed_dirs
.size());
463 EXPECT_TRUE(changed_dirs
.count(
464 base::FilePath::FromUTF8Unsafe("drive/root/Directory 1")));
467 TEST_F(ChangeListProcessorTest
, DeltaAddFileToNewButDeletedDirectory
) {
468 // This file contains the following updates:
469 // 1) A new PDF file is added to a new directory
470 // 2) but the new directory is marked "deleted" (i.e. moved to Trash)
471 // Hence, the PDF file should be just ignored.
472 const char kTestJson
[] =
473 "gdata/delta_file_added_in_new_but_deleted_directory.json";
475 ResourceEntryMap entry_map
;
476 ParentResourceIdMap parent_resource_id_map
;
477 ConvertToMap(ParseChangeList(kTestJson
), &entry_map
, &parent_resource_id_map
);
479 const std::string
kDirId("folder:new_folder_resource_id");
480 const std::string
kFileId("pdf:file_added_in_deleted_dir_id");
482 // Check the content of parsed ResourceEntryMap.
483 EXPECT_EQ(2U, entry_map
.size());
484 EXPECT_TRUE(entry_map
.count(kDirId
));
485 EXPECT_TRUE(entry_map
.count(kFileId
));
486 EXPECT_EQ(kDirId
, parent_resource_id_map
[kFileId
]);
487 EXPECT_TRUE(entry_map
[kDirId
].deleted());
489 // Apply the changelist and check the effect.
490 EXPECT_EQ(FILE_ERROR_OK
,
491 ApplyFullResourceList(ParseChangeList(kBaseResourceListFile
)));
492 std::set
<base::FilePath
> changed_dirs
;
493 EXPECT_EQ(FILE_ERROR_OK
,
494 ApplyChangeList(ParseChangeList(kTestJson
), &changed_dirs
));
496 // The value is written in kTestJson.
497 EXPECT_EQ(16730, metadata_
->GetLargestChangestamp());
498 EXPECT_FALSE(GetResourceEntry("drive/root/New Directory/new_pdf_file.pdf"));
500 EXPECT_TRUE(changed_dirs
.empty());
503 TEST_F(ChangeListProcessorTest
, RefreshDirectory
) {
505 EXPECT_EQ(FILE_ERROR_OK
,
506 ApplyFullResourceList(ParseChangeList(kBaseResourceListFile
)));
508 // Create change lists.
509 ScopedVector
<ChangeList
> change_lists
;
510 change_lists
.push_back(new ChangeList
);
512 // Add a new file to the change lists.
513 ResourceEntry new_file
;
514 new_file
.set_title("new_file");
515 new_file
.set_resource_id("new_file_id");
516 change_lists
[0]->mutable_entries()->push_back(new_file
);
517 change_lists
[0]->mutable_parent_resource_ids()->push_back(kRootId
);
519 // Add "Directory 1" to the map with a new name.
521 EXPECT_EQ(FILE_ERROR_OK
, metadata_
->GetResourceEntryByPath(
522 util::GetDriveMyDriveRootPath().AppendASCII("Directory 1"), &dir1
));
523 dir1
.set_title(dir1
.title() + " (renamed)");
524 change_lists
[0]->mutable_entries()->push_back(dir1
);
525 change_lists
[0]->mutable_parent_resource_ids()->push_back(kRootId
);
527 // Update the directory with the map.
529 EXPECT_EQ(FILE_ERROR_OK
, metadata_
->GetResourceEntryByPath(
530 util::GetDriveMyDriveRootPath(), &root
));
531 const int64 kNewChangestamp
= 12345;
532 base::FilePath file_path
;
533 EXPECT_EQ(FILE_ERROR_OK
, ChangeListProcessor::RefreshDirectory(
535 DirectoryFetchInfo(root
.local_id(), kRootId
, kNewChangestamp
),
538 EXPECT_EQ(util::GetDriveMyDriveRootPath().value(), file_path
.value());
540 // The new changestamp should be set.
542 EXPECT_EQ(FILE_ERROR_OK
, metadata_
->GetResourceEntryByPath(
543 util::GetDriveMyDriveRootPath(), &entry
));
544 EXPECT_EQ(kNewChangestamp
, entry
.directory_specific_info().changestamp());
546 // "new_file" should be added.
547 EXPECT_EQ(FILE_ERROR_OK
, metadata_
->GetResourceEntryByPath(
548 util::GetDriveMyDriveRootPath().AppendASCII(new_file
.title()), &entry
));
550 // "Directory 1" should be renamed.
551 EXPECT_EQ(FILE_ERROR_OK
, metadata_
->GetResourceEntryByPath(
552 util::GetDriveMyDriveRootPath().AppendASCII(dir1
.title()), &entry
));
555 TEST_F(ChangeListProcessorTest
, RefreshDirectory_WrongParentId
) {
557 EXPECT_EQ(FILE_ERROR_OK
,
558 ApplyFullResourceList(ParseChangeList(kBaseResourceListFile
)));
560 // Create change lists and add a new file to it.
561 ScopedVector
<ChangeList
> change_lists
;
562 change_lists
.push_back(new ChangeList
);
563 ResourceEntry new_file
;
564 new_file
.set_title("new_file");
565 new_file
.set_resource_id("new_file_id");
566 // This entry should not be added because the parent ID does not match.
567 change_lists
[0]->mutable_parent_resource_ids()->push_back(
568 "some-random-resource-id");
569 change_lists
[0]->mutable_entries()->push_back(new_file
);
572 // Update the directory.
574 EXPECT_EQ(FILE_ERROR_OK
, metadata_
->GetResourceEntryByPath(
575 util::GetDriveMyDriveRootPath(), &root
));
576 const int64 kNewChangestamp
= 12345;
577 base::FilePath file_path
;
578 EXPECT_EQ(FILE_ERROR_OK
, ChangeListProcessor::RefreshDirectory(
580 DirectoryFetchInfo(root
.local_id(), kRootId
, kNewChangestamp
),
583 EXPECT_EQ(util::GetDriveMyDriveRootPath().value(), file_path
.value());
585 // "new_file" should not be added.
587 EXPECT_EQ(FILE_ERROR_NOT_FOUND
, metadata_
->GetResourceEntryByPath(
588 util::GetDriveMyDriveRootPath().AppendASCII(new_file
.title()), &entry
));
591 TEST_F(ChangeListProcessorTest
, SharedFilesWithNoParentInFeed
) {
593 EXPECT_EQ(FILE_ERROR_OK
,
594 ApplyFullResourceList(ParseChangeList(kBaseResourceListFile
)));
596 // Create change lists.
597 ScopedVector
<ChangeList
> change_lists
;
598 change_lists
.push_back(new ChangeList
);
600 // Add a new file with non-existing parent resource id to the change lists.
601 ResourceEntry new_file
;
602 new_file
.set_title("new_file");
603 new_file
.set_resource_id("new_file_id");
604 change_lists
[0]->mutable_entries()->push_back(new_file
);
605 change_lists
[0]->mutable_parent_resource_ids()->push_back("nonexisting");
606 change_lists
[0]->set_largest_changestamp(kBaseResourceListChangestamp
+ 1);
608 std::set
<base::FilePath
> changed_dirs
;
609 EXPECT_EQ(FILE_ERROR_OK
, ApplyChangeList(change_lists
.Pass(), &changed_dirs
));
611 // "new_file" should be added under drive/other.
613 EXPECT_EQ(FILE_ERROR_OK
, metadata_
->GetResourceEntryByPath(
614 util::GetDriveGrandRootPath().AppendASCII("other/new_file"), &entry
));
617 } // namespace internal