blob: e67309f722c5281870fc52e5ed74f62e8eae6ce6 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/sync_file_system/drive_backend/api_util.h"
#include "base/file_util.h"
#include "base/location.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "chrome/browser/drive/drive_uploader.h"
#include "chrome/browser/drive/fake_drive_service.h"
#include "chrome/browser/google_apis/drive_api_parser.h"
#include "chrome/browser/google_apis/gdata_errorcode.h"
#include "chrome/browser/google_apis/test_util.h"
#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_util.h"
#include "chrome/browser/sync_file_system/drive_backend/fake_drive_service_helper.h"
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/escape.h"
#include "testing/gtest/include/gtest/gtest.h"
#define FPL(x) FILE_PATH_LITERAL(x)
using drive::DriveServiceInterface;
using drive::DriveUploaderInterface;
using drive::FakeDriveService;
using drive::UploadCompletionCallback;
using google_apis::GDataErrorCode;
using google_apis::ProgressCallback;
using google_apis::ResourceEntry;
using google_apis::ResourceList;
namespace sync_file_system {
namespace drive_backend {
namespace {
const char kOrigin[] = "chrome-extension://example";
const char kOriginDirectoryName[] = "example";
struct Output {
GDataErrorCode error;
std::string resource_id;
std::string file_md5;
int64 largest_changestamp;
Output() : error(google_apis::GDATA_OTHER_ERROR),
largest_changestamp(-1) {
}
};
void DidAddFileOrDirectoryForMakingConflict(GDataErrorCode error,
scoped_ptr<ResourceEntry> entry) {
ASSERT_EQ(google_apis::HTTP_CREATED, error);
ASSERT_TRUE(entry);
}
void DidAddFileForUploadNew(
const UploadCompletionCallback& callback,
GDataErrorCode error,
scoped_ptr<ResourceEntry> entry) {
ASSERT_EQ(google_apis::HTTP_CREATED, error);
ASSERT_TRUE(entry);
base::MessageLoopProxy::current()->PostTask(
FROM_HERE,
base::Bind(callback,
google_apis::HTTP_SUCCESS,
GURL(),
base::Passed(&entry)));
}
void DidGetResourceEntryForUploadExisting(
const UploadCompletionCallback& callback,
GDataErrorCode error,
scoped_ptr<ResourceEntry> entry) {
ASSERT_EQ(google_apis::HTTP_SUCCESS, error);
ASSERT_TRUE(entry);
base::MessageLoopProxy::current()->PostTask(
FROM_HERE,
base::Bind(callback,
google_apis::HTTP_SUCCESS,
GURL(),
base::Passed(&entry)));
}
class FakeDriveServiceWrapper : public FakeDriveService {
public:
FakeDriveServiceWrapper() : make_directory_conflict_(false) {}
virtual ~FakeDriveServiceWrapper() {}
// DriveServiceInterface overrides.
virtual google_apis::CancelCallback AddNewDirectory(
const std::string& parent_resource_id,
const std::string& directory_name,
const google_apis::GetResourceEntryCallback& callback) OVERRIDE {
if (make_directory_conflict_) {
FakeDriveService::AddNewDirectory(
parent_resource_id,
directory_name,
base::Bind(&DidAddFileOrDirectoryForMakingConflict));
}
return FakeDriveService::AddNewDirectory(
parent_resource_id, directory_name, callback);
}
void set_make_directory_conflict(bool enable) {
make_directory_conflict_ = enable;
}
private:
bool make_directory_conflict_;
DISALLOW_COPY_AND_ASSIGN(FakeDriveServiceWrapper);
};
// A fake implementation of DriveUploaderInterface, which provides fake
// behaviors for file uploading.
class FakeDriveUploader : public DriveUploaderInterface {
public:
explicit FakeDriveUploader(FakeDriveServiceWrapper* fake_drive_service)
: fake_drive_service_(fake_drive_service),
make_file_conflict_(false) {}
virtual ~FakeDriveUploader() {}
// DriveUploaderInterface overrides.
// Proxies a request to upload a new file to FakeDriveService, and returns the
// resource entry to the caller.
virtual google_apis::CancelCallback UploadNewFile(
const std::string& parent_resource_id,
const base::FilePath& local_file_path,
const std::string& title,
const std::string& content_type,
const UploadCompletionCallback& callback,
const ProgressCallback& progress_callback) OVERRIDE {
DCHECK(!callback.is_null());
const std::string kFileContent = "test content";
if (make_file_conflict_) {
fake_drive_service_->AddNewFile(
content_type,
kFileContent,
parent_resource_id,
title,
false, // shared_with_me
base::Bind(&DidAddFileOrDirectoryForMakingConflict));
}
fake_drive_service_->AddNewFile(
content_type,
kFileContent,
parent_resource_id,
title,
false, // shared_with_me
base::Bind(&DidAddFileForUploadNew, callback));
base::MessageLoop::current()->RunUntilIdle();
return google_apis::CancelCallback();
}
// Pretends that an existing file |resource_id| was uploaded successfully, and
// returns a resource entry to the caller.
virtual google_apis::CancelCallback UploadExistingFile(
const std::string& resource_id,
const base::FilePath& local_file_path,
const std::string& content_type,
const std::string& etag,
const UploadCompletionCallback& callback,
const ProgressCallback& progress_callback) OVERRIDE {
DCHECK(!callback.is_null());
return fake_drive_service_->GetResourceEntry(
resource_id,
base::Bind(&DidGetResourceEntryForUploadExisting, callback));
}
// At the moment, sync file system doesn't support resuming of the uploading.
// So this method shouldn't be reached.
virtual google_apis::CancelCallback ResumeUploadFile(
const GURL& upload_location,
const base::FilePath& local_file_path,
const std::string& content_type,
const UploadCompletionCallback& callback,
const ProgressCallback& progress_callback) OVERRIDE {
NOTREACHED();
return google_apis::CancelCallback();
}
void set_make_file_conflict(bool enable) {
make_file_conflict_ = enable;
}
private:
FakeDriveServiceWrapper* fake_drive_service_;
bool make_file_conflict_;
DISALLOW_COPY_AND_ASSIGN(FakeDriveUploader);
};
} // namespace
class APIUtilTest : public testing::Test {
public:
APIUtilTest() : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
fake_drive_service_(NULL),
fake_drive_uploader_(NULL) {}
virtual void SetUp() OVERRIDE {
fake_drive_service_ = new FakeDriveServiceWrapper;
fake_drive_uploader_ = new FakeDriveUploader(fake_drive_service_);
fake_drive_helper_.reset(new FakeDriveServiceHelper(
fake_drive_service_, fake_drive_uploader_));
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
api_util_ = APIUtil::CreateForTesting(
temp_dir_.path(),
scoped_ptr<DriveServiceInterface>(fake_drive_service_),
scoped_ptr<DriveUploaderInterface>(fake_drive_uploader_));
fake_drive_service_->LoadResourceListForWapi(
"sync_file_system/initialize.json");
}
virtual void TearDown() OVERRIDE {
api_util_.reset();
}
protected:
std::string SetUpSyncRootDirectory() {
std::string sync_root_id;
EXPECT_EQ(google_apis::HTTP_CREATED,
fake_drive_helper_->AddOrphanedFolder(
APIUtil::GetSyncRootDirectoryName(),
&sync_root_id));
return sync_root_id;
}
std::string SetUpOriginRootDirectory(const std::string& sync_root_id) {
std::string origin_root_id;
EXPECT_EQ(google_apis::HTTP_CREATED,
fake_drive_helper_->AddFolder(
sync_root_id,
kOriginDirectoryName,
&origin_root_id));
return origin_root_id;
}
void SetUpFile(const std::string& origin_root_id,
const std::string& content_data,
const std::string& title,
scoped_ptr<ResourceEntry>* entry) {
ASSERT_TRUE(entry);
std::string file_resource_id;
EXPECT_EQ(google_apis::HTTP_SUCCESS,
fake_drive_helper_->AddFile(
origin_root_id,
title,
content_data,
&file_resource_id));
EXPECT_EQ(google_apis::HTTP_SUCCESS,
fake_drive_helper_->GetResourceEntry(
file_resource_id,
entry));
}
void LoadAccountMetadata() {
fake_drive_service_->LoadAccountMetadataForWapi(
"sync_file_system/account_metadata.json");
}
void VerifyTitleUniqueness(const std::string& parent_resource_id,
const std::string& title,
const std::string& resource_id,
google_apis::DriveEntryKind kind) {
ScopedVector<ResourceEntry> entries;
EXPECT_EQ(google_apis::HTTP_SUCCESS,
fake_drive_helper_->SearchByTitle(
parent_resource_id, title, &entries));
ASSERT_EQ(1u, entries.size());
EXPECT_EQ(resource_id, entries[0]->resource_id());
EXPECT_EQ(kind, entries[0]->kind());
}
void VerifyFileDeletion(const std::string& parent_resource_id,
const std::string& title) {
ScopedVector<ResourceEntry> entries;
EXPECT_EQ(google_apis::HTTP_SUCCESS,
fake_drive_helper_->SearchByTitle(
parent_resource_id, title, &entries));
EXPECT_TRUE(entries.empty());
}
APIUtil* api_util() { return api_util_.get(); }
FakeDriveServiceWrapper* fake_drive_service() {
return fake_drive_service_;
}
FakeDriveUploader* fake_drive_uploader() {
return fake_drive_uploader_;
}
void TestGetSyncRoot();
void TestCreateSyncRoot();
void TestCreateSyncRoot_Conflict();
void TestGetOriginDirectory();
void TestCreateOriginDirectory();
void TestCreateOriginDirectory_Conflict();
void TestGetLargestChangeStamp();
void TestListFiles();
void TestListChanges();
void TestDownloadFile();
void TestDownloadFileInNotModified();
void TestUploadNewFile();
void TestUploadNewFile_ConflictWithFile();
void TestUploadExistingFile();
void TestUploadExistingFileInConflict();
void TestDeleteFile();
void TestDeleteFileInConflict();
void TestCreateDirectory();
private:
content::TestBrowserThreadBundle thread_bundle_;
base::ScopedTempDir temp_dir_;
scoped_ptr<APIUtil> api_util_;
FakeDriveServiceWrapper* fake_drive_service_;
FakeDriveUploader* fake_drive_uploader_;
scoped_ptr<FakeDriveServiceHelper> fake_drive_helper_;
DISALLOW_COPY_AND_ASSIGN(APIUtilTest);
};
void DidGetResourceID(Output* output,
GDataErrorCode error,
const std::string& resource_id) {
ASSERT_TRUE(output);
output->error = error;
output->resource_id = resource_id;
}
void DidGetLargestChangeStamp(Output* output,
GDataErrorCode error,
int64 largest_changestamp) {
ASSERT_TRUE(output);
output->error = error;
output->largest_changestamp = largest_changestamp;
}
void DidGetResourceList(GDataErrorCode* error_out,
scoped_ptr<ResourceList>* document_feed_out,
GDataErrorCode error,
scoped_ptr<ResourceList> document_feed) {
ASSERT_TRUE(error_out);
ASSERT_TRUE(document_feed_out);
*error_out = error;
*document_feed_out = document_feed.Pass();
}
void DidDownloadFile(Output* output,
GDataErrorCode error,
const std::string& file_md5,
int64 file_size,
const base::Time& updated_time,
scoped_ptr<webkit_blob::ScopedFile> file) {
ASSERT_TRUE(output);
ASSERT_TRUE(base::PathExists(file->path()));
output->error = error;
output->file_md5 = file_md5;
}
void DidUploadFile(Output* output,
GDataErrorCode error,
const std::string& resource_id,
const std::string& file_md5) {
ASSERT_TRUE(output);
output->error = error;
output->resource_id = resource_id;
output->file_md5 = file_md5;
}
void DidDeleteFile(GDataErrorCode* error_out,
GDataErrorCode error) {
ASSERT_TRUE(error);
*error_out = error;
}
void APIUtilTest::TestGetSyncRoot() {
LoadAccountMetadata();
const std::string sync_root_id = SetUpSyncRootDirectory();
Output output;
api_util()->GetDriveDirectoryForSyncRoot(
base::Bind(&DidGetResourceID, &output));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_SUCCESS, output.error);
EXPECT_EQ(sync_root_id, output.resource_id);
}
void APIUtilTest::TestCreateSyncRoot() {
LoadAccountMetadata();
Output output;
api_util()->GetDriveDirectoryForSyncRoot(
base::Bind(&DidGetResourceID, &output));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_CREATED, output.error);
EXPECT_FALSE(output.resource_id.empty());
VerifyTitleUniqueness(std::string(), // directory_resource_id
APIUtil::GetSyncRootDirectoryName(),
output.resource_id,
google_apis::ENTRY_KIND_FOLDER);
}
void APIUtilTest::TestCreateSyncRoot_Conflict() {
LoadAccountMetadata();
fake_drive_service()->set_make_directory_conflict(true);
Output output;
api_util()->GetDriveDirectoryForSyncRoot(
base::Bind(&DidGetResourceID, &output));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_SUCCESS, output.error);
EXPECT_FALSE(output.resource_id.empty());
// Verify that there is no duplicated directory on the remote side.
VerifyTitleUniqueness(std::string(), // directory_resource_id
APIUtil::GetSyncRootDirectoryName(),
output.resource_id,
google_apis::ENTRY_KIND_FOLDER);
}
void APIUtilTest::TestGetOriginDirectory() {
const std::string sync_root_id = SetUpSyncRootDirectory();
const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
Output output;
api_util()->GetDriveDirectoryForOrigin(
sync_root_id,
GURL(kOrigin),
base::Bind(&DidGetResourceID, &output));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_SUCCESS, output.error);
EXPECT_EQ(origin_root_id, output.resource_id);
}
void APIUtilTest::TestCreateOriginDirectory() {
const std::string& sync_root_id = SetUpSyncRootDirectory();
Output output;
api_util()->GetDriveDirectoryForOrigin(
sync_root_id,
GURL(kOrigin),
base::Bind(&DidGetResourceID, &output));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_CREATED, output.error);
EXPECT_FALSE(output.resource_id.empty());
VerifyTitleUniqueness(sync_root_id,
kOriginDirectoryName,
output.resource_id,
google_apis::ENTRY_KIND_FOLDER);
}
void APIUtilTest::TestCreateOriginDirectory_Conflict() {
fake_drive_service()->set_make_directory_conflict(true);
const std::string sync_root_id = SetUpSyncRootDirectory();
Output output;
api_util()->GetDriveDirectoryForOrigin(
sync_root_id,
GURL(kOrigin),
base::Bind(&DidGetResourceID, &output));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_SUCCESS, output.error);
EXPECT_FALSE(output.resource_id.empty());
// Verify that there is no duplicated directory on the remote side.
VerifyTitleUniqueness(sync_root_id,
kOriginDirectoryName,
output.resource_id,
google_apis::ENTRY_KIND_FOLDER);
}
void APIUtilTest::TestGetLargestChangeStamp() {
LoadAccountMetadata();
Output output;
api_util()->GetLargestChangeStamp(
base::Bind(&DidGetLargestChangeStamp, &output));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_SUCCESS, output.error);
EXPECT_EQ(654321, output.largest_changestamp);
}
void APIUtilTest::TestListFiles() {
fake_drive_service()->set_default_max_results(3);
const std::string sync_root_id = SetUpSyncRootDirectory();
const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
int kNumberOfFiles = 5;
for (int i = 0; i < kNumberOfFiles; ++i) {
scoped_ptr<ResourceEntry> file;
std::string file_content = base::StringPrintf("test content %d", i);
std::string file_title = base::StringPrintf("test_%d.txt", i);
SetUpFile(origin_root_id, file_content, file_title, &file);
}
GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
scoped_ptr<ResourceList> document_feed;
api_util()->ListFiles(
origin_root_id,
base::Bind(&DidGetResourceList, &error, &document_feed));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
EXPECT_EQ(3U, document_feed->entries().size());
// TODO(hidehiko): Use page token instead of feed url.
GURL feed_url;
ASSERT_TRUE(document_feed->GetNextFeedURL(&feed_url));
error = google_apis::GDATA_OTHER_ERROR;
document_feed.reset();
api_util()->ContinueListing(
feed_url.spec(),
base::Bind(&DidGetResourceList, &error, &document_feed));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
EXPECT_EQ(2U, document_feed->entries().size());
}
void APIUtilTest::TestListChanges() {
const int64 kStartChangestamp = 6;
const std::string sync_root_id = SetUpSyncRootDirectory();
const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
// Files should have changestamp #4+ since creating the sync root directory is
// #1, moving it out of 'My Drive' is #2, and creating the origin root
// directory is #3.
const int kNumberOfFiles = 5;
for (int i = 0; i < kNumberOfFiles; ++i) {
scoped_ptr<ResourceEntry> file;
std::string file_content = base::StringPrintf("test content %d", i);
std::string file_title = base::StringPrintf("test_%d.txt", i);
SetUpFile(origin_root_id, file_content, file_title, &file);
}
GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
scoped_ptr<ResourceList> document_feed;
api_util()->ListFiles(
origin_root_id,
base::Bind(&DidGetResourceList, &error, &document_feed));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
EXPECT_EQ(5U, document_feed->entries().size());
error = google_apis::GDATA_OTHER_ERROR;
document_feed.reset();
api_util()->ListChanges(
kStartChangestamp,
base::Bind(&DidGetResourceList, &error, &document_feed));
base::MessageLoop::current()->RunUntilIdle();
// There should be 3 files which have changestamp #6+.
EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
EXPECT_EQ(3U, document_feed->entries().size());
}
void APIUtilTest::TestDownloadFile() {
const std::string kFileContent = "test content";
const std::string kFileTitle = "test.txt";
const std::string sync_root_id = SetUpSyncRootDirectory();
const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
scoped_ptr<ResourceEntry> file;
SetUpFile(origin_root_id, kFileContent, kFileTitle, &file);
Output output;
api_util()->DownloadFile(
file->resource_id(),
"", // local_file_md5
base::Bind(&DidDownloadFile, &output));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(file->file_md5(), output.file_md5);
EXPECT_EQ(google_apis::HTTP_SUCCESS, output.error);
}
void APIUtilTest::TestDownloadFileInNotModified() {
const std::string kFileContent = "test content";
const std::string kFileTitle = "test.txt";
const std::string sync_root_id = SetUpSyncRootDirectory();
const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
scoped_ptr<ResourceEntry> file;
SetUpFile(origin_root_id, kFileContent, kFileTitle, &file);
// Since local file's hash value is equal to remote file's one, it is expected
// to cancel download the file and to return NOT_MODIFIED status code.
Output output;
api_util()->DownloadFile(
file->resource_id(),
file->file_md5(),
base::Bind(&DidDownloadFile, &output));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(file->file_md5(), output.file_md5);
EXPECT_EQ(google_apis::HTTP_NOT_MODIFIED, output.error);
}
void APIUtilTest::TestUploadNewFile() {
const std::string kFileTitle = "test.txt";
const base::FilePath kLocalFilePath(FPL("/tmp/dir/file"));
const std::string sync_root_id = SetUpSyncRootDirectory();
const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
Output output;
api_util()->UploadNewFile(
origin_root_id,
kLocalFilePath,
kFileTitle,
base::Bind(&DidUploadFile, &output));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_CREATED, output.error);
EXPECT_TRUE(!output.resource_id.empty());
VerifyTitleUniqueness(origin_root_id,
kFileTitle,
output.resource_id,
google_apis::ENTRY_KIND_FILE);
}
void APIUtilTest::TestUploadNewFile_ConflictWithFile() {
const std::string kFileTitle = "test.txt";
const base::FilePath kLocalFilePath(FPL("/tmp/dir/file"));
const std::string sync_root_id = SetUpSyncRootDirectory();
const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
fake_drive_uploader()->set_make_file_conflict(true);
Output output;
api_util()->UploadNewFile(
origin_root_id,
kLocalFilePath,
kFileTitle,
base::Bind(&DidUploadFile, &output));
base::MessageLoop::current()->RunUntilIdle();
// HTTP_CONFLICT error must be returned with empty resource_id.
EXPECT_EQ(google_apis::HTTP_CONFLICT, output.error);
EXPECT_TRUE(!output.resource_id.empty());
// Verify that there is no duplicated file on the remote side.
VerifyTitleUniqueness(origin_root_id,
kFileTitle,
output.resource_id,
google_apis::ENTRY_KIND_FILE);
}
void APIUtilTest::TestUploadExistingFile() {
const base::FilePath kLocalFilePath(FPL("/tmp/dir/file"));
const std::string kFileContent = "test content";
const std::string kFileTitle = "test.txt";
const std::string sync_root_id = SetUpSyncRootDirectory();
const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
scoped_ptr<ResourceEntry> file;
SetUpFile(origin_root_id, kFileContent, kFileTitle, &file);
Output output;
api_util()->UploadExistingFile(
file->resource_id(),
file->file_md5(),
kLocalFilePath,
base::Bind(&DidUploadFile, &output));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_SUCCESS, output.error);
EXPECT_EQ(file->resource_id(), output.resource_id);
VerifyTitleUniqueness(origin_root_id,
file->title(),
file->resource_id(),
file->kind());
}
void APIUtilTest::TestUploadExistingFileInConflict() {
const base::FilePath kLocalFilePath(FPL("/tmp/dir/file"));
const std::string kFileContent = "test content";
const std::string kFileTitle = "test.txt";
const std::string sync_root_id = SetUpSyncRootDirectory();
const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
scoped_ptr<ResourceEntry> file;
SetUpFile(origin_root_id, kFileContent, kFileTitle, &file);
// Since remote file's hash value is different from the expected one, it is
// expected to cancel upload the file and to return CONFLICT status code.
const std::string kExpectedRemoteFileMD5 = "123456";
Output output;
api_util()->UploadExistingFile(
file->resource_id(),
kExpectedRemoteFileMD5,
kLocalFilePath,
base::Bind(&DidUploadFile, &output));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_CONFLICT, output.error);
EXPECT_TRUE(output.resource_id.empty());
// Verify that there is no duplicated file on the remote side.
VerifyTitleUniqueness(origin_root_id,
file->title(),
file->resource_id(),
file->kind());
}
void APIUtilTest::TestDeleteFile() {
const std::string kFileContent = "test content";
const std::string kFileTitle = "test.txt";
const std::string sync_root_id = SetUpSyncRootDirectory();
const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
scoped_ptr<ResourceEntry> file;
SetUpFile(origin_root_id, kFileContent, kFileTitle, &file);
GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
api_util()->DeleteFile(file->resource_id(),
file->file_md5(),
base::Bind(&DidDeleteFile, &error));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
VerifyFileDeletion(origin_root_id, kFileTitle);
}
void APIUtilTest::TestDeleteFileInConflict() {
const std::string kFileContent = "test content";
const std::string kFileTitle = "test.txt";
const std::string sync_root_id = SetUpSyncRootDirectory();
const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
scoped_ptr<ResourceEntry> file;
SetUpFile(origin_root_id, kFileContent, kFileTitle, &file);
// Since remote file's hash value is different from the expected one, it is
// expected to cancel delete the file and to return CONFLICT status code.
const std::string kExpectedRemoteFileMD5 = "123456";
GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
api_util()->DeleteFile(file->resource_id(),
kExpectedRemoteFileMD5,
base::Bind(&DidDeleteFile, &error));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_CONFLICT, error);
// Verify that the conflict file was not deleted on the remote side.
VerifyTitleUniqueness(origin_root_id,
file->title(),
file->resource_id(),
file->kind());
}
void APIUtilTest::TestCreateDirectory() {
const std::string kDirectoryTitle("directory");
const std::string sync_root_id = SetUpSyncRootDirectory();
const std::string origin_root_id = SetUpOriginRootDirectory(sync_root_id);
Output output;
api_util()->CreateDirectory(
origin_root_id,
kDirectoryTitle,
base::Bind(&DidGetResourceID, &output));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_CREATED, output.error);
EXPECT_FALSE(output.resource_id.empty());
VerifyTitleUniqueness(origin_root_id,
kDirectoryTitle,
output.resource_id,
google_apis::ENTRY_KIND_FOLDER);
}
TEST_F(APIUtilTest, GetSyncRoot) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestGetSyncRoot();
}
TEST_F(APIUtilTest, GetSyncRoot_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestGetSyncRoot();
}
TEST_F(APIUtilTest, CreateSyncRoot) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestCreateSyncRoot();
}
TEST_F(APIUtilTest, CreateSyncRoot_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestCreateSyncRoot();
}
TEST_F(APIUtilTest, CreateSyncRoot_Conflict) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestCreateSyncRoot_Conflict();
}
TEST_F(APIUtilTest, CreateSyncRoot_Conflict_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestCreateSyncRoot_Conflict();
}
TEST_F(APIUtilTest, GetOriginDirectory) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestGetOriginDirectory();
}
TEST_F(APIUtilTest, GetOriginDirectory_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestGetOriginDirectory();
}
TEST_F(APIUtilTest, CreateOriginDirectory) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestCreateOriginDirectory();
}
TEST_F(APIUtilTest, CreateOriginDirectory_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestCreateOriginDirectory();
}
TEST_F(APIUtilTest, CreateOriginDirectory_Conflict) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestCreateOriginDirectory_Conflict();
}
TEST_F(APIUtilTest, CreateOriginDirectory_Conflict_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestCreateOriginDirectory_Conflict();
}
TEST_F(APIUtilTest, GetLargestChangeStamp) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestGetLargestChangeStamp();
}
TEST_F(APIUtilTest, GetLargestChangeStamp_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestGetLargestChangeStamp();
}
TEST_F(APIUtilTest, ListFiles) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestListFiles();
}
TEST_F(APIUtilTest, ListFiles_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestListFiles();
}
TEST_F(APIUtilTest, ListChanges) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestListChanges();
}
TEST_F(APIUtilTest, ListChanges_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestListChanges();
}
TEST_F(APIUtilTest, DownloadFile) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestDownloadFile();
}
TEST_F(APIUtilTest, DownloadFile_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestDownloadFile();
}
TEST_F(APIUtilTest, DownloadFileInNotModified) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestDownloadFileInNotModified();
}
TEST_F(APIUtilTest, DownloadFileInNotModified_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestDownloadFileInNotModified();
}
TEST_F(APIUtilTest, UploadNewFile) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestUploadNewFile();
}
TEST_F(APIUtilTest, UploadNewFile_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestUploadNewFile();
}
TEST_F(APIUtilTest, UploadNewFile_ConflictWithFile) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestUploadNewFile_ConflictWithFile();
}
TEST_F(APIUtilTest, UploadNewFile_ConflictWithFile_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestUploadNewFile_ConflictWithFile();
}
TEST_F(APIUtilTest, UploadExistingFile) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestUploadExistingFile();
}
TEST_F(APIUtilTest, UploadExistingFile_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestUploadExistingFile();
}
TEST_F(APIUtilTest, UploadExistingFileInConflict) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestUploadExistingFileInConflict();
}
TEST_F(APIUtilTest, UploadExistingFileInConflict_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestUploadExistingFileInConflict();
}
TEST_F(APIUtilTest, DeleteFile) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestDeleteFile();
}
TEST_F(APIUtilTest, DeleteFile_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestDeleteFile();
}
TEST_F(APIUtilTest, DeleteFileInConflict) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestDeleteFileInConflict();
}
TEST_F(APIUtilTest, DeleteFileInConflict_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestDeleteFileInConflict();
}
TEST_F(APIUtilTest, CreateDirectory) {
ASSERT_FALSE(IsDriveAPIDisabled());
TestCreateDirectory();
}
TEST_F(APIUtilTest, CreateDirectory_WAPI) {
ScopedDisableDriveAPI disable_drive_api;
TestCreateDirectory();
}
} // namespace drive_backend
} // namespace sync_file_system