// Copyright (c) 2012 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/gdata/drive_file_system.h"

#include <string>
#include <vector>

#include "base/bind.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/json/json_file_value_serializer.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
#include "base/stringprintf.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/values.h"
#include "chrome/browser/chromeos/gdata/drive.pb.h"
#include "chrome/browser/chromeos/gdata/drive_file_system_util.h"
#include "chrome/browser/chromeos/gdata/drive_function_remove.h"
#include "chrome/browser/chromeos/gdata/drive_test_util.h"
#include "chrome/browser/chromeos/gdata/drive_uploader.h"
#include "chrome/browser/chromeos/gdata/drive_webapps_registry.h"
#include "chrome/browser/chromeos/gdata/mock_directory_change_observer.h"
#include "chrome/browser/chromeos/gdata/mock_drive_cache_observer.h"
#include "chrome/browser/chromeos/gdata/mock_drive_service.h"
#include "chrome/browser/chromeos/gdata/mock_drive_uploader.h"
#include "chrome/browser/chromeos/gdata/mock_drive_web_apps_registry.h"
#include "chrome/browser/chromeos/gdata/mock_free_disk_space_getter.h"
#include "chrome/browser/google_apis/drive_api_parser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::AnyNumber;
using ::testing::AtLeast;
using ::testing::Eq;
using ::testing::NotNull;
using ::testing::Return;
using ::testing::StrictMock;
using ::testing::_;

namespace gdata {
namespace {

const char kSymLinkToDevNull[] = "/dev/null";

const int64 kLotsOfSpace = kMinFreeSpace * 10;

struct SearchResultPair {
  const char* path;
  const bool is_directory;
};

// Callback to DriveFileSystem::Search used in ContentSearch tests.
// Verifies returned vector of results.
void DriveSearchCallback(
    MessageLoop* message_loop,
    const SearchResultPair* expected_results,
    size_t expected_results_size,
    DriveFileError error,
    const GURL& next_feed,
    scoped_ptr<std::vector<SearchResultInfo> > results) {
  ASSERT_TRUE(results.get());
  ASSERT_EQ(expected_results_size, results->size());

  for (size_t i = 0; i < results->size(); i++) {
    EXPECT_EQ(FilePath(expected_results[i].path),
              results->at(i).path);
    EXPECT_EQ(expected_results[i].is_directory,
              results->at(i).is_directory);
  }

  message_loop->Quit();
}

// Action used to set mock expectations for
// DriveServiceInterface::GetDocumentEntry().
ACTION_P2(MockGetDocumentEntry, status, value) {
  base::MessageLoopProxy::current()->PostTask(FROM_HERE,
      base::Bind(arg1, status, base::Passed(value)));
}

// Action used to set mock expectations for
// DriveUploaderInterface::UploadExistingFile().
ACTION_P4(MockUploadExistingFile,
          error, drive_path, local_file_path, document_entry) {
  scoped_ptr<DocumentEntry> scoped_document_entry(document_entry);
  base::MessageLoopProxy::current()->PostTask(FROM_HERE,
      base::Bind(arg5,
                 error,
                 drive_path,
                 local_file_path,
                 base::Passed(&scoped_document_entry)));

  const int kUploadId = 123;
  return kUploadId;
}

// Action used to set mock expectations for
// DriveUploaderInterface::UploadNewFile().
ACTION(MockUploadNewFile) {
  scoped_ptr<base::Value> value =
      test_util::LoadJSONFile("gdata/uploaded_file.json");
  scoped_ptr<DocumentEntry> document_entry(
      DocumentEntry::ExtractAndParse(*value));

  base::MessageLoopProxy::current()->PostTask(FROM_HERE,
      base::Bind(arg7,
                 DRIVE_FILE_OK,
                 arg1,
                 arg2,
                 base::Passed(&document_entry)));

  const int kUploadId = 123;
  return kUploadId;
}

// Action used to set mock expectations for
// DriveFileSystem::CopyDocument().
ACTION_P2(MockCopyDocument, status, value) {
  base::MessageLoopProxy::current()->PostTask(
      FROM_HERE,
      base::Bind(arg2, status, base::Passed(value)));
}

// Counts the number of files (not directories) in |entries|.
int CountFiles(const DriveEntryProtoVector& entries) {
  int num_files = 0;
  for (size_t i = 0; i < entries.size(); ++i) {
    if (!entries[i].file_info().is_directory())
      ++num_files;
  }
  return num_files;
}

}  // namespace

class DriveFileSystemTest : public testing::Test {
 protected:
  DriveFileSystemTest()
      : ui_thread_(content::BrowserThread::UI, &message_loop_),
        io_thread_(content::BrowserThread::IO),
        cache_(NULL),
        file_system_(NULL),
        mock_drive_service_(NULL),
        mock_webapps_registry_(NULL),
        num_callback_invocations_(0),
        expected_error_(DRIVE_FILE_OK),
        expected_cache_state_(0),
        expected_sub_dir_type_(DriveCache::CACHE_TYPE_META),
        expected_success_(true),
        expect_outgoing_symlink_(false),
        root_feed_changestamp_(0) {
  }

  virtual void SetUp() OVERRIDE {
    io_thread_.StartIOThread();

    profile_.reset(new TestingProfile);

    callback_helper_ = new CallbackHelper;

    // Allocate and keep a pointer to the mock, and inject it into the
    // DriveFileSystem object, which will own the mock object.
    mock_drive_service_ = new StrictMock<MockDriveService>;

    EXPECT_CALL(*mock_drive_service_, Initialize(profile_.get())).Times(1);

    // Likewise, this will be owned by DriveFileSystem.
    mock_free_disk_space_checker_ = new StrictMock<MockFreeDiskSpaceGetter>;
    SetFreeDiskSpaceGetterForTesting(mock_free_disk_space_checker_);

    scoped_refptr<base::SequencedWorkerPool> pool =
        content::BrowserThread::GetBlockingPool();
    blocking_task_runner_ =
        pool->GetSequencedTaskRunner(pool->GetSequenceToken());

    cache_ = DriveCache::CreateDriveCacheOnUIThread(
        DriveCache::GetCacheRootPath(profile_.get()), blocking_task_runner_);

    mock_uploader_.reset(new StrictMock<MockDriveUploader>);
    mock_webapps_registry_.reset(new StrictMock<MockDriveWebAppsRegistry>);

    ASSERT_FALSE(file_system_);
    file_system_ = new DriveFileSystem(profile_.get(),
                                       cache_,
                                       mock_drive_service_,
                                       mock_uploader_.get(),
                                       mock_webapps_registry_.get(),
                                       blocking_task_runner_);

    mock_cache_observer_.reset(new StrictMock<MockDriveCacheObserver>);
    cache_->AddObserver(mock_cache_observer_.get());

    mock_directory_observer_.reset(new StrictMock<MockDirectoryChangeObserver>);
    file_system_->AddObserver(mock_directory_observer_.get());

    file_system_->Initialize();
    cache_->RequestInitializeOnUIThreadForTesting();
    test_util::RunBlockingPoolTask();
  }

  virtual void TearDown() OVERRIDE {
    ASSERT_TRUE(file_system_);
    EXPECT_CALL(*mock_drive_service_, CancelAll()).Times(1);
    delete file_system_;
    file_system_ = NULL;
    delete mock_drive_service_;
    mock_drive_service_ = NULL;
    SetFreeDiskSpaceGetterForTesting(NULL);
    cache_->DestroyOnUIThread();
    // The cache destruction requires to post a task to the blocking pool.
    test_util::RunBlockingPoolTask();

    profile_.reset(NULL);
  }

  // Loads test json file as root ("/drive") element.
  void LoadRootFeedDocument(const std::string& filename) {
    LoadChangeFeed(filename, 0);
  }

  void LoadChangeFeed(const std::string& filename,
                      int largest_changestamp) {
    test_util::LoadChangeFeed(filename,
                              file_system_,
                              largest_changestamp,
                              root_feed_changestamp_);
    root_feed_changestamp_++;
  }

  void AddDirectoryFromFile(const FilePath& directory_path,
                            const std::string& filename) {
    scoped_ptr<Value> atom = test_util::LoadJSONFile(filename);
    ASSERT_TRUE(atom.get());
    ASSERT_TRUE(atom->GetType() == Value::TYPE_DICTIONARY);

    DictionaryValue* dict_value = NULL;
    Value* entry_value = NULL;
    ASSERT_TRUE(atom->GetAsDictionary(&dict_value));
    ASSERT_TRUE(dict_value->Get("entry", &entry_value));

    DictionaryValue* entry_dict = NULL;
    ASSERT_TRUE(entry_value->GetAsDictionary(&entry_dict));

    // Tweak entry title to match the last segment of the directory path
    // (new directory name).
    std::vector<FilePath::StringType> dir_parts;
    directory_path.GetComponents(&dir_parts);
    entry_dict->SetString("title.$t", dir_parts[dir_parts.size() - 1]);

    DriveFileError error;
    DriveFileSystem::CreateDirectoryParams params(directory_path,
                                                  directory_path,
                                                  false,  // is_exclusive
                                                  false,  // is_recursive
        base::Bind(&test_util::CopyErrorCodeFromFileOperationCallback, &error));
    file_system_->AddNewDirectory(params, HTTP_SUCCESS, atom.Pass());
    test_util::RunBlockingPoolTask();
    EXPECT_EQ(DRIVE_FILE_OK, error);
  }

  bool RemoveEntry(const FilePath& file_path) {
    DriveFileError error;
    EXPECT_CALL(*mock_drive_service_, DeleteDocument(_, _)).Times(AnyNumber());
    file_system_->remove_function_->Remove(
        file_path, false,
        base::Bind(&test_util::CopyErrorCodeFromFileOperationCallback, &error));

    test_util::RunBlockingPoolTask();
    return error == DRIVE_FILE_OK;
  }

  FilePath GetCachePathForFile(const std::string& resource_id,
                               const std::string& md5) {
    return cache_->GetCacheFilePath(resource_id,
                                    md5,
                                    DriveCache::CACHE_TYPE_TMP,
                                    DriveCache::CACHED_FILE_FROM_SERVER);
  }

  // Gets entry info by path synchronously.
  scoped_ptr<DriveEntryProto> GetEntryInfoByPathSync(
      const FilePath& file_path) {
    file_system_->GetEntryInfoByPath(
        file_path,
        base::Bind(&CallbackHelper::GetEntryInfoCallback,
                   callback_helper_.get()));
    test_util::RunBlockingPoolTask();

    return callback_helper_->entry_proto_.Pass();
  }

  // Gets directory info by path synchronously.
  scoped_ptr<DriveEntryProtoVector> ReadDirectoryByPathSync(
      const FilePath& file_path) {
    file_system_->ReadDirectoryByPath(
        file_path,
        base::Bind(&CallbackHelper::ReadDirectoryCallback,
                   callback_helper_.get()));
    test_util::RunBlockingPoolTask();

    return callback_helper_->directory_entries_.Pass();
  }

  // Returns true if an entry exists at |file_path|.
  bool EntryExists(const FilePath& file_path) {
    return GetEntryInfoByPathSync(file_path).get();
  }


  // Gets the resource ID of |file_path|. Returns an empty string if not found.
  std::string GetResourceIdByPath(const FilePath& file_path) {
    scoped_ptr<DriveEntryProto> entry_proto =
        GetEntryInfoByPathSync(file_path);
    if (entry_proto.get())
      return entry_proto->resource_id();
    else
      return "";
  }

  // Helper function to call GetCacheEntry from origin thread.
  bool GetCacheEntryFromOriginThread(const std::string& resource_id,
                                     const std::string& md5,
                                     DriveCacheEntry* cache_entry) {
    bool result = false;
    blocking_task_runner_->PostTask(
        FROM_HERE,
        base::Bind(&DriveFileSystemTest::GetCacheEntryFromOriginThreadInternal,
                   base::Unretained(this),
                   resource_id,
                   md5,
                   cache_entry,
                   &result));
    test_util::RunBlockingPoolTask();
    return result;
  }

  // Used to implement GetCacheEntry.
  void GetCacheEntryFromOriginThreadInternal(
      const std::string& resource_id,
      const std::string& md5,
      DriveCacheEntry* cache_entry,
      bool* result) {
    *result = cache_->GetCacheEntry(resource_id, md5, cache_entry);
  }

  // Returns true if the cache entry exists for the given resource ID and MD5.
  bool CacheEntryExists(const std::string& resource_id,
                        const std::string& md5) {
    DriveCacheEntry cache_entry;
    return GetCacheEntryFromOriginThread(resource_id, md5, &cache_entry);
  }

  // Returns true if the cache file exists for the given resource ID and MD5.
  bool CacheFileExists(const std::string& resource_id,
                       const std::string& md5) {
    const FilePath file_path = cache_->GetCacheFilePath(
        resource_id,
        md5,
        DriveCache::CACHE_TYPE_TMP,
        DriveCache::CACHED_FILE_FROM_SERVER);
    return file_util::PathExists(file_path);
  }

  void TestStoreToCache(
      const std::string& resource_id,
      const std::string& md5,
      const FilePath& source_path,
      DriveFileError expected_error,
      int expected_cache_state,
      DriveCache::CacheSubDirectoryType expected_sub_dir_type) {
    expected_error_ = expected_error;
    expected_cache_state_ = expected_cache_state;
    expected_sub_dir_type_ = expected_sub_dir_type;

    cache_->StoreOnUIThread(
        resource_id, md5, source_path,
        DriveCache::FILE_OPERATION_COPY,
        base::Bind(&DriveFileSystemTest::VerifyCacheFileState,
                   base::Unretained(this)));

    test_util::RunBlockingPoolTask();
  }

  void TestPin(
      const std::string& resource_id,
      const std::string& md5,
      DriveFileError expected_error,
      int expected_cache_state,
      DriveCache::CacheSubDirectoryType expected_sub_dir_type) {
    expected_error_ = expected_error;
    expected_cache_state_ = expected_cache_state;
    expected_sub_dir_type_ = expected_sub_dir_type;

    cache_->PinOnUIThread(
        resource_id, md5,
        base::Bind(&DriveFileSystemTest::VerifyCacheFileState,
                   base::Unretained(this)));

    test_util::RunBlockingPoolTask();
  }

  void TestMarkDirty(
      const std::string& resource_id,
      const std::string& md5,
      DriveFileError expected_error,
      int expected_cache_state,
      DriveCache::CacheSubDirectoryType expected_sub_dir_type) {
    expected_error_ = expected_error;
    expected_cache_state_ = expected_cache_state;
    expected_sub_dir_type_ = expected_sub_dir_type;
    expect_outgoing_symlink_ = false;

    cache_->MarkDirtyOnUIThread(
        resource_id,
        md5,
        base::Bind(&DriveFileSystemTest::VerifyMarkDirty,
                   base::Unretained(this),
                   resource_id,
                   md5));

    test_util::RunBlockingPoolTask();
  }

  void VerifyMarkDirty(const std::string& resource_id,
                       const std::string& md5,
                       DriveFileError error,
                       const FilePath& cache_file_path) {
    VerifyCacheFileState(error, resource_id, md5);

    // Verify filename of |cache_file_path|.
    if (error == DRIVE_FILE_OK) {
      FilePath base_name = cache_file_path.BaseName();
      EXPECT_EQ(util::EscapeCacheFileName(resource_id) +
                FilePath::kExtensionSeparator +
                "local",
                base_name.value());
    } else {
      EXPECT_TRUE(cache_file_path.empty());
    }
  }

  void TestCommitDirty(
      const std::string& resource_id,
      const std::string& md5,
      DriveFileError expected_error,
      int expected_cache_state,
      DriveCache::CacheSubDirectoryType expected_sub_dir_type) {
    expected_error_ = expected_error;
    expected_cache_state_ = expected_cache_state;
    expected_sub_dir_type_ = expected_sub_dir_type;
    expect_outgoing_symlink_ = true;

    cache_->CommitDirtyOnUIThread(
        resource_id, md5,
        base::Bind(&DriveFileSystemTest::VerifyCacheFileState,
                   base::Unretained(this)));

    test_util::RunBlockingPoolTask();
  }

  // Verify the file identified by |resource_id| and |md5| is in the expected
  // cache state after |OpenFile|, that is, marked dirty and has no outgoing
  // symlink, etc.
  void VerifyCacheStateAfterOpenFile(DriveFileError error,
                                     const std::string& resource_id,
                                     const std::string& md5,
                                     const FilePath& cache_file_path) {
    expected_error_ = DRIVE_FILE_OK;
    expected_cache_state_ = (test_util::TEST_CACHE_STATE_PRESENT |
                             test_util::TEST_CACHE_STATE_DIRTY |
                             test_util::TEST_CACHE_STATE_PERSISTENT);
    expected_sub_dir_type_ = DriveCache::CACHE_TYPE_PERSISTENT;
    expect_outgoing_symlink_ = false;
    VerifyMarkDirty(resource_id, md5, error, cache_file_path);
  }

  // Verify the file identified by |resource_id| and |md5| is in the expected
  // cache state after |CloseFile|, that is, marked dirty and has an outgoing
  // symlink, etc.
  void VerifyCacheStateAfterCloseFile(DriveFileError error,
                                      const std::string& resource_id,
                                      const std::string& md5) {
    expected_error_ = DRIVE_FILE_OK;
    expected_cache_state_ = (test_util::TEST_CACHE_STATE_PRESENT |
                             test_util::TEST_CACHE_STATE_DIRTY |
                             test_util::TEST_CACHE_STATE_PERSISTENT);
    expected_sub_dir_type_ = DriveCache::CACHE_TYPE_PERSISTENT;
    expect_outgoing_symlink_ = true;
    VerifyCacheFileState(error, resource_id, md5);
  }

  void VerifyCacheFileState(DriveFileError error,
                            const std::string& resource_id,
                            const std::string& md5) {
    ++num_callback_invocations_;

    EXPECT_EQ(expected_error_, error);

    // Verify cache map.
    DriveCacheEntry cache_entry;
    const bool cache_entry_found =
        GetCacheEntryFromOriginThread(resource_id, md5, &cache_entry);
    if (test_util::ToCacheEntry(expected_cache_state_).is_present() ||
        test_util::ToCacheEntry(expected_cache_state_).is_pinned()) {
      ASSERT_TRUE(cache_entry_found);
      EXPECT_TRUE(test_util::CacheStatesEqual(
          test_util::ToCacheEntry(expected_cache_state_),
          cache_entry));
      EXPECT_EQ(expected_sub_dir_type_,
                DriveCache::GetSubDirectoryType(cache_entry));
    } else {
      EXPECT_FALSE(cache_entry_found);
    }

    // Verify actual cache file.
    FilePath dest_path = cache_->GetCacheFilePath(
        resource_id,
        md5,
        test_util::ToCacheEntry(expected_cache_state_).is_pinned() ||
        test_util::ToCacheEntry(expected_cache_state_).is_dirty() ?
                DriveCache::CACHE_TYPE_PERSISTENT :
                DriveCache::CACHE_TYPE_TMP,
        test_util::ToCacheEntry(expected_cache_state_).is_dirty() ?
            DriveCache::CACHED_FILE_LOCALLY_MODIFIED :
            DriveCache::CACHED_FILE_FROM_SERVER);
    bool exists = file_util::PathExists(dest_path);
    if (test_util::ToCacheEntry(expected_cache_state_).is_present())
      EXPECT_TRUE(exists);
    else
      EXPECT_FALSE(exists);

    // Verify symlink in pinned dir.
    FilePath symlink_path = cache_->GetCacheFilePath(
        resource_id,
        std::string(),
        DriveCache::CACHE_TYPE_PINNED,
        DriveCache::CACHED_FILE_FROM_SERVER);
    // Check that pin symlink exists, without dereferencing to target path.
    exists = file_util::IsLink(symlink_path);
    if (test_util::ToCacheEntry(expected_cache_state_).is_pinned()) {
      EXPECT_TRUE(exists);
      FilePath target_path;
      EXPECT_TRUE(file_util::ReadSymbolicLink(symlink_path, &target_path));
      if (test_util::ToCacheEntry(expected_cache_state_).is_present())
        EXPECT_EQ(dest_path, target_path);
      else
        EXPECT_EQ(kSymLinkToDevNull, target_path.value());
    } else {
      EXPECT_FALSE(exists);
    }

    // Verify symlink in outgoing dir.
    symlink_path = cache_->GetCacheFilePath(
        resource_id,
        std::string(),
        DriveCache::CACHE_TYPE_OUTGOING,
        DriveCache::CACHED_FILE_FROM_SERVER);
    // Check that outgoing symlink exists, without dereferencing to target path.
    exists = file_util::IsLink(symlink_path);
    if (expect_outgoing_symlink_ &&
        test_util::ToCacheEntry(expected_cache_state_).is_dirty()) {
      EXPECT_TRUE(exists);
      FilePath target_path;
      EXPECT_TRUE(file_util::ReadSymbolicLink(symlink_path, &target_path));
      EXPECT_TRUE(target_path.value() != kSymLinkToDevNull);
      if (test_util::ToCacheEntry(expected_cache_state_).is_present())
        EXPECT_EQ(dest_path, target_path);
    } else {
      EXPECT_FALSE(exists);
    }
  }

  void SetExpectationsForGetDocumentEntry(scoped_ptr<base::Value>* document,
                                          const std::string& resource_id) {
    EXPECT_CALL(*mock_drive_service_, GetDocumentEntry(resource_id, _))
        .WillOnce(MockGetDocumentEntry(gdata::HTTP_SUCCESS, document));
  }

  // Loads serialized proto file from GCache, and makes sure the root
  // filesystem has a root at 'drive'
  void TestLoadMetadataFromCache() {
    file_system_->LoadRootFeedFromCacheForTesting();
    test_util::RunBlockingPoolTask();
  }

  // Creates a proto file representing a filesystem with directories:
  // drive, drive/Dir1, drive/Dir1/SubDir2
  // and files
  // drive/File1, drive/Dir1/File2, drive/Dir1/SubDir2/File3.
  // Sets the changestamp to 654321, equal to that of "account_metadata.json"
  // test data, indicating the cache is holding the latest file system info.
  void SaveTestFileSystem() {
    DriveRootDirectoryProto root;
    root.set_version(kProtoVersion);
    root.set_largest_changestamp(654321);
    DriveDirectoryProto* root_dir = root.mutable_drive_directory();
    DriveEntryProto* dir_base = root_dir->mutable_drive_entry();
    PlatformFileInfoProto* platform_info = dir_base->mutable_file_info();
    dir_base->set_title("drive");
    dir_base->set_resource_id(kDriveRootDirectoryResourceId);
    dir_base->set_upload_url("http://resumable-create-media/1");
    platform_info->set_is_directory(true);

    // drive/File1
    DriveEntryProto* file = root_dir->add_child_files();
    file->set_title("File1");
    file->set_resource_id("resource_id:File1");
    file->set_upload_url("http://resumable-edit-media/1");
    file->mutable_file_specific_info()->set_file_md5("md5");
    platform_info = file->mutable_file_info();
    platform_info->set_is_directory(false);
    platform_info->set_size(1048576);

    // drive/Dir1
    DriveDirectoryProto* dir1 = root_dir->add_child_directories();
    dir_base = dir1->mutable_drive_entry();
    dir_base->set_title("Dir1");
    dir_base->set_resource_id("resource_id:Dir1");
    dir_base->set_upload_url("http://resumable-create-media/2");
    platform_info = dir_base->mutable_file_info();
    platform_info->set_is_directory(true);

    // drive/Dir1/File2
    file = dir1->add_child_files();
    file->set_title("File2");
    file->set_resource_id("resource_id:File2");
    file->set_upload_url("http://resumable-edit-media/2");
    file->mutable_file_specific_info()->set_file_md5("md5");
    platform_info = file->mutable_file_info();
    platform_info->set_is_directory(false);
    platform_info->set_size(555);

    // drive/Dir1/SubDir2
    DriveDirectoryProto* dir2 = dir1->add_child_directories();
    dir_base = dir2->mutable_drive_entry();
    dir_base->set_title("SubDir2");
    dir_base->set_resource_id("resource_id:SubDir2");
    dir_base->set_upload_url("http://resumable-create-media/3");
    platform_info = dir_base->mutable_file_info();
    platform_info->set_is_directory(true);

    // drive/Dir1/SubDir2/File3
    file = dir2->add_child_files();
    file->set_title("File3");
    file->set_resource_id("resource_id:File3");
    file->set_upload_url("http://resumable-edit-media/3");
    file->mutable_file_specific_info()->set_file_md5("md5");
    platform_info = file->mutable_file_info();
    platform_info->set_is_directory(false);
    platform_info->set_size(12345);

    // Write this proto out to GCache/vi/meta/file_system.pb
    std::string serialized_proto;
    ASSERT_TRUE(root.SerializeToString(&serialized_proto));
    ASSERT_TRUE(!serialized_proto.empty());

    FilePath cache_dir_path = profile_->GetPath().Append(
        FILE_PATH_LITERAL("GCache/v1/meta/"));
    ASSERT_TRUE(file_util::CreateDirectory(cache_dir_path));
    const int file_size = static_cast<int>(serialized_proto.length());
    ASSERT_EQ(file_util::WriteFile(cache_dir_path.Append("file_system.pb"),
        serialized_proto.data(), file_size), file_size);
  }

  // Verifies that |file_path| is a valid JSON file for the hosted document
  // associated with |entry| (i.e. |url| and |resource_id| match).
  void VerifyHostedDocumentJSONFile(const DriveEntryProto& entry_proto,
                                    const FilePath& file_path) {
    std::string error;
    JSONFileValueSerializer serializer(file_path);
    scoped_ptr<Value> value(serializer.Deserialize(NULL, &error));
    ASSERT_TRUE(value.get()) << "Parse error " << file_path.value()
                             << ": " << error;
    DictionaryValue* dict_value = NULL;
    ASSERT_TRUE(value->GetAsDictionary(&dict_value));

    std::string edit_url, resource_id;
    EXPECT_TRUE(dict_value->GetString("url", &edit_url));
    EXPECT_TRUE(dict_value->GetString("resource_id", &resource_id));

    EXPECT_EQ(entry_proto.file_specific_info().alternate_url(),
              edit_url);
    EXPECT_EQ(entry_proto.resource_id(), resource_id);
  }

  // This is used as a helper for registering callbacks that need to be
  // RefCountedThreadSafe, and a place where we can fetch results from various
  // operations.
  class CallbackHelper
    : public base::RefCountedThreadSafe<CallbackHelper> {
   public:
    CallbackHelper()
        : last_error_(DRIVE_FILE_OK),
          quota_bytes_total_(0),
          quota_bytes_used_(0),
          entry_proto_(NULL) {}

    virtual void GetFileCallback(DriveFileError error,
                                 const FilePath& file_path,
                                 const std::string& mime_type,
                                 DriveFileType file_type) {
      last_error_ = error;
      download_path_ = file_path;
      mime_type_ = mime_type;
      file_type_ = file_type;
    }

    virtual void FileOperationCallback(DriveFileError error) {
      DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

      last_error_ = error;
    }

    virtual void GetAvailableSpaceCallback(DriveFileError error,
                                           int64 bytes_total,
                                           int64 bytes_used) {
      last_error_ = error;
      quota_bytes_total_ = bytes_total;
      quota_bytes_used_ = bytes_used;
    }

    virtual void OpenFileCallback(DriveFileError error,
                                  const FilePath& file_path) {
      last_error_ = error;
      opened_file_path_ = file_path;
      MessageLoop::current()->Quit();
    }

    virtual void CloseFileCallback(DriveFileError error) {
      last_error_ = error;
      MessageLoop::current()->Quit();
    }

    virtual void GetEntryInfoCallback(
        DriveFileError error,
        scoped_ptr<DriveEntryProto> entry_proto) {
      last_error_ = error;
      entry_proto_ = entry_proto.Pass();
    }

    virtual void ReadDirectoryCallback(
        DriveFileError error,
        bool /* hide_hosted_documents */,
        scoped_ptr<DriveEntryProtoVector> entries) {
      last_error_ = error;
      directory_entries_ = entries.Pass();
    }

    DriveFileError last_error_;
    FilePath download_path_;
    FilePath opened_file_path_;
    std::string mime_type_;
    DriveFileType file_type_;
    int64 quota_bytes_total_;
    int64 quota_bytes_used_;
    scoped_ptr<DriveEntryProto> entry_proto_;
    scoped_ptr<DriveEntryProtoVector> directory_entries_;

   protected:
    virtual ~CallbackHelper() {}

   private:
    friend class base::RefCountedThreadSafe<CallbackHelper>;
  };

  // Copy the result from FindFirstMissingParentDirectory().
  static void CopyResultFromFindFirstMissingParentDirectory(
      DriveFileSystem::FindFirstMissingParentDirectoryResult* out_result,
      const DriveFileSystem::FindFirstMissingParentDirectoryResult& result) {
    DCHECK(out_result);
    *out_result = result;
  }

  MessageLoopForUI message_loop_;
  // The order of the test threads is important, do not change the order.
  // See also content/browser/browser_thread_impl.cc.
  content::TestBrowserThread ui_thread_;
  content::TestBrowserThread io_thread_;
  scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
  scoped_ptr<TestingProfile> profile_;
  scoped_refptr<CallbackHelper> callback_helper_;
  DriveCache* cache_;
  scoped_ptr<StrictMock<MockDriveUploader> > mock_uploader_;
  DriveFileSystem* file_system_;
  StrictMock<MockDriveService>* mock_drive_service_;
  scoped_ptr<StrictMock<MockDriveWebAppsRegistry> > mock_webapps_registry_;
  StrictMock<MockFreeDiskSpaceGetter>* mock_free_disk_space_checker_;
  scoped_ptr<StrictMock<MockDriveCacheObserver> > mock_cache_observer_;
  scoped_ptr<StrictMock<MockDirectoryChangeObserver> > mock_directory_observer_;

  int num_callback_invocations_;
  DriveFileError expected_error_;
  int expected_cache_state_;
  DriveCache::CacheSubDirectoryType expected_sub_dir_type_;
  bool expected_success_;
  bool expect_outgoing_symlink_;
  std::string expected_file_extension_;
  int root_feed_changestamp_;
};

void AsyncInitializationCallback(
    int* counter,
    int expected_counter,
    const FilePath& expected_file_path,
    MessageLoop* message_loop,
    DriveFileError error,
    scoped_ptr<DriveEntryProto> entry_proto) {
  ASSERT_EQ(DRIVE_FILE_OK, error);
  ASSERT_TRUE(entry_proto.get());
  ASSERT_TRUE(entry_proto->file_info().is_directory());
  EXPECT_EQ(expected_file_path.value(), entry_proto->base_name());

  (*counter)++;
  if (*counter >= expected_counter)
    message_loop->Quit();
}

TEST_F(DriveFileSystemTest, DuplicatedAsyncInitialization) {
  int counter = 0;
  GetEntryInfoCallback callback = base::Bind(
      &AsyncInitializationCallback,
      &counter,
      2,
      FilePath(FILE_PATH_LITERAL("drive")),
      &message_loop_);

  EXPECT_CALL(*mock_drive_service_, GetAccountMetadata(_)).Times(1);
  EXPECT_CALL(*mock_drive_service_,
              GetDocuments(Eq(GURL()), _, _, _, _)).Times(1);

  EXPECT_CALL(*mock_webapps_registry_, UpdateFromFeed(_)).Times(1);

  file_system_->GetEntryInfoByPath(
      FilePath(FILE_PATH_LITERAL("drive")), callback);
  file_system_->GetEntryInfoByPath(
      FilePath(FILE_PATH_LITERAL("drive")), callback);
  message_loop_.Run();  // Wait to get our result
  EXPECT_EQ(2, counter);
}

TEST_F(DriveFileSystemTest, SearchRootDirectory) {
  LoadRootFeedDocument("gdata/root_feed.json");

  const FilePath kFilePath = FilePath(FILE_PATH_LITERAL("drive"));
  scoped_ptr<DriveEntryProto> entry = GetEntryInfoByPathSync(
      FilePath(FILE_PATH_LITERAL(kFilePath)));
  ASSERT_TRUE(entry.get());
  EXPECT_EQ(kDriveRootDirectoryResourceId, entry->resource_id());
}

TEST_F(DriveFileSystemTest, SearchExistingFile) {
  LoadRootFeedDocument("gdata/root_feed.json");

  const FilePath kFilePath = FilePath(
      FILE_PATH_LITERAL("drive/File 1.txt"));
  scoped_ptr<DriveEntryProto> entry = GetEntryInfoByPathSync(kFilePath);
  ASSERT_TRUE(entry.get());
  EXPECT_EQ("file:2_file_resource_id", entry->resource_id());
}

TEST_F(DriveFileSystemTest, SearchExistingDocument) {
  LoadRootFeedDocument("gdata/root_feed.json");

  const FilePath kFilePath = FilePath(
      FILE_PATH_LITERAL("drive/Document 1.gdoc"));
  scoped_ptr<DriveEntryProto> entry = GetEntryInfoByPathSync(kFilePath);
  ASSERT_TRUE(entry.get());
  EXPECT_EQ("document:5_document_resource_id", entry->resource_id());
}

TEST_F(DriveFileSystemTest, SearchNonExistingFile) {
  LoadRootFeedDocument("gdata/root_feed.json");

  const FilePath kFilePath = FilePath(
      FILE_PATH_LITERAL("drive/nonexisting.file"));
  scoped_ptr<DriveEntryProto> entry = GetEntryInfoByPathSync(kFilePath);
  ASSERT_FALSE(entry.get());
}

TEST_F(DriveFileSystemTest, SearchEncodedFileNames) {
  LoadRootFeedDocument("gdata/root_feed.json");

  const FilePath kFilePath1 = FilePath(
      FILE_PATH_LITERAL("drive/Slash / in file 1.txt"));
  scoped_ptr<DriveEntryProto> entry = GetEntryInfoByPathSync(kFilePath1);
  ASSERT_FALSE(entry.get());

  const FilePath kFilePath2 = FilePath::FromUTF8Unsafe(
      "drive/Slash \xE2\x88\x95 in file 1.txt");
  entry = GetEntryInfoByPathSync(kFilePath2);
  ASSERT_TRUE(entry.get());
  EXPECT_EQ("file:slash_file_resource_id", entry->resource_id());

  const FilePath kFilePath3 = FilePath::FromUTF8Unsafe(
      "drive/Slash \xE2\x88\x95 in directory/Slash SubDir File.txt");
  entry = GetEntryInfoByPathSync(kFilePath3);
  ASSERT_TRUE(entry.get());
  EXPECT_EQ("file:slash_subdir_file", entry->resource_id());
}

TEST_F(DriveFileSystemTest, SearchEncodedFileNamesLoadingRoot) {
  LoadRootFeedDocument("gdata/root_feed.json");

  const FilePath kFilePath1 = FilePath(
      FILE_PATH_LITERAL("drive/Slash / in file 1.txt"));
  scoped_ptr<DriveEntryProto> entry = GetEntryInfoByPathSync(kFilePath1);
  ASSERT_FALSE(entry.get());

  const FilePath kFilePath2 = FilePath::FromUTF8Unsafe(
      "drive/Slash \xE2\x88\x95 in file 1.txt");
  entry = GetEntryInfoByPathSync(kFilePath2);
  ASSERT_TRUE(entry.get());
  EXPECT_EQ("file:slash_file_resource_id", entry->resource_id());

  const FilePath kFilePath3 = FilePath::FromUTF8Unsafe(
      "drive/Slash \xE2\x88\x95 in directory/Slash SubDir File.txt");
  entry = GetEntryInfoByPathSync(kFilePath3);
  ASSERT_TRUE(entry.get());
  EXPECT_EQ("file:slash_subdir_file", entry->resource_id());
}

TEST_F(DriveFileSystemTest, SearchDuplicateNames) {
  LoadRootFeedDocument("gdata/root_feed.json");

  const FilePath kFilePath1 = FilePath(
      FILE_PATH_LITERAL("drive/Duplicate Name.txt"));
  scoped_ptr<DriveEntryProto> entry = GetEntryInfoByPathSync(kFilePath1);
  ASSERT_TRUE(entry.get());
  EXPECT_EQ("file:3_file_resource_id", entry->resource_id());

  const FilePath kFilePath2 = FilePath(
      FILE_PATH_LITERAL("drive/Duplicate Name (2).txt"));
  entry = GetEntryInfoByPathSync(kFilePath2);
  ASSERT_TRUE(entry.get());
  EXPECT_EQ("file:4_file_resource_id", entry->resource_id());
}

TEST_F(DriveFileSystemTest, SearchExistingDirectory) {
  LoadRootFeedDocument("gdata/root_feed.json");

  const FilePath kFilePath = FilePath(
      FILE_PATH_LITERAL("drive/Directory 1"));
  scoped_ptr<DriveEntryProto> entry = GetEntryInfoByPathSync(kFilePath);
  ASSERT_TRUE(entry.get());
  ASSERT_EQ("folder:1_folder_resource_id", entry->resource_id());
}

TEST_F(DriveFileSystemTest, SearchInSubdir) {
  LoadRootFeedDocument("gdata/root_feed.json");

  const FilePath kFilePath = FilePath(
      FILE_PATH_LITERAL("drive/Directory 1/SubDirectory File 1.txt"));
  scoped_ptr<DriveEntryProto> entry = GetEntryInfoByPathSync(kFilePath);
  ASSERT_TRUE(entry.get());
  ASSERT_EQ("file:subdirectory_file_1_id", entry->resource_id());
}

// Check the reconstruction of the directory structure from only the root feed.
TEST_F(DriveFileSystemTest, SearchInSubSubdir) {
  LoadRootFeedDocument("gdata/root_feed.json");

  const FilePath kFilePath = FilePath(
      FILE_PATH_LITERAL("drive/Directory 1/Sub Directory Folder/"
                        "Sub Sub Directory Folder"));
  scoped_ptr<DriveEntryProto> entry = GetEntryInfoByPathSync(kFilePath);
  ASSERT_TRUE(entry.get());
  ASSERT_EQ("folder:sub_sub_directory_folder_id", entry->resource_id());
}

TEST_F(DriveFileSystemTest, FilePathTests) {
  LoadRootFeedDocument("gdata/root_feed.json");

  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL("drive/File 1.txt"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL("drive/Directory 1"))));
  EXPECT_TRUE(EntryExists(
      FilePath(
          FILE_PATH_LITERAL("drive/Directory 1/SubDirectory File 1.txt"))));
}

TEST_F(DriveFileSystemTest, ChangeFeed_AddAndDeleteFileInRoot) {
  int latest_changelog = 0;
  LoadRootFeedDocument("gdata/root_feed.json");

  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive"))))).Times(2);

  LoadChangeFeed("gdata/delta_file_added_in_root.json", ++latest_changelog);
  EXPECT_TRUE(
      EntryExists(FilePath(FILE_PATH_LITERAL("drive/Added file.gdoc"))));

  LoadChangeFeed("gdata/delta_file_deleted_in_root.json", ++latest_changelog);
  EXPECT_FALSE(
      EntryExists(FilePath(FILE_PATH_LITERAL("drive/Added file.gdoc"))));
}


TEST_F(DriveFileSystemTest, ChangeFeed_AddAndDeleteFileFromExistingDirectory) {
  int latest_changelog = 0;
  LoadRootFeedDocument("gdata/root_feed.json");

  EXPECT_TRUE(EntryExists(FilePath(
      FILE_PATH_LITERAL("drive/Directory 1"))));

  // Add file to an existing directory.
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive"))))).Times(1);
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive/Directory 1"))))).Times(1);
  LoadChangeFeed("gdata/delta_file_added_in_directory.json",
                 ++latest_changelog);
  EXPECT_TRUE(EntryExists(FilePath(
      FILE_PATH_LITERAL("drive/Directory 1/Added file.gdoc"))));

  // Remove that file from the directory.
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive/Directory 1"))))).Times(1);
  LoadChangeFeed("gdata/delta_file_deleted_in_directory.json",
                 ++latest_changelog);
  EXPECT_TRUE(EntryExists(FilePath(
      FILE_PATH_LITERAL("drive/Directory 1"))));
  EXPECT_FALSE(EntryExists(FilePath(
      FILE_PATH_LITERAL("drive/Directory 1/Added file.gdoc"))));
}

TEST_F(DriveFileSystemTest, ChangeFeed_AddFileToNewDirectory) {
  int latest_changelog = 0;
  LoadRootFeedDocument("gdata/root_feed.json");
  // Add file to a new directory.
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive"))))).Times(1);
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive/New Directory"))))).Times(1);

  LoadChangeFeed("gdata/delta_file_added_in_new_directory.json",
                 ++latest_changelog);

  EXPECT_TRUE(EntryExists(FilePath(
      FILE_PATH_LITERAL("drive/New Directory"))));
  EXPECT_TRUE(EntryExists(FilePath(
      FILE_PATH_LITERAL("drive/New Directory/File in new dir.gdoc"))));
}

TEST_F(DriveFileSystemTest, ChangeFeed_AddFileToNewButDeletedDirectory) {
  int latest_changelog = 0;
  LoadRootFeedDocument("gdata/root_feed.json");

  // This feed contains thw 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.
  LoadChangeFeed("gdata/delta_file_added_in_new_but_deleted_directory.json",
                 ++latest_changelog);
}

TEST_F(DriveFileSystemTest, ChangeFeed_DirectoryMovedFromRootToDirectory) {
  int latest_changelog = 0;
  LoadRootFeedDocument("gdata/root_feed.json");

  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 2"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1/SubDirectory File 1.txt"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1/Sub Directory Folder"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1/Sub Directory Folder/Sub Sub Directory Folder"))));

  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive"))))).Times(1);
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive/Directory 2"))))).Times(1);
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive/Directory 2/Directory 1")))))
      .Times(1);
  LoadChangeFeed("gdata/delta_dir_moved_from_root_to_directory.json",
                 ++latest_changelog);

  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 2"))));
  EXPECT_FALSE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 2/Directory 1"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 2/Directory 1/SubDirectory File 1.txt"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 2/Directory 1/Sub Directory Folder"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 2/Directory 1/Sub Directory Folder/"
      "Sub Sub Directory Folder"))));
}

TEST_F(DriveFileSystemTest, ChangeFeed_FileMovedFromDirectoryToRoot) {
  int latest_changelog = 0;
  LoadRootFeedDocument("gdata/root_feed.json");

  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1/Sub Directory Folder"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1/Sub Directory Folder/Sub Sub Directory Folder"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1/SubDirectory File 1.txt"))));

  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive"))))).Times(1);
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive/Directory 1"))))).Times(1);
  LoadChangeFeed("gdata/delta_file_moved_from_directory_to_root.json",
                 ++latest_changelog);

  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1/Sub Directory Folder"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1/Sub Directory Folder/Sub Sub Directory Folder"))));
  EXPECT_FALSE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1/SubDirectory File 1.txt"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/SubDirectory File 1.txt"))));
}

TEST_F(DriveFileSystemTest, ChangeFeed_FileRenamedInDirectory) {
  int latest_changelog = 0;
  LoadRootFeedDocument("gdata/root_feed.json");

  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1/SubDirectory File 1.txt"))));

  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive"))))).Times(1);
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive/Directory 1"))))).Times(1);
  LoadChangeFeed("gdata/delta_file_renamed_in_directory.json",
                 ++latest_changelog);

  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1"))));
  EXPECT_FALSE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1/SubDirectory File 1.txt"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL(
      "drive/Directory 1/New SubDirectory File 1.txt"))));
}

TEST_F(DriveFileSystemTest, CachedFeedLoading) {
  SaveTestFileSystem();
  TestLoadMetadataFromCache();

  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL("drive/File1"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL("drive/Dir1"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL("drive/Dir1/File2"))));
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL("drive/Dir1/SubDir2"))));
  EXPECT_TRUE(EntryExists(
      FilePath(FILE_PATH_LITERAL("drive/Dir1/SubDir2/File3"))));
}

TEST_F(DriveFileSystemTest, CachedFeadLoadingThenServerFeedLoading) {
  SaveTestFileSystem();

  // SaveTestFileSystem and "account_metadata.json" have the same changestamp,
  // so no request for new feeds (i.e., call to GetDocuments) should happen.
  mock_drive_service_->set_account_metadata(
      test_util::LoadJSONFile("gdata/account_metadata.json").release());
  EXPECT_CALL(*mock_drive_service_, GetAccountMetadata(_)).Times(1);
  EXPECT_CALL(*mock_webapps_registry_, UpdateFromFeed(_)).Times(1);
  EXPECT_CALL(*mock_drive_service_, GetDocuments(_, _, _, _, _)).Times(0);

  // Kicks loading of cached file system and query for server update.
  EXPECT_TRUE(EntryExists(FilePath(FILE_PATH_LITERAL("drive/File1"))));

  // Since the file system has verified that it holds the latest snapshot,
  // it should change its state to FROM_SERVER, which admits periodic refresh.
  // To test it, call CheckForUpdates and verify it does try to check updates.
  mock_drive_service_->set_account_metadata(
      test_util::LoadJSONFile("gdata/account_metadata.json").release());
  EXPECT_CALL(*mock_drive_service_, GetAccountMetadata(_)).Times(1);
  EXPECT_CALL(*mock_webapps_registry_, UpdateFromFeed(_)).Times(1);

  file_system_->CheckForUpdates();
  test_util::RunBlockingPoolTask();
}

TEST_F(DriveFileSystemTest, TransferFileFromLocalToRemote_RegularFile) {
  EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
      .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));

  LoadRootFeedDocument("gdata/root_feed.json");

  // We'll add a file to the Drive root directory.
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive"))))).Times(1);

  FileOperationCallback callback =
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get());

  // Prepare a local file.
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  const FilePath local_src_file_path = temp_dir.path().Append("local.txt");
  const std::string kContent = "hello";
  file_util::WriteFile(local_src_file_path, kContent.data(), kContent.size());

  // Confirm that the remote file does not exist.
  const FilePath remote_dest_file_path(FILE_PATH_LITERAL("drive/remote.txt"));
  EXPECT_FALSE(EntryExists(remote_dest_file_path));

  scoped_ptr<base::Value> value =
      test_util::LoadJSONFile("gdata/document_to_download.json");
  scoped_ptr<DocumentEntry> document_entry(
      DocumentEntry::ExtractAndParse(*value));

  EXPECT_CALL(*mock_uploader_, UploadNewFile(_, _, _, _, _, _, _, _, _))
      .WillOnce(MockUploadNewFile());

  // Transfer the local file to Drive.
  file_system_->TransferFileFromLocalToRemote(
      local_src_file_path, remote_dest_file_path, callback);
  test_util::RunBlockingPoolTask();

  EXPECT_EQ(DRIVE_FILE_OK, callback_helper_->last_error_);

  // Now the remote file should exist.
  EXPECT_TRUE(EntryExists(remote_dest_file_path));
}

TEST_F(DriveFileSystemTest, TransferFileFromLocalToRemote_HostedDocument) {
  LoadRootFeedDocument("gdata/root_feed.json");

  // Prepare a local file, which is a json file of a hosted document, which
  // matches "Document 1" in root_feed.json.
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  const FilePath local_src_file_path = temp_dir.path().Append("local.gdoc");
  const std::string kEditUrl =
      "https://3_document_self_link/document:5_document_resource_id";
  const std::string kResourceId = "document:5_document_resource_id";
  const std::string kContent =
      base::StringPrintf("{\"url\": \"%s\", \"resource_id\": \"%s\"}",
                         kEditUrl.c_str(), kResourceId.c_str());
  file_util::WriteFile(local_src_file_path, kContent.data(), kContent.size());

  // Confirm that the remote file does not exist.
  const FilePath remote_dest_file_path(
      FILE_PATH_LITERAL("drive/Directory 1/Document 1.gdoc"));
  EXPECT_FALSE(EntryExists(remote_dest_file_path));

  // We'll add a file to "Directory 1" directory on Drive.
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive/Directory 1"))))).Times(1);

  // We'll copy a hosted document using CopyDocument.
  // ".gdoc" suffix should be stripped when copying.
  scoped_ptr<base::Value> document =
      test_util::LoadJSONFile("gdata/uploaded_document.json");
  EXPECT_CALL(*mock_drive_service_,
              CopyDocument(kResourceId,
                           FILE_PATH_LITERAL("Document 1"),
                           _))
      .WillOnce(MockCopyDocument(gdata::HTTP_SUCCESS, &document));
  // We'll then add the hosted document to the destination directory.
  EXPECT_CALL(*mock_drive_service_,
              AddResourceToDirectory(_, _, _)).Times(1);

  FileOperationCallback callback =
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get());

  // Transfer the local file to Drive.
  file_system_->TransferFileFromLocalToRemote(
      local_src_file_path, remote_dest_file_path, callback);
  test_util::RunBlockingPoolTask();

  EXPECT_EQ(DRIVE_FILE_OK, callback_helper_->last_error_);

  // Now the remote file should exist.
  EXPECT_TRUE(EntryExists(remote_dest_file_path));
}

TEST_F(DriveFileSystemTest, TransferFileFromRemoteToLocal_RegularFile) {
  LoadRootFeedDocument("gdata/root_feed.json");

  FileOperationCallback callback =
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get());

  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  FilePath local_dest_file_path = temp_dir.path().Append("local_copy.txt");

  FilePath remote_src_file_path(FILE_PATH_LITERAL("drive/File 1.txt"));
  scoped_ptr<DriveEntryProto> file = GetEntryInfoByPathSync(
      remote_src_file_path);
  FilePath cache_file = GetCachePathForFile(
      file->resource_id(),
      file->file_specific_info().file_md5());
  const int64 file_size = file->file_info().size();

  // Pretend we have enough space.
  EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
      .Times(2).WillRepeatedly(Return(file_size + kMinFreeSpace));

  const std::string remote_src_file_data = "Test file data";
  mock_drive_service_->set_file_data(new std::string(remote_src_file_data));

  // Before Download starts metadata from server will be fetched.
  // We will read content url from the result.
  scoped_ptr<base::Value> document =
      test_util::LoadJSONFile("gdata/document_to_download.json");
  SetExpectationsForGetDocumentEntry(&document, "file:2_file_resource_id");

  // The file is obtained with the mock DriveService.
  EXPECT_CALL(*mock_drive_service_,
              DownloadFile(remote_src_file_path,
                           cache_file,
                           GURL("https://file_content_url_changed/"),
                           _, _))
      .Times(1);

  file_system_->TransferFileFromRemoteToLocal(
      remote_src_file_path, local_dest_file_path, callback);
  test_util::RunBlockingPoolTask();

  EXPECT_EQ(DRIVE_FILE_OK, callback_helper_->last_error_);

  std::string cache_file_data;
  EXPECT_TRUE(file_util::ReadFileToString(cache_file, &cache_file_data));
  EXPECT_EQ(remote_src_file_data, cache_file_data);

  std::string local_dest_file_data;
  EXPECT_TRUE(file_util::ReadFileToString(local_dest_file_path,
                                          &local_dest_file_data));
  EXPECT_EQ(remote_src_file_data, local_dest_file_data);
}

TEST_F(DriveFileSystemTest, TransferFileFromRemoteToLocal_HostedDocument) {
  LoadRootFeedDocument("gdata/root_feed.json");

  FileOperationCallback callback =
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get());

  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  FilePath local_dest_file_path = temp_dir.path().Append("local_copy.txt");
  FilePath remote_src_file_path(FILE_PATH_LITERAL("drive/Document 1.gdoc"));
  file_system_->TransferFileFromRemoteToLocal(
      remote_src_file_path, local_dest_file_path, callback);
  test_util::RunBlockingPoolTask();

  EXPECT_EQ(DRIVE_FILE_OK, callback_helper_->last_error_);

  scoped_ptr<DriveEntryProto> entry_proto = GetEntryInfoByPathSync(
      remote_src_file_path);
  ASSERT_TRUE(entry_proto.get());
  VerifyHostedDocumentJSONFile(*entry_proto, local_dest_file_path);
}

TEST_F(DriveFileSystemTest, CopyNotExistingFile) {
  FilePath src_file_path(FILE_PATH_LITERAL("drive/Dummy file.txt"));
  FilePath dest_file_path(FILE_PATH_LITERAL("drive/Test.log"));

  LoadRootFeedDocument("gdata/root_feed.json");

  EXPECT_FALSE(EntryExists(src_file_path));

  FileOperationCallback callback =
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get());

  file_system_->Copy(src_file_path, dest_file_path, callback);
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(DRIVE_FILE_ERROR_NOT_FOUND, callback_helper_->last_error_);

  EXPECT_FALSE(EntryExists(src_file_path));
  EXPECT_FALSE(EntryExists(dest_file_path));
}

TEST_F(DriveFileSystemTest, CopyFileToNonExistingDirectory) {
  FilePath src_file_path(FILE_PATH_LITERAL("drive/File 1.txt"));
  FilePath dest_parent_path(FILE_PATH_LITERAL("drive/Dummy"));
  FilePath dest_file_path(FILE_PATH_LITERAL("drive/Dummy/Test.log"));

  LoadRootFeedDocument("gdata/root_feed.json");

  ASSERT_TRUE(EntryExists(src_file_path));
  scoped_ptr<DriveEntryProto> src_entry_proto = GetEntryInfoByPathSync(
      src_file_path);
  ASSERT_TRUE(src_entry_proto.get());
  std::string src_file_path_resource_id =
      src_entry_proto->resource_id();
  EXPECT_FALSE(src_entry_proto->edit_url().empty());

  EXPECT_FALSE(EntryExists(dest_parent_path));

  FileOperationCallback callback =
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get());

  file_system_->Move(src_file_path, dest_file_path, callback);
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(DRIVE_FILE_ERROR_NOT_FOUND, callback_helper_->last_error_);

  EXPECT_TRUE(EntryExists(src_file_path));
  EXPECT_FALSE(EntryExists(dest_parent_path));
  EXPECT_FALSE(EntryExists(dest_file_path));
}

// Test the case where the parent of |dest_file_path| is an existing file,
// not a directory.
TEST_F(DriveFileSystemTest, CopyFileToInvalidPath) {
  FilePath src_file_path(FILE_PATH_LITERAL("drive/Document 1.gdoc"));
  FilePath dest_parent_path(FILE_PATH_LITERAL("drive/Duplicate Name.txt"));
  FilePath dest_file_path(FILE_PATH_LITERAL(
      "drive/Duplicate Name.txt/Document 1.gdoc"));

  LoadRootFeedDocument("gdata/root_feed.json");

  ASSERT_TRUE(EntryExists(src_file_path));
  scoped_ptr<DriveEntryProto> src_entry_proto = GetEntryInfoByPathSync(
      src_file_path);
  ASSERT_TRUE(src_entry_proto.get());
  std::string src_file_resource_id =
      src_entry_proto->resource_id();
  EXPECT_FALSE(src_entry_proto->edit_url().empty());

  ASSERT_TRUE(EntryExists(dest_parent_path));
  scoped_ptr<DriveEntryProto> dest_entry_proto = GetEntryInfoByPathSync(
      dest_parent_path);
  ASSERT_TRUE(dest_entry_proto.get());

  FileOperationCallback callback =
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get());

  file_system_->Copy(src_file_path, dest_file_path, callback);
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(DRIVE_FILE_ERROR_NOT_A_DIRECTORY,
            callback_helper_->last_error_);

  EXPECT_TRUE(EntryExists(src_file_path));
  EXPECT_TRUE(EntryExists(src_file_path));
  EXPECT_TRUE(EntryExists(dest_parent_path));

  EXPECT_FALSE(EntryExists(dest_file_path));
}

TEST_F(DriveFileSystemTest, RenameFile) {
  const FilePath src_file_path(
      FILE_PATH_LITERAL("drive/Directory 1/SubDirectory File 1.txt"));
  const FilePath src_parent_path(FILE_PATH_LITERAL("drive/Directory 1"));
  const FilePath dest_file_path(
      FILE_PATH_LITERAL("drive/Directory 1/Test.log"));

  LoadRootFeedDocument("gdata/root_feed.json");

  ASSERT_TRUE(EntryExists(src_file_path));
  scoped_ptr<DriveEntryProto> src_entry_proto = GetEntryInfoByPathSync(
      src_file_path);
  ASSERT_TRUE(src_entry_proto.get());
  std::string src_file_resource_id =
      src_entry_proto->resource_id();

  EXPECT_CALL(*mock_drive_service_,
              RenameResource(GURL(src_entry_proto->edit_url()),
                             FILE_PATH_LITERAL("Test.log"), _));

  FileOperationCallback callback =
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get());

  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive/Directory 1"))))).Times(1);

  file_system_->Move(src_file_path, dest_file_path, callback);
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(DRIVE_FILE_OK, callback_helper_->last_error_);

  EXPECT_FALSE(EntryExists(src_file_path));
  EXPECT_TRUE(EntryExists(dest_file_path));
  EXPECT_EQ(src_file_resource_id, GetResourceIdByPath(dest_file_path));
}

TEST_F(DriveFileSystemTest, MoveFileFromRootToSubDirectory) {
  FilePath src_file_path(FILE_PATH_LITERAL("drive/File 1.txt"));
  FilePath dest_parent_path(FILE_PATH_LITERAL("drive/Directory 1"));
  FilePath dest_file_path(FILE_PATH_LITERAL("drive/Directory 1/Test.log"));

  LoadRootFeedDocument("gdata/root_feed.json");

  ASSERT_TRUE(EntryExists(src_file_path));
  scoped_ptr<DriveEntryProto> src_entry_proto = GetEntryInfoByPathSync(
      src_file_path);
  ASSERT_TRUE(src_entry_proto.get());
  std::string src_file_resource_id =
      src_entry_proto->resource_id();
  EXPECT_FALSE(src_entry_proto->edit_url().empty());

  ASSERT_TRUE(EntryExists(dest_parent_path));
  scoped_ptr<DriveEntryProto> dest_parent_proto = GetEntryInfoByPathSync(
      dest_parent_path);
  ASSERT_TRUE(dest_parent_proto.get());
  ASSERT_TRUE(dest_parent_proto->file_info().is_directory());
  EXPECT_FALSE(dest_parent_proto->content_url().empty());

  EXPECT_CALL(*mock_drive_service_,
              RenameResource(GURL(src_entry_proto->edit_url()),
                             FILE_PATH_LITERAL("Test.log"), _));
  EXPECT_CALL(*mock_drive_service_,
              AddResourceToDirectory(
                  GURL(dest_parent_proto->content_url()),
                  GURL(src_entry_proto->edit_url()), _));

  FileOperationCallback callback =
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get());

  // Expect notification for both source and destination directories.
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive"))))).Times(1);
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive/Directory 1"))))).Times(1);

  file_system_->Move(src_file_path, dest_file_path, callback);
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(DRIVE_FILE_OK, callback_helper_->last_error_);

  EXPECT_FALSE(EntryExists(src_file_path));
  EXPECT_TRUE(EntryExists(dest_file_path));
  EXPECT_EQ(src_file_resource_id, GetResourceIdByPath(dest_file_path));
}

TEST_F(DriveFileSystemTest, MoveFileFromSubDirectoryToRoot) {
  FilePath src_parent_path(FILE_PATH_LITERAL("drive/Directory 1"));
  FilePath src_file_path(
      FILE_PATH_LITERAL("drive/Directory 1/SubDirectory File 1.txt"));
  FilePath dest_file_path(FILE_PATH_LITERAL("drive/Test.log"));

  LoadRootFeedDocument("gdata/root_feed.json");

  ASSERT_TRUE(EntryExists(src_file_path));
  scoped_ptr<DriveEntryProto> src_entry_proto = GetEntryInfoByPathSync(
      src_file_path);
  ASSERT_TRUE(src_entry_proto.get());
  std::string src_file_resource_id =
      src_entry_proto->resource_id();
  EXPECT_FALSE(src_entry_proto->edit_url().empty());

  ASSERT_TRUE(EntryExists(src_parent_path));
  scoped_ptr<DriveEntryProto> src_parent_proto = GetEntryInfoByPathSync(
      src_parent_path);
  ASSERT_TRUE(src_parent_proto.get());
  ASSERT_TRUE(src_parent_proto->file_info().is_directory());
  EXPECT_FALSE(src_parent_proto->content_url().empty());

  EXPECT_CALL(*mock_drive_service_,
              RenameResource(GURL(src_entry_proto->edit_url()),
                             FILE_PATH_LITERAL("Test.log"), _));
  EXPECT_CALL(*mock_drive_service_,
              RemoveResourceFromDirectory(
                  GURL(src_parent_proto->content_url()),
                  GURL(src_entry_proto->edit_url()),
                  src_file_resource_id, _));

  FileOperationCallback callback =
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get());

  // Expect notification for both source and destination directories.
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive"))))).Times(1);
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive/Directory 1"))))).Times(1);

  file_system_->Move(src_file_path, dest_file_path, callback);
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(DRIVE_FILE_OK, callback_helper_->last_error_);

  EXPECT_FALSE(EntryExists(src_file_path));
  ASSERT_TRUE(EntryExists(dest_file_path));
  EXPECT_EQ(src_file_resource_id, GetResourceIdByPath(dest_file_path));
}

TEST_F(DriveFileSystemTest, MoveFileBetweenSubDirectories) {
  FilePath src_parent_path(FILE_PATH_LITERAL("drive/Directory 1"));
  FilePath src_file_path(
      FILE_PATH_LITERAL("drive/Directory 1/SubDirectory File 1.txt"));
  FilePath dest_parent_path(FILE_PATH_LITERAL("drive/New Folder 1"));
  FilePath dest_file_path(FILE_PATH_LITERAL("drive/New Folder 1/Test.log"));
  FilePath interim_file_path(FILE_PATH_LITERAL("drive/Test.log"));

  LoadRootFeedDocument("gdata/root_feed.json");

  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive"))))).Times(1);

  AddDirectoryFromFile(dest_parent_path, "gdata/directory_entry_atom.json");

  ASSERT_TRUE(EntryExists(src_file_path));
  scoped_ptr<DriveEntryProto> src_entry_proto = GetEntryInfoByPathSync(
      src_file_path);
  ASSERT_TRUE(src_entry_proto.get());
  std::string src_file_resource_id =
      src_entry_proto->resource_id();
  EXPECT_FALSE(src_entry_proto->edit_url().empty());

  ASSERT_TRUE(EntryExists(src_parent_path));
  scoped_ptr<DriveEntryProto> src_parent_proto = GetEntryInfoByPathSync(
      src_parent_path);
  ASSERT_TRUE(src_parent_proto.get());
  ASSERT_TRUE(src_parent_proto->file_info().is_directory());
  EXPECT_FALSE(src_parent_proto->content_url().empty());

  ASSERT_TRUE(EntryExists(dest_parent_path));
  scoped_ptr<DriveEntryProto> dest_parent_proto = GetEntryInfoByPathSync(
      dest_parent_path);
  ASSERT_TRUE(dest_parent_proto.get());
  ASSERT_TRUE(dest_parent_proto->file_info().is_directory());
  EXPECT_FALSE(dest_parent_proto->content_url().empty());

  EXPECT_FALSE(EntryExists(interim_file_path));

  EXPECT_CALL(*mock_drive_service_,
              RenameResource(GURL(src_entry_proto->edit_url()),
                             FILE_PATH_LITERAL("Test.log"), _));
  EXPECT_CALL(*mock_drive_service_,
              RemoveResourceFromDirectory(
                  GURL(src_parent_proto->content_url()),
                  GURL(src_entry_proto->edit_url()),
                  src_file_resource_id, _));
  EXPECT_CALL(*mock_drive_service_,
              AddResourceToDirectory(
                  GURL(dest_parent_proto->content_url()),
                  GURL(src_entry_proto->edit_url()),
                  _));

  FileOperationCallback callback =
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get());

  // Expect notification for both source and destination directories plus
  // interim file path.
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive/Directory 1"))))).Times(1);
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive"))))).Times(1);
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive/New Folder 1"))))).Times(1);

  file_system_->Move(src_file_path, dest_file_path, callback);
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(DRIVE_FILE_OK, callback_helper_->last_error_);

  EXPECT_FALSE(EntryExists(src_file_path));
  EXPECT_FALSE(EntryExists(interim_file_path));

  EXPECT_FALSE(EntryExists(src_file_path));
  EXPECT_TRUE(EntryExists(dest_file_path));
  EXPECT_EQ(src_file_resource_id, GetResourceIdByPath(dest_file_path));
}

TEST_F(DriveFileSystemTest, MoveNotExistingFile) {
  FilePath src_file_path(FILE_PATH_LITERAL("drive/Dummy file.txt"));
  FilePath dest_file_path(FILE_PATH_LITERAL("drive/Test.log"));

  LoadRootFeedDocument("gdata/root_feed.json");

  EXPECT_FALSE(EntryExists(src_file_path));

  FileOperationCallback callback =
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get());

  file_system_->Move(src_file_path, dest_file_path, callback);
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(DRIVE_FILE_ERROR_NOT_FOUND, callback_helper_->last_error_);

  EXPECT_FALSE(EntryExists(src_file_path));
  EXPECT_FALSE(EntryExists(dest_file_path));
}

TEST_F(DriveFileSystemTest, MoveFileToNonExistingDirectory) {
  FilePath src_file_path(FILE_PATH_LITERAL("drive/File 1.txt"));
  FilePath dest_parent_path(FILE_PATH_LITERAL("drive/Dummy"));
  FilePath dest_file_path(FILE_PATH_LITERAL("drive/Dummy/Test.log"));

  LoadRootFeedDocument("gdata/root_feed.json");

  ASSERT_TRUE(EntryExists(src_file_path));
  scoped_ptr<DriveEntryProto> src_entry_proto = GetEntryInfoByPathSync(
      src_file_path);
  ASSERT_TRUE(src_entry_proto.get());
  std::string src_file_resource_id =
      src_entry_proto->resource_id();
  EXPECT_FALSE(src_entry_proto->edit_url().empty());

  EXPECT_FALSE(EntryExists(dest_parent_path));

  FileOperationCallback callback =
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get());

  file_system_->Move(src_file_path, dest_file_path, callback);
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(DRIVE_FILE_ERROR_NOT_FOUND, callback_helper_->last_error_);


  EXPECT_FALSE(EntryExists(dest_parent_path));
  EXPECT_FALSE(EntryExists(dest_file_path));
}

// Test the case where the parent of |dest_file_path| is a existing file,
// not a directory.
TEST_F(DriveFileSystemTest, MoveFileToInvalidPath) {
  FilePath src_file_path(FILE_PATH_LITERAL("drive/File 1.txt"));
  FilePath dest_parent_path(FILE_PATH_LITERAL("drive/Duplicate Name.txt"));
  FilePath dest_file_path(FILE_PATH_LITERAL(
      "drive/Duplicate Name.txt/Test.log"));

  LoadRootFeedDocument("gdata/root_feed.json");

  ASSERT_TRUE(EntryExists(src_file_path));
  scoped_ptr<DriveEntryProto> src_entry_proto = GetEntryInfoByPathSync(
      src_file_path);
  ASSERT_TRUE(src_entry_proto.get());
  std::string src_file_resource_id =
      src_entry_proto->resource_id();
  EXPECT_FALSE(src_entry_proto->edit_url().empty());

  ASSERT_TRUE(EntryExists(dest_parent_path));
  scoped_ptr<DriveEntryProto> dest_parent_proto = GetEntryInfoByPathSync(
      dest_parent_path);
  ASSERT_TRUE(dest_parent_proto.get());

  FileOperationCallback callback =
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get());

  file_system_->Move(src_file_path, dest_file_path, callback);
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(DRIVE_FILE_ERROR_NOT_A_DIRECTORY,
            callback_helper_->last_error_);

  EXPECT_TRUE(EntryExists(src_file_path));
  EXPECT_TRUE(EntryExists(dest_parent_path));
  EXPECT_FALSE(EntryExists(dest_file_path));
}

TEST_F(DriveFileSystemTest, RemoveEntries) {
  LoadRootFeedDocument("gdata/root_feed.json");

  FilePath nonexisting_file(FILE_PATH_LITERAL("drive/Dummy file.txt"));
  FilePath file_in_root(FILE_PATH_LITERAL("drive/File 1.txt"));
  FilePath dir_in_root(FILE_PATH_LITERAL("drive/Directory 1"));
  FilePath file_in_subdir(
      FILE_PATH_LITERAL("drive/Directory 1/SubDirectory File 1.txt"));

  ASSERT_TRUE(EntryExists(file_in_root));
  scoped_ptr<DriveEntryProto> file_in_root_proto = GetEntryInfoByPathSync(
      file_in_root);
  ASSERT_TRUE(file_in_root_proto.get());

  ASSERT_TRUE(EntryExists(dir_in_root));
  scoped_ptr<DriveEntryProto> dir_in_root_proto = GetEntryInfoByPathSync(
      dir_in_root);
  ASSERT_TRUE(dir_in_root_proto.get());
  ASSERT_TRUE(dir_in_root_proto->file_info().is_directory());

  ASSERT_TRUE(EntryExists(file_in_subdir));
  scoped_ptr<DriveEntryProto> file_in_subdir_proto = GetEntryInfoByPathSync(
      file_in_subdir);
  ASSERT_TRUE(file_in_subdir_proto.get());

  // Once for file in root and once for file...
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive"))))).Times(2);

  // Remove first file in root.
  EXPECT_TRUE(RemoveEntry(file_in_root));
  EXPECT_FALSE(EntryExists(file_in_root));
  EXPECT_TRUE(EntryExists(dir_in_root));
  EXPECT_TRUE(EntryExists(file_in_subdir));

  // Remove directory.
  EXPECT_TRUE(RemoveEntry(dir_in_root));
  EXPECT_FALSE(EntryExists(file_in_root));
  EXPECT_FALSE(EntryExists(dir_in_root));
  EXPECT_FALSE(EntryExists(file_in_subdir));

  // Try removing file in already removed subdirectory.
  EXPECT_FALSE(RemoveEntry(file_in_subdir));

  // Try removing non-existing file.
  EXPECT_FALSE(RemoveEntry(nonexisting_file));

  // Try removing root file element.
  EXPECT_FALSE(RemoveEntry(FilePath(FILE_PATH_LITERAL("drive"))));

  // Need this to ensure OnDirectoryChanged() is run.
  test_util::RunBlockingPoolTask();
}

TEST_F(DriveFileSystemTest, CreateDirectory) {
  LoadRootFeedDocument("gdata/root_feed.json");

  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive"))))).Times(1);

  // Create directory in root.
  FilePath dir_path(FILE_PATH_LITERAL("drive/New Folder 1"));
  EXPECT_FALSE(EntryExists(dir_path));
  AddDirectoryFromFile(dir_path, "gdata/directory_entry_atom.json");
  EXPECT_TRUE(EntryExists(dir_path));

  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive/New Folder 1"))))).Times(1);

  // Create directory in a sub directory.
  FilePath subdir_path(FILE_PATH_LITERAL("drive/New Folder 1/New Folder 2"));
  EXPECT_FALSE(EntryExists(subdir_path));
  AddDirectoryFromFile(subdir_path, "gdata/directory_entry_atom2.json");
  EXPECT_TRUE(EntryExists(subdir_path));
}

TEST_F(DriveFileSystemTest, FindFirstMissingParentDirectory) {
  LoadRootFeedDocument("gdata/root_feed.json");

  DriveFileSystem::FindFirstMissingParentDirectoryResult result;

  // Create directory in root.
  FilePath dir_path(FILE_PATH_LITERAL("drive/New Folder 1"));
  file_system_->FindFirstMissingParentDirectory(
      dir_path,
      base::Bind(&CopyResultFromFindFirstMissingParentDirectory,
                 &result));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(DriveFileSystem::FIND_FIRST_FOUND_MISSING, result.error);
  EXPECT_EQ(FilePath(FILE_PATH_LITERAL("drive/New Folder 1")),
            result.first_missing_parent_path);
  EXPECT_TRUE(result.last_dir_content_url.is_empty());  // root directory.

  // Missing folders in subdir of an existing folder.
  FilePath dir_path2(FILE_PATH_LITERAL("drive/Directory 1/New Folder 2"));
  file_system_->FindFirstMissingParentDirectory(
      dir_path2,
      base::Bind(&CopyResultFromFindFirstMissingParentDirectory,
                 &result));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(DriveFileSystem::FIND_FIRST_FOUND_MISSING, result.error);
  EXPECT_EQ(FilePath(FILE_PATH_LITERAL("drive/Directory 1/New Folder 2")),
            result.first_missing_parent_path);
  EXPECT_FALSE(result.last_dir_content_url.is_empty());  // non-root dir.

  // Missing two folders on the path.
  FilePath dir_path3 = dir_path2.Append(FILE_PATH_LITERAL("Another Folder"));
  file_system_->FindFirstMissingParentDirectory(
      dir_path3,
      base::Bind(&CopyResultFromFindFirstMissingParentDirectory,
                 &result));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(DriveFileSystem::FIND_FIRST_FOUND_MISSING, result.error);
  EXPECT_EQ(FilePath(FILE_PATH_LITERAL("drive/Directory 1/New Folder 2")),
            result.first_missing_parent_path);
  EXPECT_FALSE(result.last_dir_content_url.is_empty());  // non-root dir.

  // Folders on top of an existing file.
  file_system_->FindFirstMissingParentDirectory(
      FilePath(FILE_PATH_LITERAL("drive/File 1.txt/BadDir")),
      base::Bind(&CopyResultFromFindFirstMissingParentDirectory,
                 &result));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(DriveFileSystem::FIND_FIRST_FOUND_INVALID, result.error);

  // Existing folder.
  file_system_->FindFirstMissingParentDirectory(
      FilePath(FILE_PATH_LITERAL("drive/Directory 1")),
      base::Bind(&CopyResultFromFindFirstMissingParentDirectory,
                 &result));
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(DriveFileSystem::FIND_FIRST_DIRECTORY_ALREADY_PRESENT,
            result.error);
}

// Create a directory through the document service
TEST_F(DriveFileSystemTest, CreateDirectoryWithService) {
  LoadRootFeedDocument("gdata/root_feed.json");
  EXPECT_CALL(*mock_drive_service_,
              CreateDirectory(_, "Sample Directory Title", _)).Times(1);
  EXPECT_CALL(*mock_directory_observer_, OnDirectoryChanged(
      Eq(FilePath(FILE_PATH_LITERAL("drive"))))).Times(1);

  // Set last error so it's not a valid error code.
  callback_helper_->last_error_ = static_cast<DriveFileError>(1);
  file_system_->CreateDirectory(
      FilePath(FILE_PATH_LITERAL("drive/Sample Directory Title")),
      false,  // is_exclusive
      true,  // is_recursive
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get()));
  test_util::RunBlockingPoolTask();
  // TODO(gspencer): Uncomment this when we get a blob that
  // works that can be returned from the mock.
  // EXPECT_EQ(DRIVE_FILE_OK, callback_helper_->last_error_);
}

TEST_F(DriveFileSystemTest, GetFileByPath_FromGData_EnoughSpace) {
  LoadRootFeedDocument("gdata/root_feed.json");

  GetFileCallback callback =
      base::Bind(&CallbackHelper::GetFileCallback,
                 callback_helper_.get());

  FilePath file_in_root(FILE_PATH_LITERAL("drive/File 1.txt"));
  scoped_ptr<DriveEntryProto> entry_proto(GetEntryInfoByPathSync(file_in_root));
  FilePath downloaded_file = GetCachePathForFile(
      entry_proto->resource_id(),
      entry_proto->file_specific_info().file_md5());
  const int64 file_size = entry_proto->file_info().size();

  // Pretend we have enough space.
  EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
      .Times(2).WillRepeatedly(Return(file_size + kMinFreeSpace));

  // Before Download starts metadata from server will be fetched.
  // We will read content url from the result.
  scoped_ptr<base::Value> document =
      test_util::LoadJSONFile("gdata/document_to_download.json");
  SetExpectationsForGetDocumentEntry(&document, "file:2_file_resource_id");

  // The file is obtained with the mock DriveService.
  EXPECT_CALL(*mock_drive_service_,
              DownloadFile(file_in_root,
                           downloaded_file,
                           GURL("https://file_content_url_changed/"),
                           _, _))
      .Times(1);

  file_system_->GetFileByPath(file_in_root, callback,
                              GetContentCallback());
  test_util::RunBlockingPoolTask();

  EXPECT_EQ(DRIVE_FILE_OK, callback_helper_->last_error_);
  EXPECT_EQ(REGULAR_FILE, callback_helper_->file_type_);
  EXPECT_EQ(downloaded_file.value(),
            callback_helper_->download_path_.value());
}

TEST_F(DriveFileSystemTest, GetFileByPath_FromGData_NoSpaceAtAll) {
  LoadRootFeedDocument("gdata/root_feed.json");

  GetFileCallback callback =
      base::Bind(&CallbackHelper::GetFileCallback,
                 callback_helper_.get());

  FilePath file_in_root(FILE_PATH_LITERAL("drive/File 1.txt"));
  scoped_ptr<DriveEntryProto> entry_proto(GetEntryInfoByPathSync(file_in_root));
  FilePath downloaded_file = GetCachePathForFile(
      entry_proto->resource_id(),
      entry_proto->file_specific_info().file_md5());

  // Pretend we have no space at all.
  EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
      .Times(2).WillRepeatedly(Return(0));

  // Before Download starts metadata from server will be fetched.
  // We will read content url from the result.
  scoped_ptr<base::Value> document =
      test_util::LoadJSONFile("gdata/document_to_download.json");
  SetExpectationsForGetDocumentEntry(&document, "file:2_file_resource_id");

  // The file is not obtained with the mock DriveService, because of no space.
  EXPECT_CALL(*mock_drive_service_,
              DownloadFile(file_in_root,
                           downloaded_file,
                           GURL("https://file_content_url_changed/"),
                           _, _))
      .Times(0);

  file_system_->GetFileByPath(file_in_root, callback,
                              GetContentCallback());
  test_util::RunBlockingPoolTask();

  EXPECT_EQ(DRIVE_FILE_ERROR_NO_SPACE,
            callback_helper_->last_error_);
}

TEST_F(DriveFileSystemTest, GetFileByPath_FromGData_NoEnoughSpaceButCanFreeUp) {
  LoadRootFeedDocument("gdata/root_feed.json");

  GetFileCallback callback =
      base::Bind(&CallbackHelper::GetFileCallback,
                 callback_helper_.get());

  FilePath file_in_root(FILE_PATH_LITERAL("drive/File 1.txt"));
  scoped_ptr<DriveEntryProto> entry_proto(GetEntryInfoByPathSync(file_in_root));
  FilePath downloaded_file = GetCachePathForFile(
      entry_proto->resource_id(),
      entry_proto->file_specific_info().file_md5());
  const int64 file_size = entry_proto->file_info().size();

  // Pretend we have no space first (checked before downloading a file),
  // but then start reporting we have space. This is to emulate that
  // the disk space was freed up by removing temporary files.
  EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
      .WillOnce(Return(file_size + kMinFreeSpace))
      .WillOnce(Return(0))
      .WillOnce(Return(file_size + kMinFreeSpace))
      .WillOnce(Return(file_size + kMinFreeSpace));

  // Store something in the temporary cache directory.
  TestStoreToCache("<resource_id>",
                   "<md5>",
                   test_util::GetTestFilePath("gdata/root_feed.json"),
                   DRIVE_FILE_OK,
                   test_util::TEST_CACHE_STATE_PRESENT,
                   DriveCache::CACHE_TYPE_TMP);
  ASSERT_TRUE(CacheEntryExists("<resource_id>", "<md5>"));
  ASSERT_TRUE(CacheFileExists("<resource_id>", "<md5>"));

  // Before Download starts metadata from server will be fetched.
  // We will read content url from the result.
  scoped_ptr<base::Value> document =
      test_util::LoadJSONFile("gdata/document_to_download.json");
  SetExpectationsForGetDocumentEntry(&document, "file:2_file_resource_id");

  // The file is obtained with the mock DriveService, because of we freed up the
  // space.
  EXPECT_CALL(*mock_drive_service_,
              DownloadFile(file_in_root,
                           downloaded_file,
                           GURL("https://file_content_url_changed/"),
                           _, _))
      .Times(1);

  file_system_->GetFileByPath(file_in_root, callback,
                              GetContentCallback());
  test_util::RunBlockingPoolTask();

  EXPECT_EQ(DRIVE_FILE_OK, callback_helper_->last_error_);
  EXPECT_EQ(REGULAR_FILE, callback_helper_->file_type_);
  EXPECT_EQ(downloaded_file.value(),
            callback_helper_->download_path_.value());

  // The file should be removed in order to free up space, and the cache
  // entry should also be removed.
  ASSERT_FALSE(CacheEntryExists("<resource_id>", "<md5>"));
  ASSERT_FALSE(CacheFileExists("<resource_id>", "<md5>"));
}

TEST_F(DriveFileSystemTest, GetFileByPath_FromGData_EnoughSpaceButBecomeFull) {
  LoadRootFeedDocument("gdata/root_feed.json");

  GetFileCallback callback =
      base::Bind(&CallbackHelper::GetFileCallback,
                 callback_helper_.get());

  FilePath file_in_root(FILE_PATH_LITERAL("drive/File 1.txt"));
  scoped_ptr<DriveEntryProto> entry_proto(GetEntryInfoByPathSync(file_in_root));
  FilePath downloaded_file = GetCachePathForFile(
      entry_proto->resource_id(),
      entry_proto->file_specific_info().file_md5());
  const int64 file_size = entry_proto->file_info().size();

  // Pretend we have enough space first (checked before downloading a file),
  // but then start reporting we have not enough space. This is to emulate that
  // the disk space becomes full after the file is downloaded for some reason
  // (ex. the actual file was larger than the expected size).
  EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
      .WillOnce(Return(file_size + kMinFreeSpace))
      .WillOnce(Return(kMinFreeSpace - 1))
      .WillOnce(Return(kMinFreeSpace - 1));

  // Before Download starts metadata from server will be fetched.
  // We will read content url from the result.
  scoped_ptr<base::Value> document =
      test_util::LoadJSONFile("gdata/document_to_download.json");
  SetExpectationsForGetDocumentEntry(&document, "file:2_file_resource_id");

  // The file is obtained with the mock DriveService.
  EXPECT_CALL(*mock_drive_service_,
              DownloadFile(file_in_root,
                           downloaded_file,
                           GURL("https://file_content_url_changed/"),
                           _, _))
      .Times(1);

  file_system_->GetFileByPath(file_in_root, callback,
                              GetContentCallback());
  test_util::RunBlockingPoolTask();

  EXPECT_EQ(DRIVE_FILE_ERROR_NO_SPACE,
            callback_helper_->last_error_);
}

TEST_F(DriveFileSystemTest, GetFileByPath_FromCache) {
  EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
      .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));

  LoadRootFeedDocument("gdata/root_feed.json");

  GetFileCallback callback =
      base::Bind(&CallbackHelper::GetFileCallback,
                 callback_helper_.get());

  FilePath file_in_root(FILE_PATH_LITERAL("drive/File 1.txt"));
  scoped_ptr<DriveEntryProto> entry_proto(GetEntryInfoByPathSync(file_in_root));
  FilePath downloaded_file = GetCachePathForFile(
      entry_proto->resource_id(),
      entry_proto->file_specific_info().file_md5());

  // Store something as cached version of this file.
  TestStoreToCache(entry_proto->resource_id(),
                   entry_proto->file_specific_info().file_md5(),
                   test_util::GetTestFilePath("gdata/root_feed.json"),
                   DRIVE_FILE_OK,
                   test_util::TEST_CACHE_STATE_PRESENT,
                   DriveCache::CACHE_TYPE_TMP);

  // Make sure we don't fetch metadata for downloading file.
  EXPECT_CALL(*mock_drive_service_, GetDocumentEntry(_, _)).Times(0);

  // Make sure we don't call downloads at all.
  EXPECT_CALL(*mock_drive_service_,
              DownloadFile(file_in_root,
                           downloaded_file,
                           GURL("https://file_content_url_changed/"),
                           _, _))
      .Times(0);

  file_system_->GetFileByPath(file_in_root, callback,
                              GetContentCallback());
  test_util::RunBlockingPoolTask();

  EXPECT_EQ(REGULAR_FILE, callback_helper_->file_type_);
  EXPECT_EQ(downloaded_file.value(),
            callback_helper_->download_path_.value());
}

TEST_F(DriveFileSystemTest, GetFileByPath_HostedDocument) {
  LoadRootFeedDocument("gdata/root_feed.json");

  GetFileCallback callback =
      base::Bind(&CallbackHelper::GetFileCallback,
                 callback_helper_.get());

  FilePath file_in_root(FILE_PATH_LITERAL("drive/Document 1.gdoc"));
  scoped_ptr<DriveEntryProto> src_entry_proto =
      GetEntryInfoByPathSync(file_in_root);
  ASSERT_TRUE(src_entry_proto.get());

  file_system_->GetFileByPath(file_in_root, callback,
                              GetContentCallback());
  test_util::RunBlockingPoolTask();

  EXPECT_EQ(HOSTED_DOCUMENT, callback_helper_->file_type_);
  EXPECT_FALSE(callback_helper_->download_path_.empty());

  ASSERT_TRUE(src_entry_proto.get());
  VerifyHostedDocumentJSONFile(*src_entry_proto,
                               callback_helper_->download_path_);
}

TEST_F(DriveFileSystemTest, GetFileByResourceId) {
  EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
      .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));

  LoadRootFeedDocument("gdata/root_feed.json");

  GetFileCallback callback =
      base::Bind(&CallbackHelper::GetFileCallback,
                 callback_helper_.get());

  FilePath file_in_root(FILE_PATH_LITERAL("drive/File 1.txt"));
  scoped_ptr<DriveEntryProto> entry_proto(GetEntryInfoByPathSync(file_in_root));
  FilePath downloaded_file = GetCachePathForFile(
      entry_proto->resource_id(),
      entry_proto->file_specific_info().file_md5());

  // Before Download starts metadata from server will be fetched.
  // We will read content url from the result.
  scoped_ptr<base::Value> document =
      test_util::LoadJSONFile("gdata/document_to_download.json");
  SetExpectationsForGetDocumentEntry(&document, "file:2_file_resource_id");

  // The file is obtained with the mock DriveService, because it's not stored in
  // the cache.
  EXPECT_CALL(*mock_drive_service_,
              DownloadFile(file_in_root,
                           downloaded_file,
                           GURL("https://file_content_url_changed/"),
                           _, _))
      .Times(1);

  file_system_->GetFileByResourceId(entry_proto->resource_id(),
                                    callback,
                                    GetContentCallback());
  test_util::RunBlockingPoolTask();

  EXPECT_EQ(REGULAR_FILE, callback_helper_->file_type_);
  EXPECT_EQ(downloaded_file.value(),
            callback_helper_->download_path_.value());
}

TEST_F(DriveFileSystemTest, GetFileByResourceId_FromCache) {
  EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
      .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));

  LoadRootFeedDocument("gdata/root_feed.json");

  GetFileCallback callback =
      base::Bind(&CallbackHelper::GetFileCallback,
                 callback_helper_.get());

  FilePath file_in_root(FILE_PATH_LITERAL("drive/File 1.txt"));
  scoped_ptr<DriveEntryProto> entry_proto(GetEntryInfoByPathSync(file_in_root));
  FilePath downloaded_file = GetCachePathForFile(
      entry_proto->resource_id(),
      entry_proto->file_specific_info().file_md5());

  // Store something as cached version of this file.
  TestStoreToCache(entry_proto->resource_id(),
                   entry_proto->file_specific_info().file_md5(),
                   test_util::GetTestFilePath("gdata/root_feed.json"),
                   DRIVE_FILE_OK,
                   test_util::TEST_CACHE_STATE_PRESENT,
                   DriveCache::CACHE_TYPE_TMP);

  // The file is obtained from the cache.
  // Make sure we don't call downloads at all.
  EXPECT_CALL(*mock_drive_service_, DownloadFile(_, _, _, _, _))
      .Times(0);

  file_system_->GetFileByResourceId(entry_proto->resource_id(),
                                    callback,
                                    GetContentCallback());
  test_util::RunBlockingPoolTask();

  EXPECT_EQ(REGULAR_FILE, callback_helper_->file_type_);
  EXPECT_EQ(downloaded_file.value(),
            callback_helper_->download_path_.value());
}

TEST_F(DriveFileSystemTest, UpdateFileByResourceId_PersistentFile) {
  EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
      .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));

  LoadRootFeedDocument("gdata/root_feed.json");

  // This is a file defined in root_feed.json.
  const FilePath kFilePath(FILE_PATH_LITERAL("drive/File 1.txt"));
  const std::string kResourceId("file:2_file_resource_id");
  const std::string kMd5("3b4382ebefec6e743578c76bbd0575ce");

  // Pin the file so it'll be store in "persistent" directory.
  EXPECT_CALL(*mock_cache_observer_, OnCachePinned(kResourceId, kMd5)).Times(1);
  TestPin(kResourceId,
          kMd5,
          DRIVE_FILE_OK,
          test_util::TEST_CACHE_STATE_PINNED,
          DriveCache::CACHE_TYPE_TMP);

  // First store a file to cache. A cache file will be created at:
  // GCache/v1/persistent/<kResourceId>.<kMd5>
  const FilePath original_cache_file_path =
      DriveCache::GetCacheRootPath(profile_.get())
      .AppendASCII("persistent")
      .AppendASCII(kResourceId + "." + kMd5);
  TestStoreToCache(kResourceId,
                   kMd5,
                   // Anything works.
                   test_util::GetTestFilePath("gdata/root_feed.json"),
                   DRIVE_FILE_OK,
                   test_util::TEST_CACHE_STATE_PRESENT |
                   test_util::TEST_CACHE_STATE_PINNED |
                   test_util::TEST_CACHE_STATE_PERSISTENT,
                   DriveCache::CACHE_TYPE_PERSISTENT);
  ASSERT_TRUE(file_util::PathExists(original_cache_file_path));

  // Add the dirty bit. The cache file will be renamed to
  // GCache/v1/persistent/<kResourceId>.local
  TestMarkDirty(kResourceId,
                kMd5,
                DRIVE_FILE_OK,
                test_util::TEST_CACHE_STATE_PRESENT |
                test_util::TEST_CACHE_STATE_PINNED |
                test_util::TEST_CACHE_STATE_DIRTY |
                test_util::TEST_CACHE_STATE_PERSISTENT,
                DriveCache::CACHE_TYPE_PERSISTENT);
  const FilePath dirty_cache_file_path =
      DriveCache::GetCacheRootPath(profile_.get())
      .AppendASCII("persistent")
      .AppendASCII(kResourceId + ".local");
  ASSERT_FALSE(file_util::PathExists(original_cache_file_path));
  ASSERT_TRUE(file_util::PathExists(dirty_cache_file_path));

  // Modify the cached file.
  const std::string kDummyCacheContent("modification to the cache");
  ASSERT_TRUE(file_util::WriteFile(dirty_cache_file_path,
                                   kDummyCacheContent.c_str(),
                                   kDummyCacheContent.size()));

  // Commit the dirty bit. The cache file name remains the same
  // but a symlink will be created at:
  // GCache/v1/outgoing/<kResourceId>
  EXPECT_CALL(*mock_cache_observer_, OnCacheCommitted(kResourceId)).Times(1);
  TestCommitDirty(kResourceId,
                  kMd5,
                  DRIVE_FILE_OK,
                  test_util::TEST_CACHE_STATE_PRESENT |
                  test_util::TEST_CACHE_STATE_PINNED |
                  test_util::TEST_CACHE_STATE_DIRTY |
                  test_util::TEST_CACHE_STATE_PERSISTENT,
                  DriveCache::CACHE_TYPE_PERSISTENT);
  const FilePath outgoing_symlink_path =
      DriveCache::GetCacheRootPath(profile_.get())
      .AppendASCII("outgoing")
      .AppendASCII(kResourceId);
  ASSERT_TRUE(file_util::PathExists(dirty_cache_file_path));
  ASSERT_TRUE(file_util::PathExists(outgoing_symlink_path));

  // Create a DocumentEntry, which is needed to mock
  // DriveUploaderInterface::UploadExistingFile().
  // TODO(satorux): This should be cleaned up. crbug.com/134240.
  DocumentEntry* document_entry = NULL;
  scoped_ptr<base::Value> value =
      test_util::LoadJSONFile("gdata/root_feed.json");
  ASSERT_TRUE(value.get());
  base::DictionaryValue* as_dict = NULL;
  base::ListValue* entry_list = NULL;
  if (value->GetAsDictionary(&as_dict) &&
      as_dict->GetList("feed.entry", &entry_list)) {
    for (size_t i = 0; i < entry_list->GetSize(); ++i) {
      base::DictionaryValue* entry = NULL;
      std::string resource_id;
      if (entry_list->GetDictionary(i, &entry) &&
          entry->GetString("gd$resourceId.$t", &resource_id) &&
          resource_id == kResourceId) {
        // This will be deleted by UploadExistingFile().
        document_entry = DocumentEntry::CreateFrom(*entry);
      }
    }
  }
  ASSERT_TRUE(document_entry);

  // The mock uploader will be used to simulate a file upload.
  EXPECT_CALL(*mock_uploader_, UploadExistingFile(
      GURL("https://file_link_resumable_edit_media/"),
      kFilePath,
      dirty_cache_file_path,
      "audio/mpeg",
      kDummyCacheContent.size(),  // The size after modification must be used.
      _,   // Completion callback.
      _))  // Ready callback.
      .WillOnce(MockUploadExistingFile(
          DRIVE_FILE_OK,
          FilePath::FromUTF8Unsafe("drive/File1"),
          dirty_cache_file_path,
          document_entry));

  // We'll notify the directory change to the observer upon completion.
  EXPECT_CALL(*mock_directory_observer_,
              OnDirectoryChanged(Eq(FilePath(kDriveRootDirectory)))).Times(1);

  // The callback will be called upon completion of
  // UpdateFileByResourceId().
  FileOperationCallback callback =
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get());

  // Check the number of files in the root directory. We'll compare the
  // number after updating a file.
  scoped_ptr<DriveEntryProtoVector> root_directory_entries(
      ReadDirectoryByPathSync(FilePath::FromUTF8Unsafe("drive")));
  ASSERT_TRUE(root_directory_entries.get());
  const int num_files_in_root = CountFiles(*root_directory_entries);

  file_system_->UpdateFileByResourceId(kResourceId, callback);
  test_util::RunBlockingPoolTask();

  EXPECT_EQ(DRIVE_FILE_OK, callback_helper_->last_error_);
  // Make sure that the number of files did not change (i.e. we updated an
  // existing file, rather than adding a new file. The number of files
  // increases if we don't handle the file update right).
  EXPECT_EQ(num_files_in_root, CountFiles(*root_directory_entries));
  // After the file is updated, the dirty bit is cleared, hence the symlink
  // should be gone.
  ASSERT_FALSE(file_util::PathExists(outgoing_symlink_path));
}

TEST_F(DriveFileSystemTest, UpdateFileByResourceId_NonexistentFile) {
  LoadRootFeedDocument("gdata/root_feed.json");

  // This is nonexistent in root_feed.json.
  const FilePath kFilePath(FILE_PATH_LITERAL("drive/Nonexistent.txt"));
  const std::string kResourceId("file:nonexistent_resource_id");
  const std::string kMd5("nonexistent_md5");

  // The callback will be called upon completion of
  // UpdateFileByResourceId().
  FileOperationCallback callback =
      base::Bind(&CallbackHelper::FileOperationCallback,
                 callback_helper_.get());

  file_system_->UpdateFileByResourceId(kResourceId, callback);
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(DRIVE_FILE_ERROR_NOT_FOUND, callback_helper_->last_error_);
}

TEST_F(DriveFileSystemTest, ContentSearch) {
  LoadRootFeedDocument("gdata/root_feed.json");

  mock_drive_service_->set_search_result("gdata/search_result_feed.json");

  EXPECT_CALL(*mock_drive_service_, GetDocuments(Eq(GURL()), _, "foo", _, _))
      .Times(1);

  const SearchResultPair kExpectedResults[] = {
    { "drive/Directory 1/SubDirectory File 1.txt", false },
    { "drive/Directory 1", true }
  };

  SearchCallback callback = base::Bind(&DriveSearchCallback,
      &message_loop_, kExpectedResults, ARRAYSIZE_UNSAFE(kExpectedResults));

  file_system_->Search("foo", GURL(), callback);
  message_loop_.Run();  // Wait to get our result.
}

TEST_F(DriveFileSystemTest, ContentSearchWithNewEntry) {
  LoadRootFeedDocument("gdata/root_feed.json");

  // Search result returning two entries "Directory 1/" and
  // "Directory 1/SubDirectory Newly Added File.txt". The latter is not
  // contained in the root feed.
  mock_drive_service_->set_search_result(
      "gdata/search_result_with_new_entry_feed.json");

  EXPECT_CALL(*mock_drive_service_, GetDocuments(Eq(GURL()), _, "foo", _, _))
      .Times(1);

  // As the result of the first Search(), only entries in the current file
  // system snapshot are expected to be returned.
  const SearchResultPair kExpectedResults[] = {
    { "drive/Directory 1", true }
  };

  // At the same time, unknown entry should trigger delta feed request.
  // This will cause notification to observers (e.g., File Browser) so that
  // they can request search again.
  EXPECT_CALL(*mock_drive_service_, GetAccountMetadata(_)).Times(1);
  EXPECT_CALL(*mock_drive_service_, GetDocuments(Eq(GURL()), _, "", _, _))
      .Times(1);
  EXPECT_CALL(*mock_webapps_registry_, UpdateFromFeed(_)).Times(1);

  SearchCallback callback = base::Bind(&DriveSearchCallback,
      &message_loop_, kExpectedResults, ARRAYSIZE_UNSAFE(kExpectedResults));

  file_system_->Search("foo", GURL(), callback);
  message_loop_.Run();  // Wait to get our result.
}

TEST_F(DriveFileSystemTest, ContentSearchEmptyResult) {
  LoadRootFeedDocument("gdata/root_feed.json");

  mock_drive_service_->set_search_result("gdata/empty_feed.json");

  EXPECT_CALL(*mock_drive_service_, GetDocuments(Eq(GURL()), _, "foo", _, _))
      .Times(1);

  const SearchResultPair* expected_results = NULL;

  SearchCallback callback = base::Bind(&DriveSearchCallback,
      &message_loop_, expected_results, 0u);

  file_system_->Search("foo", GURL(), callback);
  message_loop_.Run();  // Wait to get our result.
}

TEST_F(DriveFileSystemTest, GetAvailableSpace) {
  GetAvailableSpaceCallback callback =
      base::Bind(&CallbackHelper::GetAvailableSpaceCallback,
                 callback_helper_.get());

  EXPECT_CALL(*mock_drive_service_, GetAccountMetadata(_));

  file_system_->GetAvailableSpace(callback);
  test_util::RunBlockingPoolTask();
  EXPECT_EQ(GG_LONGLONG(6789012345), callback_helper_->quota_bytes_used_);
  EXPECT_EQ(GG_LONGLONG(9876543210), callback_helper_->quota_bytes_total_);
}

TEST_F(DriveFileSystemTest, RequestDirectoryRefresh) {
  LoadRootFeedDocument("gdata/root_feed.json");

  // We'll fetch documents in the root directory with its resource ID.
  EXPECT_CALL(*mock_drive_service_,
              GetDocuments(Eq(GURL()), _, _, kDriveRootDirectoryResourceId, _))
      .Times(1);
  // We'll notify the directory change to the observer.
  EXPECT_CALL(*mock_directory_observer_,
              OnDirectoryChanged(Eq(FilePath(kDriveRootDirectory)))).Times(1);

  file_system_->RequestDirectoryRefresh(FilePath(kDriveRootDirectory));
  test_util::RunBlockingPoolTask();
}

TEST_F(DriveFileSystemTest, OpenAndCloseFile) {
  LoadRootFeedDocument("gdata/root_feed.json");

  OpenFileCallback callback =
      base::Bind(&CallbackHelper::OpenFileCallback,
                 callback_helper_.get());
  FileOperationCallback close_file_callback =
      base::Bind(&CallbackHelper::CloseFileCallback,
                 callback_helper_.get());

  const FilePath kFileInRoot(FILE_PATH_LITERAL("drive/File 1.txt"));
  scoped_ptr<DriveEntryProto> entry_proto(GetEntryInfoByPathSync(kFileInRoot));
  FilePath downloaded_file = GetCachePathForFile(
      entry_proto->resource_id(),
      entry_proto->file_specific_info().file_md5());
  const int64 file_size = entry_proto->file_info().size();
  const std::string& file_resource_id =
      entry_proto->resource_id();
  const std::string& file_md5 = entry_proto->file_specific_info().file_md5();

  // A dirty file is created on close.
  EXPECT_CALL(*mock_cache_observer_, OnCacheCommitted(file_resource_id))
      .Times(1);

  // Pretend we have enough space.
  EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
      .Times(2).WillRepeatedly(Return(file_size + kMinFreeSpace));

  const std::string kExpectedFileData = "test file data";
  mock_drive_service_->set_file_data(new std::string(kExpectedFileData));

  // Before Download starts metadata from server will be fetched.
  // We will read content url from the result.
  scoped_ptr<base::Value> document =
      test_util::LoadJSONFile("gdata/document_to_download.json");
  SetExpectationsForGetDocumentEntry(&document, "file:2_file_resource_id");

  // The file is obtained with the mock DriveService.
  EXPECT_CALL(*mock_drive_service_,
              DownloadFile(kFileInRoot,
                           downloaded_file,
                           GURL("https://file_content_url_changed/"),
                           _, _))
      .Times(1);

  // Open kFileInRoot ("drive/File 1.txt").
  file_system_->OpenFile(kFileInRoot, callback);
  message_loop_.Run();
  const FilePath opened_file_path = callback_helper_->opened_file_path_;

  // Verify that the file was properly opened.
  EXPECT_EQ(DRIVE_FILE_OK, callback_helper_->last_error_);

  // Try to open the already opened file.
  file_system_->OpenFile(kFileInRoot, callback);
  message_loop_.Run();

  // It must fail.
  EXPECT_EQ(DRIVE_FILE_ERROR_IN_USE, callback_helper_->last_error_);

  // Verify that the file contents match the expected contents.
  std::string cache_file_data;
  EXPECT_TRUE(file_util::ReadFileToString(opened_file_path, &cache_file_data));
  EXPECT_EQ(kExpectedFileData, cache_file_data);

  // Verify that the cache state was changed as expected.
  VerifyCacheStateAfterOpenFile(DRIVE_FILE_OK,
                                file_resource_id,
                                file_md5,
                                opened_file_path);

  // Close kFileInRoot ("drive/File 1.txt").
  file_system_->CloseFile(kFileInRoot, close_file_callback);
  message_loop_.Run();

  // Verify that the file was properly closed.
  EXPECT_EQ(DRIVE_FILE_OK, callback_helper_->last_error_);

  // Verify that the cache state was changed as expected.
  VerifyCacheStateAfterCloseFile(DRIVE_FILE_OK,
                                 file_resource_id,
                                 file_md5);

  // Try to close the same file twice.
  file_system_->CloseFile(kFileInRoot, close_file_callback);
  message_loop_.Run();

  // It must fail.
  EXPECT_EQ(DRIVE_FILE_ERROR_NOT_FOUND, callback_helper_->last_error_);
}

}   // namespace gdata
