// 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 "components/drive/chromeos/sync/entry_update_performer.h"

#include <stdint.h>

#include "base/callback_helpers.h"
#include "base/files/file_util.h"
#include "base/md5.h"
#include "base/task_runner_util.h"
#include "components/drive/chromeos/file_cache.h"
#include "components/drive/chromeos/file_system/download_operation.h"
#include "components/drive/chromeos/resource_metadata.h"
#include "components/drive/drive_api_util.h"
#include "components/drive/file_system/operation_test_base.h"
#include "components/drive/job_scheduler.h"
#include "components/drive/service/fake_drive_service.h"
#include "content/public/test/test_utils.h"
#include "google_apis/drive/drive_api_parser.h"
#include "google_apis/drive/test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace drive {
namespace internal {

class EntryUpdatePerformerTest : public file_system::OperationTestBase {
 protected:
  void SetUp() override {
    OperationTestBase::SetUp();
    performer_.reset(new EntryUpdatePerformer(blocking_task_runner(),
                                              delegate(),
                                              scheduler(),
                                              metadata(),
                                              cache(),
                                              loader_controller()));
  }

  // Stores |content| to the cache and mark it as dirty.
  FileError StoreAndMarkDirty(const std::string& local_id,
                              const std::string& content) {
    base::FilePath path;
    if (!base::CreateTemporaryFileInDir(temp_dir(), &path) ||
        !google_apis::test_util::WriteStringToFile(path, content))
      return FILE_ERROR_FAILED;

    // Store the file to cache.
    FileError error = FILE_ERROR_FAILED;
    base::PostTaskAndReplyWithResult(
        blocking_task_runner(),
        FROM_HERE,
        base::Bind(&FileCache::Store,
                   base::Unretained(cache()),
                   local_id, std::string(), path,
                   FileCache::FILE_OPERATION_COPY),
        google_apis::test_util::CreateCopyResultCallback(&error));
    content::RunAllTasksUntilIdle();
    return error;
  }

  std::unique_ptr<EntryUpdatePerformer> performer_;
};

TEST_F(EntryUpdatePerformerTest, UpdateEntry) {
  base::FilePath src_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));
  base::FilePath dest_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/Sub Directory Folder"));

  ResourceEntry src_entry, dest_entry;
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &src_entry));
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));

  // Update local entry.
  base::Time new_last_modified = base::Time::FromInternalValue(
      src_entry.file_info().last_modified()) + base::TimeDelta::FromSeconds(1);
  base::Time new_last_accessed = base::Time::FromInternalValue(
      src_entry.file_info().last_accessed()) + base::TimeDelta::FromSeconds(2);

  src_entry.set_parent_local_id(dest_entry.local_id());
  src_entry.set_title("Moved" + src_entry.title());
  src_entry.mutable_file_info()->set_last_modified(
      new_last_modified.ToInternalValue());
  src_entry.mutable_file_info()->set_last_accessed(
      new_last_accessed.ToInternalValue());
  src_entry.set_metadata_edit_state(ResourceEntry::DIRTY);

  FileError error = FILE_ERROR_FAILED;
  base::PostTaskAndReplyWithResult(
      blocking_task_runner(),
      FROM_HERE,
      base::Bind(&ResourceMetadata::RefreshEntry,
                 base::Unretained(metadata()),
                 src_entry),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Perform server side update.
  error = FILE_ERROR_FAILED;
  performer_->UpdateEntry(
      src_entry.local_id(),
      ClientContext(USER_INITIATED),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Verify the file is updated on the server.
  google_apis::DriveApiErrorCode gdata_error = google_apis::DRIVE_OTHER_ERROR;
  std::unique_ptr<google_apis::FileResource> gdata_entry;
  fake_service()->GetFileResource(
      src_entry.resource_id(),
      google_apis::test_util::CreateCopyResultCallback(&gdata_error,
                                                       &gdata_entry));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
  ASSERT_TRUE(gdata_entry);

  EXPECT_EQ(src_entry.title(), gdata_entry->title());
  EXPECT_EQ(new_last_modified, gdata_entry->modified_date());
  EXPECT_EQ(new_last_accessed, gdata_entry->last_viewed_by_me_date());

  ASSERT_FALSE(gdata_entry->parents().empty());
  EXPECT_EQ(dest_entry.resource_id(), gdata_entry->parents()[0].file_id());
}

TEST_F(EntryUpdatePerformerTest, UpdateEntry_SetProperties) {
  base::FilePath entry_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));

  ResourceEntry entry;
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(entry_path, &entry));

  Property* const first_property = entry.mutable_new_properties()->Add();
  first_property->set_key("hello");
  first_property->set_value("world");
  first_property->set_visibility(Property_Visibility_PUBLIC);

  Property* const second_property = entry.mutable_new_properties()->Add();
  second_property->set_key("this");
  second_property->set_value("will-change");
  second_property->set_visibility(Property_Visibility_PUBLIC);
  entry.set_metadata_edit_state(ResourceEntry::DIRTY);

  FileError error = FILE_ERROR_FAILED;
  base::PostTaskAndReplyWithResult(
      blocking_task_runner(), FROM_HERE,
      base::Bind(&ResourceMetadata::RefreshEntry, base::Unretained(metadata()),
                 entry),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Perform server side update.
  error = FILE_ERROR_FAILED;
  performer_->UpdateEntry(
      entry.local_id(), ClientContext(USER_INITIATED),
      google_apis::test_util::CreateCopyResultCallback(&error));

  // Add a new property during an update.
  Property* const property = entry.mutable_new_properties()->Add();
  property->set_key("tokyo");
  property->set_value("kyoto");
  property->set_visibility(Property_Visibility_PUBLIC);

  // Modify an existing property during an update.
  second_property->set_value("changed");

  // Change the resource entry during an update.
  base::PostTaskAndReplyWithResult(
      blocking_task_runner(), FROM_HERE,
      base::Bind(&ResourceMetadata::RefreshEntry, base::Unretained(metadata()),
                 entry),
      google_apis::test_util::CreateCopyResultCallback(&error));

  // Wait until the update is fully completed.
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // List of synced properties should be removed from the proto.
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(entry_path, &entry));
  ASSERT_EQ(2, entry.new_properties().size());
  EXPECT_EQ("changed", entry.new_properties().Get(0).value());
  EXPECT_EQ("tokyo", entry.new_properties().Get(1).key());
}

// Tests updating metadata of a file with a non-dirty cache file.
TEST_F(EntryUpdatePerformerTest, UpdateEntry_WithNonDirtyCache) {
  base::FilePath src_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));

  // Download the file content to prepare a non-dirty cache file.
  file_system::DownloadOperation download_operation(
      blocking_task_runner(), delegate(), scheduler(), metadata(), cache(),
      temp_dir());
  FileError error = FILE_ERROR_FAILED;
  base::FilePath cache_file_path;
  std::unique_ptr<ResourceEntry> src_entry;
  download_operation.EnsureFileDownloadedByPath(
      src_path,
      ClientContext(USER_INITIATED),
      GetFileContentInitializedCallback(),
      google_apis::GetContentCallback(),
      google_apis::test_util::CreateCopyResultCallback(
          &error, &cache_file_path, &src_entry));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);
  ASSERT_TRUE(src_entry);

  // Update the entry locally.
  src_entry->set_title("Updated" + src_entry->title());
  src_entry->set_metadata_edit_state(ResourceEntry::DIRTY);

  error = FILE_ERROR_FAILED;
  base::PostTaskAndReplyWithResult(
      blocking_task_runner(),
      FROM_HERE,
      base::Bind(&ResourceMetadata::RefreshEntry,
                 base::Unretained(metadata()),
                 *src_entry),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Perform server side update. This shouldn't fail. (crbug.com/358590)
  error = FILE_ERROR_FAILED;
  performer_->UpdateEntry(
      src_entry->local_id(),
      ClientContext(USER_INITIATED),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Verify the file is updated on the server.
  google_apis::DriveApiErrorCode gdata_error = google_apis::DRIVE_OTHER_ERROR;
  std::unique_ptr<google_apis::FileResource> gdata_entry;
  fake_service()->GetFileResource(
      src_entry->resource_id(),
      google_apis::test_util::CreateCopyResultCallback(&gdata_error,
                                                       &gdata_entry));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
  ASSERT_TRUE(gdata_entry);
  EXPECT_EQ(src_entry->title(), gdata_entry->title());
}

TEST_F(EntryUpdatePerformerTest, UpdateEntry_NotFound) {
  const std::string id = "this ID should result in NOT_FOUND";
  FileError error = FILE_ERROR_FAILED;
  performer_->UpdateEntry(
      id, ClientContext(USER_INITIATED),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
}

TEST_F(EntryUpdatePerformerTest, UpdateEntry_ContentUpdate) {
  const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/File 1.txt"));
  const std::string kResourceId("2_file_resource_id");

  const std::string local_id = GetLocalId(kFilePath);
  EXPECT_FALSE(local_id.empty());

  const std::string kTestFileContent = "I'm being uploaded! Yay!";
  EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));

  int64_t original_changestamp =
      fake_service()->about_resource().largest_change_id();

  // The callback will be called upon completion of UpdateEntry().
  FileError error = FILE_ERROR_FAILED;
  performer_->UpdateEntry(
      local_id,
      ClientContext(USER_INITIATED),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Check that the server has received an update.
  EXPECT_LT(original_changestamp,
            fake_service()->about_resource().largest_change_id());

  // Check that the file size is updated to that of the updated content.
  google_apis::DriveApiErrorCode gdata_error = google_apis::DRIVE_OTHER_ERROR;
  std::unique_ptr<google_apis::FileResource> server_entry;
  fake_service()->GetFileResource(
      kResourceId,
      google_apis::test_util::CreateCopyResultCallback(&gdata_error,
                                                       &server_entry));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
  EXPECT_EQ(static_cast<int64_t>(kTestFileContent.size()),
            server_entry->file_size());

  // Make sure that the cache is no longer dirty.
  ResourceEntry entry;
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
  EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
}

TEST_F(EntryUpdatePerformerTest, UpdateEntry_ContentUpdateMd5Check) {
  const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/File 1.txt"));
  const std::string kResourceId("2_file_resource_id");

  const std::string local_id = GetLocalId(kFilePath);
  EXPECT_FALSE(local_id.empty());

  const std::string kTestFileContent = "I'm being uploaded! Yay!";
  EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));

  int64_t original_changestamp =
      fake_service()->about_resource().largest_change_id();

  // The callback will be called upon completion of UpdateEntry().
  FileError error = FILE_ERROR_FAILED;
  performer_->UpdateEntry(
      local_id,
      ClientContext(USER_INITIATED),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Check that the server has received an update.
  EXPECT_LT(original_changestamp,
            fake_service()->about_resource().largest_change_id());

  // Check that the file size is updated to that of the updated content.
  google_apis::DriveApiErrorCode gdata_error = google_apis::DRIVE_OTHER_ERROR;
  std::unique_ptr<google_apis::FileResource> server_entry;
  fake_service()->GetFileResource(
      kResourceId,
      google_apis::test_util::CreateCopyResultCallback(&gdata_error,
                                                       &server_entry));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
  EXPECT_EQ(static_cast<int64_t>(kTestFileContent.size()),
            server_entry->file_size());

  // Make sure that the cache is no longer dirty.
  ResourceEntry entry;
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
  EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());

  // Again mark the cache file dirty.
  std::unique_ptr<base::ScopedClosureRunner> file_closer;
  error = FILE_ERROR_FAILED;
  base::PostTaskAndReplyWithResult(
      blocking_task_runner(),
      FROM_HERE,
      base::Bind(&FileCache::OpenForWrite,
                 base::Unretained(cache()),
                 local_id,
                 &file_closer),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);
  file_closer.reset();

  // And call UpdateEntry again.
  // In this case, although the file is marked as dirty, but the content
  // hasn't been changed. Thus, the actual uploading should be skipped.
  original_changestamp = fake_service()->about_resource().largest_change_id();
  error = FILE_ERROR_FAILED;
  performer_->UpdateEntry(
      local_id,
      ClientContext(USER_INITIATED),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  EXPECT_EQ(original_changestamp,
            fake_service()->about_resource().largest_change_id());

  // Make sure that the cache is no longer dirty.
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
  EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
}

TEST_F(EntryUpdatePerformerTest, UpdateEntry_OpenedForWrite) {
  const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/File 1.txt"));
  const std::string kResourceId("2_file_resource_id");

  const std::string local_id = GetLocalId(kFilePath);
  EXPECT_FALSE(local_id.empty());

  const std::string kTestFileContent = "I'm being uploaded! Yay!";
  EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));

  // Emulate a situation where someone is writing to the file.
  std::unique_ptr<base::ScopedClosureRunner> file_closer;
  FileError error = FILE_ERROR_FAILED;
  base::PostTaskAndReplyWithResult(
      blocking_task_runner(),
      FROM_HERE,
      base::Bind(&FileCache::OpenForWrite,
                 base::Unretained(cache()),
                 local_id,
                 &file_closer),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Update. This should not clear the dirty bit.
  error = FILE_ERROR_FAILED;
  performer_->UpdateEntry(
      local_id,
      ClientContext(USER_INITIATED),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Make sure that the cache is still dirty.
  ResourceEntry entry;
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
  EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty());

  // Close the file.
  file_closer.reset();

  // Update. This should clear the dirty bit.
  error = FILE_ERROR_FAILED;
  performer_->UpdateEntry(
      local_id,
      ClientContext(USER_INITIATED),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Make sure that the cache is no longer dirty.
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
  EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
}

TEST_F(EntryUpdatePerformerTest, UpdateEntry_UploadNewFile) {
  // Create a new file locally.
  const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/New File.txt"));

  ResourceEntry parent;
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath.DirName(), &parent));

  ResourceEntry entry;
  entry.set_parent_local_id(parent.local_id());
  entry.set_title(kFilePath.BaseName().AsUTF8Unsafe());
  entry.mutable_file_specific_info()->set_content_mime_type("text/plain");
  entry.set_metadata_edit_state(ResourceEntry::DIRTY);

  FileError error = FILE_ERROR_FAILED;
  std::string local_id;
  base::PostTaskAndReplyWithResult(
      blocking_task_runner(),
      FROM_HERE,
      base::Bind(&internal::ResourceMetadata::AddEntry,
                 base::Unretained(metadata()),
                 entry,
                 &local_id),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Update. This should result in creating a new file on the server.
  error = FILE_ERROR_FAILED;
  performer_->UpdateEntry(
      local_id,
      ClientContext(USER_INITIATED),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // The entry got a resource ID.
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
  EXPECT_FALSE(entry.resource_id().empty());
  EXPECT_EQ(ResourceEntry::CLEAN, entry.metadata_edit_state());

  // Make sure that the cache is no longer dirty.
  EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());

  // Make sure that we really created a file.
  google_apis::DriveApiErrorCode status = google_apis::DRIVE_OTHER_ERROR;
  std::unique_ptr<google_apis::FileResource> server_entry;
  fake_service()->GetFileResource(
      entry.resource_id(),
      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
  ASSERT_TRUE(server_entry);
  EXPECT_FALSE(server_entry->IsDirectory());
}

TEST_F(EntryUpdatePerformerTest, UpdateEntry_NewFileOpendForWrite) {
  // Create a new file locally.
  const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/New File.txt"));

  ResourceEntry parent;
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath.DirName(), &parent));

  ResourceEntry entry;
  entry.set_parent_local_id(parent.local_id());
  entry.set_title(kFilePath.BaseName().AsUTF8Unsafe());
  entry.mutable_file_specific_info()->set_content_mime_type("text/plain");
  entry.set_metadata_edit_state(ResourceEntry::DIRTY);

  FileError error = FILE_ERROR_FAILED;
  std::string local_id;
  base::PostTaskAndReplyWithResult(
      blocking_task_runner(),
      FROM_HERE,
      base::Bind(&internal::ResourceMetadata::AddEntry,
                 base::Unretained(metadata()),
                 entry,
                 &local_id),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  const std::string kTestFileContent = "This is a new file.";
  EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));

  // Emulate a situation where someone is writing to the file.
  std::unique_ptr<base::ScopedClosureRunner> file_closer;
  error = FILE_ERROR_FAILED;
  base::PostTaskAndReplyWithResult(
      blocking_task_runner(),
      FROM_HERE,
      base::Bind(&FileCache::OpenForWrite,
                 base::Unretained(cache()),
                 local_id,
                 &file_closer),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Update, but no update is performed because the file is opened.
  error = FILE_ERROR_FAILED;
  performer_->UpdateEntry(
      local_id,
      ClientContext(USER_INITIATED),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // The entry hasn't got a resource ID yet.
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
  EXPECT_TRUE(entry.resource_id().empty());

  // Close the file.
  file_closer.reset();

  // Update. This should result in creating a new file on the server.
  error = FILE_ERROR_FAILED;
  performer_->UpdateEntry(
      local_id,
      ClientContext(USER_INITIATED),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // The entry got a resource ID.
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
  EXPECT_FALSE(entry.resource_id().empty());
  EXPECT_EQ(ResourceEntry::CLEAN, entry.metadata_edit_state());
}

TEST_F(EntryUpdatePerformerTest, UpdateEntry_CreateDirectory) {
  // Create a new directory locally.
  const base::FilePath kPath(FILE_PATH_LITERAL("drive/root/New Directory"));

  ResourceEntry parent;
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kPath.DirName(), &parent));

  ResourceEntry entry;
  entry.set_parent_local_id(parent.local_id());
  entry.set_title(kPath.BaseName().AsUTF8Unsafe());
  entry.mutable_file_info()->set_is_directory(true);
  entry.set_metadata_edit_state(ResourceEntry::DIRTY);

  FileError error = FILE_ERROR_FAILED;
  std::string local_id;
  base::PostTaskAndReplyWithResult(
      blocking_task_runner(),
      FROM_HERE,
      base::Bind(&internal::ResourceMetadata::AddEntry,
                 base::Unretained(metadata()),
                 entry,
                 &local_id),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Update. This should result in creating a new directory on the server.
  error = FILE_ERROR_FAILED;
  performer_->UpdateEntry(
      local_id,
      ClientContext(USER_INITIATED),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // The entry got a resource ID.
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kPath, &entry));
  EXPECT_FALSE(entry.resource_id().empty());
  EXPECT_EQ(ResourceEntry::CLEAN, entry.metadata_edit_state());

  // Make sure that we really created a directory.
  google_apis::DriveApiErrorCode status = google_apis::DRIVE_OTHER_ERROR;
  std::unique_ptr<google_apis::FileResource> server_entry;
  fake_service()->GetFileResource(
      entry.resource_id(),
      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
  ASSERT_TRUE(server_entry);
  EXPECT_TRUE(server_entry->IsDirectory());
}

TEST_F(EntryUpdatePerformerTest, UpdateEntry_InsufficientPermission) {
  base::FilePath src_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));

  ResourceEntry src_entry;
  EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &src_entry));

  // Update local entry.
  ResourceEntry updated_entry(src_entry);
  updated_entry.set_title("Moved" + src_entry.title());
  updated_entry.set_metadata_edit_state(ResourceEntry::DIRTY);

  FileError error = FILE_ERROR_FAILED;
  base::PostTaskAndReplyWithResult(
      blocking_task_runner(),
      FROM_HERE,
      base::Bind(&ResourceMetadata::RefreshEntry,
                 base::Unretained(metadata()),
                 updated_entry),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Set user permission to forbid server side update.
  EXPECT_EQ(google_apis::HTTP_SUCCESS, fake_service()->SetUserPermission(
      src_entry.resource_id(), google_apis::drive::PERMISSION_ROLE_READER));

  // Try to perform update.
  error = FILE_ERROR_FAILED;
  performer_->UpdateEntry(
      src_entry.local_id(),
      ClientContext(USER_INITIATED),
      google_apis::test_util::CreateCopyResultCallback(&error));
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // This should result in reverting the local change.
  ResourceEntry result_entry;
  EXPECT_EQ(FILE_ERROR_OK,
            GetLocalResourceEntryById(src_entry.local_id(), &result_entry));
  EXPECT_EQ(src_entry.title(), result_entry.title());
}

}  // namespace internal
}  // namespace drive
