drive: Add metadata parameters to InitiateUpload* methods

It is allowed to send metadata and file contents at the same time with Drive API.

BUG=260539
TEST=unit_tests

Review URL: https://codereview.chromium.org/139153006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@245466 0039d316-1c4b-4281-b951-d872f2087c98
parent 9bd35ea5
......@@ -113,6 +113,15 @@ void ParseFileResourceWithUploadRangeAndRun(
callback.Run(response, file_resource.Pass());
}
// Creates a Parents value which can be used as a part of request body.
scoped_ptr<base::DictionaryValue> CreateParentValue(
const std::string& file_id) {
scoped_ptr<base::DictionaryValue> parent(new base::DictionaryValue);
parent->SetString("kind", kParentLinkKind);
parent->SetString("id", file_id);
return parent.Pass();
}
} // namespace
namespace drive {
......@@ -602,7 +611,7 @@ InitiateUploadNewFileRequest::InitiateUploadNewFileRequest(
InitiateUploadNewFileRequest::~InitiateUploadNewFileRequest() {}
GURL InitiateUploadNewFileRequest::GetURL() const {
return url_generator_.GetInitiateUploadNewFileUrl();
return url_generator_.GetInitiateUploadNewFileUrl(!modified_date_.is_null());
}
net::URLFetcher::RequestType
......@@ -619,15 +628,16 @@ bool InitiateUploadNewFileRequest::GetContentData(
root.SetString("title", title_);
// Fill parent link.
{
scoped_ptr<base::DictionaryValue> parent(new base::DictionaryValue);
parent->SetString("kind", kParentLinkKind);
parent->SetString("id", parent_resource_id_);
scoped_ptr<base::ListValue> parents(new base::ListValue);
parents->Append(CreateParentValue(parent_resource_id_).release());
root.Set("parents", parents.release());
scoped_ptr<base::ListValue> parents(new base::ListValue);
parents->Append(parent.release());
if (!modified_date_.is_null())
root.SetString("modifiedDate", util::FormatTimeAsString(modified_date_));
root.Set("parents", parents.release());
if (!last_viewed_by_me_date_.is_null()) {
root.SetString("lastViewedByMeDate",
util::FormatTimeAsString(last_viewed_by_me_date_));
}
base::JSONWriter::Write(&root, upload_content);
......@@ -659,7 +669,8 @@ InitiateUploadExistingFileRequest::InitiateUploadExistingFileRequest(
InitiateUploadExistingFileRequest::~InitiateUploadExistingFileRequest() {}
GURL InitiateUploadExistingFileRequest::GetURL() const {
return url_generator_.GetInitiateUploadExistingFileUrl(resource_id_);
return url_generator_.GetInitiateUploadExistingFileUrl(
resource_id_, !modified_date_.is_null());
}
net::URLFetcher::RequestType
......@@ -675,6 +686,37 @@ InitiateUploadExistingFileRequest::GetExtraRequestHeaders() const {
return headers;
}
bool InitiateUploadExistingFileRequest::GetContentData(
std::string* upload_content_type,
std::string* upload_content) {
base::DictionaryValue root;
if (!parent_resource_id_.empty()) {
scoped_ptr<base::ListValue> parents(new base::ListValue);
parents->Append(CreateParentValue(parent_resource_id_).release());
root.Set("parents", parents.release());
}
if (!title_.empty())
root.SetString("title", title_);
if (!modified_date_.is_null())
root.SetString("modifiedDate", util::FormatTimeAsString(modified_date_));
if (!last_viewed_by_me_date_.is_null()) {
root.SetString("lastViewedByMeDate",
util::FormatTimeAsString(last_viewed_by_me_date_));
}
if (root.empty())
return false;
*upload_content_type = kContentTypeApplicationJson;
base::JSONWriter::Write(&root, upload_content);
DVLOG(1) << "InitiateUploadExistingFile data: " << *upload_content_type
<< ", [" << *upload_content << "]";
return true;
}
//============================ ResumeUploadRequest ===========================
ResumeUploadRequest::ResumeUploadRequest(
......
......@@ -624,6 +624,18 @@ class InitiateUploadNewFileRequest : public InitiateUploadRequestBase {
const InitiateUploadCallback& callback);
virtual ~InitiateUploadNewFileRequest();
// Optional parameters.
const base::Time& modified_date() const { return modified_date_; }
void set_modified_date(const base::Time& modified_date) {
modified_date_ = modified_date;
}
const base::Time& last_viewed_by_me_date() const {
return last_viewed_by_me_date_;
}
void set_last_viewed_by_me_date(const base::Time& last_viewed_by_me_date) {
last_viewed_by_me_date_ = last_viewed_by_me_date;
}
protected:
// UrlFetchRequestBase overrides.
virtual GURL GetURL() const OVERRIDE;
......@@ -636,6 +648,9 @@ class InitiateUploadNewFileRequest : public InitiateUploadRequestBase {
const std::string parent_resource_id_;
const std::string title_;
base::Time modified_date_;
base::Time last_viewed_by_me_date_;
DISALLOW_COPY_AND_ASSIGN(InitiateUploadNewFileRequest);
};
......@@ -659,17 +674,43 @@ class InitiateUploadExistingFileRequest : public InitiateUploadRequestBase {
const InitiateUploadCallback& callback);
virtual ~InitiateUploadExistingFileRequest();
// Optional parameters.
const std::string& parent_resource_id() const { return parent_resource_id_; }
void set_parent_resource_id(const std::string& parent_resource_id) {
parent_resource_id_ = parent_resource_id;
}
const std::string& title() const { return title_; }
void set_title(const std::string& title) { title_ = title; }
const base::Time& modified_date() const { return modified_date_; }
void set_modified_date(const base::Time& modified_date) {
modified_date_ = modified_date;
}
const base::Time& last_viewed_by_me_date() const {
return last_viewed_by_me_date_;
}
void set_last_viewed_by_me_date(const base::Time& last_viewed_by_me_date) {
last_viewed_by_me_date_ = last_viewed_by_me_date;
}
protected:
// UrlFetchRequestBase overrides.
virtual GURL GetURL() const OVERRIDE;
virtual net::URLFetcher::RequestType GetRequestType() const OVERRIDE;
virtual std::vector<std::string> GetExtraRequestHeaders() const OVERRIDE;
virtual bool GetContentData(std::string* upload_content_type,
std::string* upload_content) OVERRIDE;
private:
const DriveApiUrlGenerator url_generator_;
const std::string resource_id_;
const std::string etag_;
std::string parent_resource_id_;
std::string title_;
base::Time modified_date_;
base::Time last_viewed_by_me_date_;
DISALLOW_COPY_AND_ASSIGN(InitiateUploadExistingFileRequest);
};
......
......@@ -1257,6 +1257,60 @@ TEST_F(DriveApiRequestsTest, UploadNewLargeFileRequest) {
}
}
TEST_F(DriveApiRequestsTest, UploadNewFileWithMetadataRequest) {
const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
const base::Time::Exploded kLastViewedByMeDate =
{2013, 7, 0, 19, 15, 59, 13, 123};
// Set an expected url for uploading.
expected_upload_path_ = kTestUploadNewFilePath;
const char kTestContentType[] = "text/plain";
const std::string kTestContent(100, 'a');
GDataErrorCode error = GDATA_OTHER_ERROR;
GURL upload_url;
// Initiate uploading a new file to the directory with "parent_resource_id".
{
base::RunLoop run_loop;
drive::InitiateUploadNewFileRequest* request =
new drive::InitiateUploadNewFileRequest(
request_sender_.get(),
*url_generator_,
kTestContentType,
kTestContent.size(),
"parent_resource_id", // The resource id of the parent directory.
"new file title", // The title of the file being uploaded.
test_util::CreateQuitCallback(
&run_loop,
test_util::CreateCopyResultCallback(&error, &upload_url)));
request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
request->set_last_viewed_by_me_date(
base::Time::FromUTCExploded(kLastViewedByMeDate));
request_sender_->StartRequestWithRetry(request);
run_loop.Run();
}
EXPECT_EQ(HTTP_SUCCESS, error);
EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
EXPECT_EQ(base::Int64ToString(kTestContent.size()),
http_request_.headers["X-Upload-Content-Length"]);
EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable&setModifiedDate=true",
http_request_.relative_url);
EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
EXPECT_TRUE(http_request_.has_content);
EXPECT_EQ("{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
"\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
"\"parents\":[{\"id\":\"parent_resource_id\","
"\"kind\":\"drive#fileLink\"}],"
"\"title\":\"new file title\"}",
http_request_.content);
}
TEST_F(DriveApiRequestsTest, UploadExistingFileRequest) {
// Set an expected url for uploading.
expected_upload_path_ = kTestUploadExistingFilePath;
......@@ -1573,6 +1627,65 @@ TEST_F(DriveApiRequestsTest,
EXPECT_FALSE(new_entry.get());
}
TEST_F(DriveApiRequestsTest, UploadExistingFileWithMetadataRequest) {
const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
const base::Time::Exploded kLastViewedByMeDate =
{2013, 7, 0, 19, 15, 59, 13, 123};
// Set an expected url for uploading.
expected_upload_path_ = kTestUploadExistingFilePath;
const char kTestContentType[] = "text/plain";
const std::string kTestContent(100, 'a');
GDataErrorCode error = GDATA_OTHER_ERROR;
GURL upload_url;
// Initiate uploading a new file to the directory with "parent_resource_id".
{
base::RunLoop run_loop;
drive::InitiateUploadExistingFileRequest* request =
new drive::InitiateUploadExistingFileRequest(
request_sender_.get(),
*url_generator_,
kTestContentType,
kTestContent.size(),
"resource_id", // The resource id of the file to be overwritten.
kTestETag,
test_util::CreateQuitCallback(
&run_loop,
test_util::CreateCopyResultCallback(&error, &upload_url)));
request->set_parent_resource_id("new_parent_resource_id");
request->set_title("new file title");
request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
request->set_last_viewed_by_me_date(
base::Time::FromUTCExploded(kLastViewedByMeDate));
request_sender_->StartRequestWithRetry(request);
run_loop.Run();
}
EXPECT_EQ(HTTP_SUCCESS, error);
EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
EXPECT_EQ(base::Int64ToString(kTestContent.size()),
http_request_.headers["X-Upload-Content-Length"]);
EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
EXPECT_EQ("/upload/drive/v2/files/resource_id?"
"uploadType=resumable&setModifiedDate=true",
http_request_.relative_url);
EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
EXPECT_TRUE(http_request_.has_content);
EXPECT_EQ("{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
"\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
"\"parents\":[{\"id\":\"new_parent_resource_id\","
"\"kind\":\"drive#fileLink\"}],"
"\"title\":\"new file title\"}",
http_request_.content);
}
TEST_F(DriveApiRequestsTest, DownloadFileRequest) {
const base::FilePath kDownloadedFilePath =
temp_dir_.path().AppendASCII("cache_file");
......
......@@ -170,17 +170,31 @@ GURL DriveApiUrlGenerator::GetChildrenDeleteUrl(
net::EscapePath(child_id).c_str()));
}
GURL DriveApiUrlGenerator::GetInitiateUploadNewFileUrl() const {
return AddResumableUploadParam(
GURL DriveApiUrlGenerator::GetInitiateUploadNewFileUrl(
bool set_modified_date) const {
GURL url = AddResumableUploadParam(
base_url_.Resolve(kDriveV2InitiateUploadNewFileUrl));
// setModifiedDate is "false" by default.
if (set_modified_date)
url = net::AppendOrReplaceQueryParameter(url, "setModifiedDate", "true");
return url;
}
GURL DriveApiUrlGenerator::GetInitiateUploadExistingFileUrl(
const std::string& resource_id) const {
const GURL& url = base_url_.Resolve(
const std::string& resource_id,
bool set_modified_date) const {
GURL url = base_url_.Resolve(
kDriveV2InitiateUploadExistingFileUrlPrefix +
net::EscapePath(resource_id));
return AddResumableUploadParam(url);
url = AddResumableUploadParam(url);
// setModifiedDate is "false" by default.
if (set_modified_date)
url = net::AppendOrReplaceQueryParameter(url, "setModifiedDate", "true");
return url;
}
GURL DriveApiUrlGenerator::GenerateDownloadFileUrl(
......
......@@ -75,11 +75,12 @@ class DriveApiUrlGenerator {
const std::string& folder_id) const;
// Returns a URL to initiate uploading a new file.
GURL GetInitiateUploadNewFileUrl() const;
GURL GetInitiateUploadNewFileUrl(bool set_modified_date) const;
// Returns a URL to initiate uploading an existing file specified by
// |resource_id|.
GURL GetInitiateUploadExistingFileUrl(const std::string& resource_id) const;
GURL GetInitiateUploadExistingFileUrl(const std::string& resource_id,
bool set_modified_date) const;
// Generates a URL for downloading a file.
GURL GenerateDownloadFileUrl(const std::string& resource_id) const;
......
......@@ -345,45 +345,69 @@ TEST_F(DriveApiUrlGeneratorTest, GetChildrenDeleteUrl) {
}
TEST_F(DriveApiUrlGeneratorTest, GetInitiateUploadNewFileUrl) {
const bool kSetModifiedDate = true;
EXPECT_EQ(
"https://www.googleapis.com/upload/drive/v2/files?uploadType=resumable",
url_generator_.GetInitiateUploadNewFileUrl().spec());
url_generator_.GetInitiateUploadNewFileUrl(!kSetModifiedDate).spec());
EXPECT_EQ(
"http://127.0.0.1:12345/upload/drive/v2/files?uploadType=resumable",
test_url_generator_.GetInitiateUploadNewFileUrl().spec());
test_url_generator_.GetInitiateUploadNewFileUrl(
!kSetModifiedDate).spec());
EXPECT_EQ(
"http://127.0.0.1:12345/upload/drive/v2/files?uploadType=resumable&"
"setModifiedDate=true",
test_url_generator_.GetInitiateUploadNewFileUrl(
kSetModifiedDate).spec());
}
TEST_F(DriveApiUrlGeneratorTest, GetInitiateUploadExistingFileUrl) {
const bool kSetModifiedDate = true;
// |resource_id| should be embedded into the url.
EXPECT_EQ(
"https://www.googleapis.com/upload/drive/v2/files/0ADK06pfg"
"?uploadType=resumable",
url_generator_.GetInitiateUploadExistingFileUrl("0ADK06pfg").spec());
url_generator_.GetInitiateUploadExistingFileUrl(
"0ADK06pfg", !kSetModifiedDate).spec());
EXPECT_EQ(
"https://www.googleapis.com/upload/drive/v2/files/0Bz0bd074"
"?uploadType=resumable",
url_generator_.GetInitiateUploadExistingFileUrl("0Bz0bd074").spec());
url_generator_.GetInitiateUploadExistingFileUrl(
"0Bz0bd074", !kSetModifiedDate).spec());
EXPECT_EQ(
"https://www.googleapis.com/upload/drive/v2/files/file%3Afile_id"
"?uploadType=resumable",
url_generator_.GetInitiateUploadExistingFileUrl("file:file_id").spec());
url_generator_.GetInitiateUploadExistingFileUrl(
"file:file_id", !kSetModifiedDate).spec());
EXPECT_EQ(
"https://www.googleapis.com/upload/drive/v2/files/file%3Afile_id"
"?uploadType=resumable&setModifiedDate=true",
url_generator_.GetInitiateUploadExistingFileUrl(
"file:file_id", kSetModifiedDate).spec());
EXPECT_EQ(
"http://127.0.0.1:12345/upload/drive/v2/files/0ADK06pfg"
"?uploadType=resumable",
test_url_generator_.GetInitiateUploadExistingFileUrl(
"0ADK06pfg").spec());
"0ADK06pfg", !kSetModifiedDate).spec());
EXPECT_EQ(
"http://127.0.0.1:12345/upload/drive/v2/files/0Bz0bd074"
"?uploadType=resumable",
test_url_generator_.GetInitiateUploadExistingFileUrl(
"0Bz0bd074").spec());
"0Bz0bd074", !kSetModifiedDate).spec());
EXPECT_EQ(
"http://127.0.0.1:12345/upload/drive/v2/files/file%3Afile_id"
"?uploadType=resumable",
test_url_generator_.GetInitiateUploadExistingFileUrl(
"file:file_id").spec());
"file:file_id", !kSetModifiedDate).spec());
EXPECT_EQ(
"http://127.0.0.1:12345/upload/drive/v2/files/file%3Afile_id"
"?uploadType=resumable&setModifiedDate=true",
test_url_generator_.GetInitiateUploadExistingFileUrl(
"file:file_id", kSetModifiedDate).spec());
}
TEST_F(DriveApiUrlGeneratorTest, GenerateDownloadFileUrl) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment