| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/chromeos/drive/change_list_processor.h" |
| |
| #include "base/files/scoped_temp_dir.h" |
| #include "base/message_loop/message_loop_proxy.h" |
| #include "base/values.h" |
| #include "chrome/browser/chromeos/drive/drive.pb.h" |
| #include "chrome/browser/chromeos/drive/file_system_util.h" |
| #include "chrome/browser/chromeos/drive/resource_metadata.h" |
| #include "chrome/browser/chromeos/drive/test_util.h" |
| #include "chrome/browser/google_apis/drive_api_parser.h" |
| #include "chrome/browser/google_apis/gdata_wapi_parser.h" |
| #include "chrome/browser/google_apis/test_util.h" |
| #include "content/public/test/test_browser_thread_bundle.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace drive { |
| namespace internal { |
| |
| namespace { |
| |
| const int64 kBaseResourceListChangestamp = 123; |
| const char kBaseResourceListFile[] = "gdata/root_feed.json"; |
| const char kRootId[] = "fake_root"; |
| |
| enum FileOrDirectory { |
| FILE, |
| DIRECTORY, |
| }; |
| |
| struct EntryExpectation { |
| std::string path; |
| std::string id; |
| std::string parent_id; |
| FileOrDirectory type; |
| }; |
| |
| typedef std::map<std::string, ResourceEntry> ResourceEntryMap; |
| typedef std::map<std::string, std::string> ParentResourceIdMap; |
| void ConvertToMap(ScopedVector<ChangeList> change_lists, |
| ResourceEntryMap* entry_map, |
| ParentResourceIdMap* parent_resource_id_map) { |
| for (size_t i = 0; i < change_lists.size(); ++i) { |
| const std::vector<ResourceEntry>& entries = change_lists[i]->entries(); |
| const std::vector<std::string>& parent_resource_ids = |
| change_lists[i]->parent_resource_ids(); |
| EXPECT_EQ(entries.size(), parent_resource_ids.size()); |
| |
| for (size_t i = 0; i < entries.size(); ++i) { |
| const std::string& resource_id = entries[i].resource_id(); |
| (*parent_resource_id_map)[resource_id] = parent_resource_ids[i]; |
| (*entry_map)[resource_id] = entries[i]; |
| } |
| } |
| } |
| |
| class ChangeListProcessorTest : public testing::Test { |
| protected: |
| virtual void SetUp() OVERRIDE { |
| ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| |
| metadata_storage_.reset(new ResourceMetadataStorage( |
| temp_dir_.path(), base::MessageLoopProxy::current().get())); |
| ASSERT_TRUE(metadata_storage_->Initialize()); |
| |
| metadata_.reset(new internal::ResourceMetadata( |
| metadata_storage_.get(), base::MessageLoopProxy::current())); |
| ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize()); |
| } |
| |
| // Parses a json file at |test_data_path| relative to Chrome test directory |
| // into a ScopedVector<drive::internal::ChangeList>. |
| ScopedVector<ChangeList> ParseChangeList(const std::string& test_data_path) { |
| ScopedVector<ChangeList> changes; |
| changes.push_back(new ChangeList( |
| *google_apis::ResourceList::ExtractAndParse( |
| *google_apis::test_util::LoadJSONFile( |
| test_data_path)))); |
| return changes.Pass(); |
| } |
| |
| // Applies the |changes| to |metadata_| as a full resource list of changestamp |
| // |kBaseResourceListChangestamp|. |
| FileError ApplyFullResourceList(ScopedVector<ChangeList> changes) { |
| scoped_ptr<google_apis::AboutResource> about_resource( |
| new google_apis::AboutResource); |
| about_resource->set_largest_change_id(kBaseResourceListChangestamp); |
| about_resource->set_root_folder_id(kRootId); |
| |
| ChangeListProcessor processor(metadata_.get()); |
| return processor.Apply(about_resource.Pass(), |
| changes.Pass(), |
| false /* is_delta_update */); |
| } |
| |
| // Applies the |changes| to |metadata_| as a delta update. Delta changelists |
| // should contain their changestamp in themselves. |
| FileError ApplyChangeList(ScopedVector<ChangeList> changes, |
| std::set<base::FilePath>* changed_dirs) { |
| scoped_ptr<google_apis::AboutResource> about_resource( |
| new google_apis::AboutResource); |
| about_resource->set_largest_change_id(kBaseResourceListChangestamp); |
| about_resource->set_root_folder_id(kRootId); |
| |
| ChangeListProcessor processor(metadata_.get()); |
| FileError error = processor.Apply(about_resource.Pass(), |
| changes.Pass(), |
| true /* is_delta_update */); |
| *changed_dirs = processor.changed_dirs(); |
| return error; |
| } |
| |
| // Gets the resource entry for the path from |metadata_| synchronously. |
| // Returns null if the entry does not exist. |
| scoped_ptr<ResourceEntry> GetResourceEntry(const std::string& path) { |
| scoped_ptr<ResourceEntry> entry(new ResourceEntry); |
| FileError error = metadata_->GetResourceEntryByPath( |
| base::FilePath::FromUTF8Unsafe(path), entry.get()); |
| if (error != FILE_ERROR_OK) |
| entry.reset(); |
| return entry.Pass(); |
| } |
| |
| content::TestBrowserThreadBundle thread_bundle_; |
| base::ScopedTempDir temp_dir_; |
| scoped_ptr<ResourceMetadataStorage, |
| test_util::DestroyHelperForTests> metadata_storage_; |
| scoped_ptr<ResourceMetadata, test_util::DestroyHelperForTests> metadata_; |
| }; |
| |
| } // namespace |
| |
| TEST_F(ChangeListProcessorTest, ApplyFullResourceList) { |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyFullResourceList(ParseChangeList(kBaseResourceListFile))); |
| |
| const EntryExpectation kExpected[] = { |
| // Root files |
| {"drive/root", |
| kRootId, util::kDriveGrandRootSpecialResourceId, DIRECTORY}, |
| {"drive/root/File 1.txt", |
| "file:2_file_resource_id", kRootId, FILE}, |
| {"drive/root/Slash \xE2\x88\x95 in file 1.txt", |
| "file:slash_file_resource_id", kRootId, FILE}, |
| {"drive/root/Document 1 excludeDir-test.gdoc", |
| "document:5_document_resource_id", kRootId, FILE}, |
| // Subdirectory files |
| {"drive/root/Directory 1", |
| "folder:1_folder_resource_id", kRootId, DIRECTORY}, |
| {"drive/root/Directory 1/SubDirectory File 1.txt", |
| "file:subdirectory_file_1_id", "folder:1_folder_resource_id", FILE}, |
| {"drive/root/Directory 1/Shared To The Account Owner.txt", |
| "file:subdirectory_unowned_file_1_id", |
| "folder:1_folder_resource_id", FILE}, |
| {"drive/root/Directory 2 excludeDir-test", |
| "folder:sub_dir_folder_2_self_link", kRootId, DIRECTORY}, |
| {"drive/root/Slash \xE2\x88\x95 in directory", |
| "folder:slash_dir_folder_resource_id", kRootId, DIRECTORY}, |
| {"drive/root/Slash \xE2\x88\x95 in directory/Slash SubDir File.txt", |
| "file:slash_subdir_file", |
| "folder:slash_dir_folder_resource_id", FILE}, |
| // Deeper |
| {"drive/root/Directory 1/Sub Directory Folder", |
| "folder:sub_dir_folder_resource_id", |
| "folder:1_folder_resource_id", DIRECTORY}, |
| {"drive/root/Directory 1/Sub Directory Folder/Sub Sub Directory Folder", |
| "folder:sub_sub_directory_folder_id", |
| "folder:sub_dir_folder_resource_id", DIRECTORY}, |
| // Orphan |
| {"drive/other/Orphan File 1.txt", |
| "file:1_orphanfile_resource_id", |
| util::kDriveOtherDirSpecialResourceId, FILE}, |
| }; |
| |
| for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kExpected); ++i) { |
| scoped_ptr<ResourceEntry> entry = GetResourceEntry(kExpected[i].path); |
| ASSERT_TRUE(entry) << "for path: " << kExpected[i].path; |
| EXPECT_EQ(kExpected[i].id, entry->resource_id()); |
| |
| ResourceEntry parent_entry; |
| EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryById( |
| entry->parent_local_id(), &parent_entry)); |
| EXPECT_EQ(kExpected[i].parent_id, parent_entry.resource_id()); |
| EXPECT_EQ(kExpected[i].type, |
| entry->file_info().is_directory() ? DIRECTORY : FILE); |
| } |
| |
| EXPECT_EQ(kBaseResourceListChangestamp, metadata_->GetLargestChangestamp()); |
| } |
| |
| TEST_F(ChangeListProcessorTest, DeltaFileAddedInNewDirectory) { |
| const char kTestJson[] = |
| "gdata/delta_file_added_in_new_directory.json"; |
| |
| ResourceEntryMap entry_map; |
| ParentResourceIdMap parent_resource_id_map; |
| ConvertToMap(ParseChangeList(kTestJson), &entry_map, &parent_resource_id_map); |
| |
| const std::string kNewFolderId("folder:new_folder_resource_id"); |
| const std::string kNewFileId("document:file_added_in_new_dir_id"); |
| |
| // Check the content of parsed ResourceEntryMap. |
| EXPECT_EQ(2U, entry_map.size()); |
| EXPECT_TRUE(entry_map.count(kNewFolderId)); |
| EXPECT_TRUE(entry_map.count(kNewFileId)); |
| EXPECT_EQ(kRootId, parent_resource_id_map[kNewFolderId]); |
| EXPECT_EQ(kNewFolderId, parent_resource_id_map[kNewFileId]); |
| EXPECT_TRUE(entry_map[kNewFolderId].file_info().is_directory()); |
| EXPECT_FALSE(entry_map[kNewFileId].file_info().is_directory()); |
| EXPECT_EQ("New Directory", entry_map[kNewFolderId].title()); |
| EXPECT_EQ("File in new dir", entry_map[kNewFileId].title()); |
| |
| // Apply the changelist and check the effect. |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyFullResourceList(ParseChangeList(kBaseResourceListFile))); |
| std::set<base::FilePath> changed_dirs; |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyChangeList(ParseChangeList(kTestJson), &changed_dirs)); |
| |
| // The value is written in kTestJson. |
| EXPECT_EQ(16730, metadata_->GetLargestChangestamp()); |
| EXPECT_TRUE(GetResourceEntry("drive/root/New Directory")); |
| EXPECT_TRUE(GetResourceEntry( |
| "drive/root/New Directory/File in new dir.gdoc")); |
| |
| EXPECT_EQ(2U, changed_dirs.size()); |
| EXPECT_TRUE(changed_dirs.count( |
| base::FilePath::FromUTF8Unsafe("drive/root"))); |
| EXPECT_TRUE(changed_dirs.count( |
| base::FilePath::FromUTF8Unsafe("drive/root/New Directory"))); |
| } |
| |
| TEST_F(ChangeListProcessorTest, DeltaDirMovedFromRootToDirectory) { |
| const char kTestJson[] = |
| "gdata/delta_dir_moved_from_root_to_directory.json"; |
| |
| ResourceEntryMap entry_map; |
| ParentResourceIdMap parent_resource_id_map; |
| ConvertToMap(ParseChangeList(kTestJson), &entry_map, &parent_resource_id_map); |
| |
| const std::string kMovedId("folder:1_folder_resource_id"); |
| const std::string kDestId("folder:sub_dir_folder_2_self_link"); |
| |
| // Check the content of parsed ResourceEntryMap. |
| EXPECT_EQ(2U, entry_map.size()); |
| EXPECT_TRUE(entry_map.count(kMovedId)); |
| EXPECT_TRUE(entry_map.count(kDestId)); |
| EXPECT_EQ(kDestId, parent_resource_id_map[kMovedId]); |
| |
| // Apply the changelist and check the effect. |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyFullResourceList(ParseChangeList(kBaseResourceListFile))); |
| std::set<base::FilePath> changed_dirs; |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyChangeList(ParseChangeList(kTestJson), &changed_dirs)); |
| |
| // The value is written in kTestJson. |
| EXPECT_EQ(16809, metadata_->GetLargestChangestamp()); |
| EXPECT_FALSE(GetResourceEntry("drive/root/Directory 1")); |
| EXPECT_TRUE(GetResourceEntry( |
| "drive/root/Directory 2 excludeDir-test/Directory 1")); |
| |
| EXPECT_EQ(4U, changed_dirs.size()); |
| EXPECT_TRUE(changed_dirs.count( |
| base::FilePath::FromUTF8Unsafe("drive/root"))); |
| EXPECT_TRUE(changed_dirs.count( |
| base::FilePath::FromUTF8Unsafe("drive/root/Directory 1"))); |
| EXPECT_TRUE(changed_dirs.count( |
| base::FilePath::FromUTF8Unsafe( |
| "drive/root/Directory 2 excludeDir-test"))); |
| EXPECT_TRUE(changed_dirs.count( |
| base::FilePath::FromUTF8Unsafe( |
| "drive/root/Directory 2 excludeDir-test/Directory 1"))); |
| } |
| |
| TEST_F(ChangeListProcessorTest, DeltaFileMovedFromDirectoryToRoot) { |
| const char kTestJson[] = |
| "gdata/delta_file_moved_from_directory_to_root.json"; |
| |
| ResourceEntryMap entry_map; |
| ParentResourceIdMap parent_resource_id_map; |
| ConvertToMap(ParseChangeList(kTestJson), &entry_map, &parent_resource_id_map); |
| |
| const std::string kMovedId("file:subdirectory_file_1_id"); |
| const std::string kSrcId("folder:1_folder_resource_id"); |
| |
| // Check the content of parsed ResourceEntryMap. |
| EXPECT_EQ(2U, entry_map.size()); |
| EXPECT_TRUE(entry_map.count(kMovedId)); |
| EXPECT_TRUE(entry_map.count(kSrcId)); |
| EXPECT_EQ(kRootId, parent_resource_id_map[kMovedId]); |
| |
| // Apply the changelist and check the effect. |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyFullResourceList(ParseChangeList(kBaseResourceListFile))); |
| std::set<base::FilePath> changed_dirs; |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyChangeList(ParseChangeList(kTestJson), &changed_dirs)); |
| |
| // The value is written in kTestJson. |
| EXPECT_EQ(16815, metadata_->GetLargestChangestamp()); |
| EXPECT_FALSE(GetResourceEntry( |
| "drive/root/Directory 1/SubDirectory File 1.txt")); |
| EXPECT_TRUE(GetResourceEntry("drive/root/SubDirectory File 1.txt")); |
| |
| EXPECT_EQ(2U, changed_dirs.size()); |
| EXPECT_TRUE(changed_dirs.count( |
| base::FilePath::FromUTF8Unsafe("drive/root"))); |
| EXPECT_TRUE(changed_dirs.count( |
| base::FilePath::FromUTF8Unsafe("drive/root/Directory 1"))); |
| } |
| |
| TEST_F(ChangeListProcessorTest, DeltaFileRenamedInDirectory) { |
| const char kTestJson[] = |
| "gdata/delta_file_renamed_in_directory.json"; |
| |
| ResourceEntryMap entry_map; |
| ParentResourceIdMap parent_resource_id_map; |
| ConvertToMap(ParseChangeList(kTestJson), &entry_map, &parent_resource_id_map); |
| |
| const std::string kRenamedId("file:subdirectory_file_1_id"); |
| const std::string kParentId("folder:1_folder_resource_id"); |
| |
| // Check the content of parsed ResourceEntryMap. |
| EXPECT_EQ(2U, entry_map.size()); |
| EXPECT_TRUE(entry_map.count(kRenamedId)); |
| EXPECT_TRUE(entry_map.count(kParentId)); |
| EXPECT_EQ(kParentId, parent_resource_id_map[kRenamedId]); |
| EXPECT_EQ("New SubDirectory File 1.txt", entry_map[kRenamedId].title()); |
| |
| // Apply the changelist and check the effect. |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyFullResourceList(ParseChangeList(kBaseResourceListFile))); |
| std::set<base::FilePath> changed_dirs; |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyChangeList(ParseChangeList(kTestJson), &changed_dirs)); |
| |
| // The value is written in kTestJson. |
| EXPECT_EQ(16767, metadata_->GetLargestChangestamp()); |
| EXPECT_FALSE(GetResourceEntry( |
| "drive/root/Directory 1/SubDirectory File 1.txt")); |
| EXPECT_TRUE(GetResourceEntry( |
| "drive/root/Directory 1/New SubDirectory File 1.txt")); |
| |
| EXPECT_EQ(2U, changed_dirs.size()); |
| EXPECT_TRUE(changed_dirs.count( |
| base::FilePath::FromUTF8Unsafe("drive/root"))); |
| EXPECT_TRUE(changed_dirs.count( |
| base::FilePath::FromUTF8Unsafe("drive/root/Directory 1"))); |
| } |
| |
| TEST_F(ChangeListProcessorTest, DeltaAddAndDeleteFileInRoot) { |
| const char kTestJsonAdd[] = |
| "gdata/delta_file_added_in_root.json"; |
| const char kTestJsonDelete[] = |
| "gdata/delta_file_deleted_in_root.json"; |
| |
| const std::string kParentId(kRootId); |
| const std::string kFileId("document:added_in_root_id"); |
| |
| ResourceEntryMap entry_map; |
| ParentResourceIdMap parent_resource_id_map; |
| |
| // Check the content of kTestJsonAdd. |
| ConvertToMap(ParseChangeList(kTestJsonAdd), |
| &entry_map, &parent_resource_id_map); |
| EXPECT_EQ(1U, entry_map.size()); |
| EXPECT_TRUE(entry_map.count(kFileId)); |
| EXPECT_EQ(kParentId, parent_resource_id_map[kFileId]); |
| EXPECT_EQ("Added file", entry_map[kFileId].title()); |
| EXPECT_FALSE(entry_map[kFileId].deleted()); |
| |
| // Apply. |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyFullResourceList(ParseChangeList(kBaseResourceListFile))); |
| std::set<base::FilePath> changed_dirs; |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyChangeList(ParseChangeList(kTestJsonAdd), &changed_dirs)); |
| EXPECT_EQ(16683, metadata_->GetLargestChangestamp()); |
| EXPECT_TRUE(GetResourceEntry("drive/root/Added file.gdoc")); |
| EXPECT_EQ(1U, changed_dirs.size()); |
| EXPECT_TRUE(changed_dirs.count( |
| base::FilePath::FromUTF8Unsafe("drive/root"))); |
| |
| // Check the content of kTestJsonDelete. |
| entry_map.clear(); |
| parent_resource_id_map.clear(); |
| ConvertToMap(ParseChangeList(kTestJsonDelete), |
| &entry_map, &parent_resource_id_map); |
| EXPECT_EQ(1U, entry_map.size()); |
| EXPECT_TRUE(entry_map.count(kFileId)); |
| EXPECT_EQ(kParentId, parent_resource_id_map[kFileId]); |
| EXPECT_EQ("Added file", entry_map[kFileId].title()); |
| EXPECT_TRUE(entry_map[kFileId].deleted()); |
| |
| // Apply. |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyChangeList(ParseChangeList(kTestJsonDelete), &changed_dirs)); |
| EXPECT_EQ(16687, metadata_->GetLargestChangestamp()); |
| EXPECT_FALSE(GetResourceEntry("drive/root/Added file.gdoc")); |
| EXPECT_EQ(1U, changed_dirs.size()); |
| EXPECT_TRUE(changed_dirs.count( |
| base::FilePath::FromUTF8Unsafe("drive/root"))); |
| } |
| |
| |
| TEST_F(ChangeListProcessorTest, DeltaAddAndDeleteFileFromExistingDirectory) { |
| const char kTestJsonAdd[] = |
| "gdata/delta_file_added_in_directory.json"; |
| const char kTestJsonDelete[] = |
| "gdata/delta_file_deleted_in_directory.json"; |
| |
| const std::string kParentId("folder:1_folder_resource_id"); |
| const std::string kFileId("document:added_in_root_id"); |
| |
| ResourceEntryMap entry_map; |
| ParentResourceIdMap parent_resource_id_map; |
| |
| // Check the content of kTestJsonAdd. |
| ConvertToMap(ParseChangeList(kTestJsonAdd), |
| &entry_map, &parent_resource_id_map); |
| EXPECT_EQ(2U, entry_map.size()); |
| EXPECT_TRUE(entry_map.count(kFileId)); |
| EXPECT_TRUE(entry_map.count(kParentId)); |
| EXPECT_EQ(kParentId, parent_resource_id_map[kFileId]); |
| EXPECT_EQ("Added file", entry_map[kFileId].title()); |
| EXPECT_FALSE(entry_map[kFileId].deleted()); |
| |
| // Apply. |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyFullResourceList(ParseChangeList(kBaseResourceListFile))); |
| std::set<base::FilePath> changed_dirs; |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyChangeList(ParseChangeList(kTestJsonAdd), &changed_dirs)); |
| EXPECT_EQ(16730, metadata_->GetLargestChangestamp()); |
| EXPECT_TRUE(GetResourceEntry("drive/root/Directory 1/Added file.gdoc")); |
| |
| EXPECT_EQ(2U, changed_dirs.size()); |
| EXPECT_TRUE(changed_dirs.count( |
| base::FilePath::FromUTF8Unsafe("drive/root"))); |
| EXPECT_TRUE(changed_dirs.count( |
| base::FilePath::FromUTF8Unsafe("drive/root/Directory 1"))); |
| |
| // Check the content of kTestJsonDelete. |
| entry_map.clear(); |
| parent_resource_id_map.clear(); |
| ConvertToMap(ParseChangeList(kTestJsonDelete), |
| &entry_map, &parent_resource_id_map); |
| EXPECT_EQ(1U, entry_map.size()); |
| EXPECT_TRUE(entry_map.count(kFileId)); |
| EXPECT_EQ(kParentId, parent_resource_id_map[kFileId]); |
| EXPECT_EQ("Added file", entry_map[kFileId].title()); |
| EXPECT_TRUE(entry_map[kFileId].deleted()); |
| |
| // Apply. |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyChangeList(ParseChangeList(kTestJsonDelete), &changed_dirs)); |
| EXPECT_EQ(16770, metadata_->GetLargestChangestamp()); |
| EXPECT_FALSE(GetResourceEntry("drive/root/Directory 1/Added file.gdoc")); |
| |
| EXPECT_EQ(1U, changed_dirs.size()); |
| EXPECT_TRUE(changed_dirs.count( |
| base::FilePath::FromUTF8Unsafe("drive/root/Directory 1"))); |
| } |
| |
| TEST_F(ChangeListProcessorTest, DeltaAddFileToNewButDeletedDirectory) { |
| // This file contains the following updates: |
| // 1) A new PDF file is added to a new directory |
| // 2) but the new directory is marked "deleted" (i.e. moved to Trash) |
| // Hence, the PDF file should be just ignored. |
| const char kTestJson[] = |
| "gdata/delta_file_added_in_new_but_deleted_directory.json"; |
| |
| ResourceEntryMap entry_map; |
| ParentResourceIdMap parent_resource_id_map; |
| ConvertToMap(ParseChangeList(kTestJson), &entry_map, &parent_resource_id_map); |
| |
| const std::string kDirId("folder:new_folder_resource_id"); |
| const std::string kFileId("pdf:file_added_in_deleted_dir_id"); |
| |
| // Check the content of parsed ResourceEntryMap. |
| EXPECT_EQ(2U, entry_map.size()); |
| EXPECT_TRUE(entry_map.count(kDirId)); |
| EXPECT_TRUE(entry_map.count(kFileId)); |
| EXPECT_EQ(kDirId, parent_resource_id_map[kFileId]); |
| EXPECT_TRUE(entry_map[kDirId].deleted()); |
| |
| // Apply the changelist and check the effect. |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyFullResourceList(ParseChangeList(kBaseResourceListFile))); |
| std::set<base::FilePath> changed_dirs; |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyChangeList(ParseChangeList(kTestJson), &changed_dirs)); |
| |
| // The value is written in kTestJson. |
| EXPECT_EQ(16730, metadata_->GetLargestChangestamp()); |
| EXPECT_FALSE(GetResourceEntry("drive/root/New Directory/new_pdf_file.pdf")); |
| |
| EXPECT_TRUE(changed_dirs.empty()); |
| } |
| |
| TEST_F(ChangeListProcessorTest, RefreshDirectory) { |
| // Prepare metadata. |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyFullResourceList(ParseChangeList(kBaseResourceListFile))); |
| |
| // Create change lists. |
| ScopedVector<ChangeList> change_lists; |
| change_lists.push_back(new ChangeList); |
| |
| // Add a new file to the change lists. |
| ResourceEntry new_file; |
| new_file.set_title("new_file"); |
| new_file.set_resource_id("new_file_id"); |
| change_lists[0]->mutable_entries()->push_back(new_file); |
| change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId); |
| |
| // Add "Directory 1" to the map with a new name. |
| ResourceEntry dir1; |
| EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath( |
| util::GetDriveMyDriveRootPath().AppendASCII("Directory 1"), &dir1)); |
| dir1.set_title(dir1.title() + " (renamed)"); |
| change_lists[0]->mutable_entries()->push_back(dir1); |
| change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId); |
| |
| // Update the directory with the map. |
| const int64 kNewChangestamp = 12345; |
| base::FilePath file_path; |
| EXPECT_EQ(FILE_ERROR_OK, ChangeListProcessor::RefreshDirectory( |
| metadata_.get(), |
| DirectoryFetchInfo(kRootId, kNewChangestamp), |
| change_lists.Pass(), |
| &file_path)); |
| EXPECT_EQ(util::GetDriveMyDriveRootPath().value(), file_path.value()); |
| |
| // The new changestamp should be set. |
| ResourceEntry entry; |
| EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath( |
| util::GetDriveMyDriveRootPath(), &entry)); |
| EXPECT_EQ(kNewChangestamp, entry.directory_specific_info().changestamp()); |
| |
| // "new_file" should be added. |
| EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath( |
| util::GetDriveMyDriveRootPath().AppendASCII(new_file.title()), &entry)); |
| |
| // "Directory 1" should be renamed. |
| EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath( |
| util::GetDriveMyDriveRootPath().AppendASCII(dir1.title()), &entry)); |
| } |
| |
| TEST_F(ChangeListProcessorTest, RefreshDirectory_WrongParentId) { |
| // Prepare metadata. |
| EXPECT_EQ(FILE_ERROR_OK, |
| ApplyFullResourceList(ParseChangeList(kBaseResourceListFile))); |
| |
| // Create change lists and add a new file to it. |
| ScopedVector<ChangeList> change_lists; |
| change_lists.push_back(new ChangeList); |
| ResourceEntry new_file; |
| new_file.set_title("new_file"); |
| new_file.set_resource_id("new_file_id"); |
| // This entry should not be added because the parent ID does not match. |
| change_lists[0]->mutable_parent_resource_ids()->push_back( |
| "some-random-resource-id"); |
| change_lists[0]->mutable_entries()->push_back(new_file); |
| |
| |
| // Update the directory. |
| const int64 kNewChangestamp = 12345; |
| base::FilePath file_path; |
| EXPECT_EQ(FILE_ERROR_OK, ChangeListProcessor::RefreshDirectory( |
| metadata_.get(), |
| DirectoryFetchInfo(kRootId, kNewChangestamp), |
| change_lists.Pass(), |
| &file_path)); |
| EXPECT_EQ(util::GetDriveMyDriveRootPath().value(), file_path.value()); |
| |
| // "new_file" should not be added. |
| ResourceEntry entry; |
| EXPECT_EQ(FILE_ERROR_NOT_FOUND, metadata_->GetResourceEntryByPath( |
| util::GetDriveMyDriveRootPath().AppendASCII(new_file.title()), &entry)); |
| } |
| |
| } // namespace internal |
| } // namespace drive |