diff options
author | hashimoto@chromium.org <hashimoto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-03 15:36:38 +0000 |
---|---|---|
committer | hashimoto@chromium.org <hashimoto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-03 15:36:38 +0000 |
commit | e13059c061f1088237796ae4968882eec106148c (patch) | |
tree | 9c8c83e6a305387e6adc358d629f4ee9eadc24e2 /google_apis | |
parent | f878230e9e87ae1f951b6194fcd63828b3e789b9 (diff) | |
download | chromium_src-e13059c061f1088237796ae4968882eec106148c.zip chromium_src-e13059c061f1088237796ae4968882eec106148c.tar.gz chromium_src-e13059c061f1088237796ae4968882eec106148c.tar.bz2 |
drive: Remove unused GData WAPI requests
GetResourceEntryReqeust is used by DriveAPIService
BUG=357038
TEST=build
Review URL: https://codereview.chromium.org/221883004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@261413 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'google_apis')
-rw-r--r-- | google_apis/drive/gdata_wapi_requests.cc | 647 | ||||
-rw-r--r-- | google_apis/drive/gdata_wapi_requests.h | 442 | ||||
-rw-r--r-- | google_apis/drive/gdata_wapi_requests_unittest.cc | 1423 |
3 files changed, 10 insertions, 2502 deletions
diff --git a/google_apis/drive/gdata_wapi_requests.cc b/google_apis/drive/gdata_wapi_requests.cc index 1ae8a95..4259217 100644 --- a/google_apis/drive/gdata_wapi_requests.cc +++ b/google_apis/drive/gdata_wapi_requests.cc @@ -4,202 +4,10 @@ #include "google_apis/drive/gdata_wapi_requests.h" -#include "base/location.h" -#include "base/sequenced_task_runner.h" -#include "base/task_runner_util.h" -#include "base/values.h" -#include "google_apis/drive/gdata_wapi_parser.h" #include "google_apis/drive/gdata_wapi_url_generator.h" -#include "google_apis/drive/request_sender.h" -#include "google_apis/drive/request_util.h" -#include "third_party/libxml/chromium/libxml_utils.h" - -using net::URLFetcher; namespace google_apis { -namespace { - -// Parses the JSON value to ResourceList. -scoped_ptr<ResourceList> ParseResourceListOnBlockingPool( - scoped_ptr<base::Value> value) { - DCHECK(value); - - return ResourceList::ExtractAndParse(*value); -} - -// Runs |callback| with |error| and |resource_list|, but replace the error code -// with GDATA_PARSE_ERROR, if there was a parsing error. -void DidParseResourceListOnBlockingPool( - const GetResourceListCallback& callback, - GDataErrorCode error, - scoped_ptr<ResourceList> resource_list) { - DCHECK(!callback.is_null()); - - // resource_list being NULL indicates there was a parsing error. - if (!resource_list) - error = GDATA_PARSE_ERROR; - - callback.Run(error, resource_list.Pass()); -} - -// Parses the JSON value to ResourceList on the blocking pool and runs -// |callback| on the UI thread once parsing is done. -void ParseResourceListAndRun( - scoped_refptr<base::TaskRunner> blocking_task_runner, - const GetResourceListCallback& callback, - GDataErrorCode error, - scoped_ptr<base::Value> value) { - DCHECK(!callback.is_null()); - - if (!value) { - callback.Run(error, scoped_ptr<ResourceList>()); - return; - } - - base::PostTaskAndReplyWithResult( - blocking_task_runner, - FROM_HERE, - base::Bind(&ParseResourceListOnBlockingPool, base::Passed(&value)), - base::Bind(&DidParseResourceListOnBlockingPool, callback, error)); -} - -// Parses the JSON value to AccountMetadata and runs |callback| on the UI -// thread once parsing is done. -void ParseAccounetMetadataAndRun(const GetAccountMetadataCallback& callback, - GDataErrorCode error, - scoped_ptr<base::Value> value) { - DCHECK(!callback.is_null()); - - if (!value) { - callback.Run(error, scoped_ptr<AccountMetadata>()); - return; - } - - // Parsing AccountMetadata is cheap enough to do on UI thread. - scoped_ptr<AccountMetadata> entry = - google_apis::AccountMetadata::CreateFrom(*value); - if (!entry) { - callback.Run(GDATA_PARSE_ERROR, scoped_ptr<AccountMetadata>()); - return; - } - - callback.Run(error, entry.Pass()); -} - -// Parses the |value| to ResourceEntry with error handling. -// This is designed to be used for ResumeUploadRequest and -// GetUploadStatusRequest. -scoped_ptr<ResourceEntry> ParseResourceEntry(scoped_ptr<base::Value> value) { - scoped_ptr<ResourceEntry> entry; - if (value.get()) { - entry = ResourceEntry::ExtractAndParse(*value); - - // Note: |value| may be NULL, in particular if the callback is for a - // failure. - if (!entry.get()) - LOG(WARNING) << "Invalid entry received on upload."; - } - - return entry.Pass(); -} - -// Extracts the open link url from the JSON Feed. Used by AuthorizeApp(). -void ParseOpenLinkAndRun(const std::string& app_id, - const AuthorizeAppCallback& callback, - GDataErrorCode error, - scoped_ptr<base::Value> value) { - DCHECK(!callback.is_null()); - - if (!value) { - callback.Run(error, GURL()); - return; - } - - // Parsing ResourceEntry is cheap enough to do on UI thread. - scoped_ptr<ResourceEntry> resource_entry = ParseResourceEntry(value.Pass()); - if (!resource_entry) { - callback.Run(GDATA_PARSE_ERROR, GURL()); - return; - } - - // Look for the link to open the file with the app with |app_id|. - const ScopedVector<Link>& resource_links = resource_entry->links(); - GURL open_link; - for (size_t i = 0; i < resource_links.size(); ++i) { - const Link& link = *resource_links[i]; - if (link.type() == Link::LINK_OPEN_WITH && link.app_id() == app_id) { - open_link = link.href(); - break; - } - } - - if (open_link.is_empty()) - error = GDATA_OTHER_ERROR; - - callback.Run(error, open_link); -} - -} // namespace - -//============================ GetResourceListRequest ======================== - -GetResourceListRequest::GetResourceListRequest( - RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const GURL& override_url, - int64 start_changestamp, - const std::string& search_string, - const std::string& directory_resource_id, - const GetResourceListCallback& callback) - : GetDataRequest( - sender, - base::Bind(&ParseResourceListAndRun, - make_scoped_refptr(sender->blocking_task_runner()), - callback)), - url_generator_(url_generator), - override_url_(override_url), - start_changestamp_(start_changestamp), - search_string_(search_string), - directory_resource_id_(directory_resource_id) { - DCHECK(!callback.is_null()); -} - -GetResourceListRequest::~GetResourceListRequest() {} - -GURL GetResourceListRequest::GetURL() const { - return url_generator_.GenerateResourceListUrl(override_url_, - start_changestamp_, - search_string_, - directory_resource_id_); -} - -//============================ SearchByTitleRequest ========================== - -SearchByTitleRequest::SearchByTitleRequest( - RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const std::string& title, - const std::string& directory_resource_id, - const GetResourceListCallback& callback) - : GetDataRequest( - sender, - base::Bind(&ParseResourceListAndRun, - make_scoped_refptr(sender->blocking_task_runner()), - callback)), - url_generator_(url_generator), - title_(title), - directory_resource_id_(directory_resource_id) { - DCHECK(!callback.is_null()); -} - -SearchByTitleRequest::~SearchByTitleRequest() {} - -GURL SearchByTitleRequest::GetURL() const { - return url_generator_.GenerateSearchByTitleUrl( - title_, directory_resource_id_); -} - //============================ GetResourceEntryRequest ======================= GetResourceEntryRequest::GetResourceEntryRequest( @@ -222,459 +30,4 @@ GURL GetResourceEntryRequest::GetURL() const { resource_id_, embed_origin_); } -//========================= GetAccountMetadataRequest ======================== - -GetAccountMetadataRequest::GetAccountMetadataRequest( - RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const GetAccountMetadataCallback& callback, - bool include_installed_apps) - : GetDataRequest(sender, - base::Bind(&ParseAccounetMetadataAndRun, callback)), - url_generator_(url_generator), - include_installed_apps_(include_installed_apps) { - DCHECK(!callback.is_null()); -} - -GetAccountMetadataRequest::~GetAccountMetadataRequest() {} - -GURL GetAccountMetadataRequest::GetURL() const { - return url_generator_.GenerateAccountMetadataUrl(include_installed_apps_); -} - -//=========================== DeleteResourceRequest ========================== - -DeleteResourceRequest::DeleteResourceRequest( - RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const EntryActionCallback& callback, - const std::string& resource_id, - const std::string& etag) - : EntryActionRequest(sender, callback), - url_generator_(url_generator), - resource_id_(resource_id), - etag_(etag) { - DCHECK(!callback.is_null()); -} - -DeleteResourceRequest::~DeleteResourceRequest() {} - -GURL DeleteResourceRequest::GetURL() const { - return url_generator_.GenerateEditUrl(resource_id_); -} - -URLFetcher::RequestType DeleteResourceRequest::GetRequestType() const { - return URLFetcher::DELETE_REQUEST; -} - -std::vector<std::string> -DeleteResourceRequest::GetExtraRequestHeaders() const { - std::vector<std::string> headers; - headers.push_back(util::GenerateIfMatchHeader(etag_)); - return headers; -} - -//========================== CreateDirectoryRequest ========================== - -CreateDirectoryRequest::CreateDirectoryRequest( - RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const GetDataCallback& callback, - const std::string& parent_resource_id, - const std::string& directory_title) - : GetDataRequest(sender, callback), - url_generator_(url_generator), - parent_resource_id_(parent_resource_id), - directory_title_(directory_title) { - DCHECK(!callback.is_null()); -} - -CreateDirectoryRequest::~CreateDirectoryRequest() {} - -GURL CreateDirectoryRequest::GetURL() const { - return url_generator_.GenerateContentUrl(parent_resource_id_); -} - -URLFetcher::RequestType -CreateDirectoryRequest::GetRequestType() const { - return URLFetcher::POST; -} - -bool CreateDirectoryRequest::GetContentData(std::string* upload_content_type, - std::string* upload_content) { - upload_content_type->assign("application/atom+xml"); - XmlWriter xml_writer; - xml_writer.StartWriting(); - xml_writer.StartElement("entry"); - xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom"); - - xml_writer.StartElement("category"); - xml_writer.AddAttribute("scheme", - "http://schemas.google.com/g/2005#kind"); - xml_writer.AddAttribute("term", - "http://schemas.google.com/docs/2007#folder"); - xml_writer.EndElement(); // Ends "category" element. - - xml_writer.WriteElement("title", directory_title_); - - xml_writer.EndElement(); // Ends "entry" element. - xml_writer.StopWriting(); - upload_content->assign(xml_writer.GetWrittenString()); - DVLOG(1) << "CreateDirectory data: " << *upload_content_type << ", [" - << *upload_content << "]"; - return true; -} - -//=========================== RenameResourceRequest ========================== - -RenameResourceRequest::RenameResourceRequest( - RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const EntryActionCallback& callback, - const std::string& resource_id, - const std::string& new_title) - : EntryActionRequest(sender, callback), - url_generator_(url_generator), - resource_id_(resource_id), - new_title_(new_title) { - DCHECK(!callback.is_null()); -} - -RenameResourceRequest::~RenameResourceRequest() {} - -URLFetcher::RequestType RenameResourceRequest::GetRequestType() const { - return URLFetcher::PUT; -} - -std::vector<std::string> -RenameResourceRequest::GetExtraRequestHeaders() const { - std::vector<std::string> headers; - headers.push_back(util::kIfMatchAllHeader); - return headers; -} - -GURL RenameResourceRequest::GetURL() const { - return url_generator_.GenerateEditUrl(resource_id_); -} - -bool RenameResourceRequest::GetContentData(std::string* upload_content_type, - std::string* upload_content) { - upload_content_type->assign("application/atom+xml"); - XmlWriter xml_writer; - xml_writer.StartWriting(); - xml_writer.StartElement("entry"); - xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom"); - - xml_writer.WriteElement("title", new_title_); - - xml_writer.EndElement(); // Ends "entry" element. - xml_writer.StopWriting(); - upload_content->assign(xml_writer.GetWrittenString()); - DVLOG(1) << "RenameResourceRequest data: " << *upload_content_type << ", [" - << *upload_content << "]"; - return true; -} - -//=========================== AuthorizeAppRequest ========================== - -AuthorizeAppRequest::AuthorizeAppRequest( - RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const AuthorizeAppCallback& callback, - const std::string& resource_id, - const std::string& app_id) - : GetDataRequest(sender, - base::Bind(&ParseOpenLinkAndRun, app_id, callback)), - url_generator_(url_generator), - resource_id_(resource_id), - app_id_(app_id) { - DCHECK(!callback.is_null()); -} - -AuthorizeAppRequest::~AuthorizeAppRequest() {} - -URLFetcher::RequestType AuthorizeAppRequest::GetRequestType() const { - return URLFetcher::PUT; -} - -std::vector<std::string> -AuthorizeAppRequest::GetExtraRequestHeaders() const { - std::vector<std::string> headers; - headers.push_back(util::kIfMatchAllHeader); - return headers; -} - -bool AuthorizeAppRequest::GetContentData(std::string* upload_content_type, - std::string* upload_content) { - upload_content_type->assign("application/atom+xml"); - XmlWriter xml_writer; - xml_writer.StartWriting(); - xml_writer.StartElement("entry"); - xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom"); - xml_writer.AddAttribute("xmlns:docs", "http://schemas.google.com/docs/2007"); - xml_writer.WriteElement("docs:authorizedApp", app_id_); - - xml_writer.EndElement(); // Ends "entry" element. - xml_writer.StopWriting(); - upload_content->assign(xml_writer.GetWrittenString()); - DVLOG(1) << "AuthorizeAppRequest data: " << *upload_content_type << ", [" - << *upload_content << "]"; - return true; -} - -GURL AuthorizeAppRequest::GetURL() const { - return url_generator_.GenerateEditUrl(resource_id_); -} - -//======================= AddResourceToDirectoryRequest ====================== - -AddResourceToDirectoryRequest::AddResourceToDirectoryRequest( - RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const EntryActionCallback& callback, - const std::string& parent_resource_id, - const std::string& resource_id) - : EntryActionRequest(sender, callback), - url_generator_(url_generator), - parent_resource_id_(parent_resource_id), - resource_id_(resource_id) { - DCHECK(!callback.is_null()); -} - -AddResourceToDirectoryRequest::~AddResourceToDirectoryRequest() {} - -GURL AddResourceToDirectoryRequest::GetURL() const { - return url_generator_.GenerateContentUrl(parent_resource_id_); -} - -URLFetcher::RequestType -AddResourceToDirectoryRequest::GetRequestType() const { - return URLFetcher::POST; -} - -bool AddResourceToDirectoryRequest::GetContentData( - std::string* upload_content_type, std::string* upload_content) { - upload_content_type->assign("application/atom+xml"); - XmlWriter xml_writer; - xml_writer.StartWriting(); - xml_writer.StartElement("entry"); - xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom"); - - xml_writer.WriteElement( - "id", url_generator_.GenerateEditUrlWithoutParams(resource_id_).spec()); - - xml_writer.EndElement(); // Ends "entry" element. - xml_writer.StopWriting(); - upload_content->assign(xml_writer.GetWrittenString()); - DVLOG(1) << "AddResourceToDirectoryRequest data: " << *upload_content_type - << ", [" << *upload_content << "]"; - return true; -} - -//==================== RemoveResourceFromDirectoryRequest ==================== - -RemoveResourceFromDirectoryRequest::RemoveResourceFromDirectoryRequest( - RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const EntryActionCallback& callback, - const std::string& parent_resource_id, - const std::string& document_resource_id) - : EntryActionRequest(sender, callback), - url_generator_(url_generator), - resource_id_(document_resource_id), - parent_resource_id_(parent_resource_id) { - DCHECK(!callback.is_null()); -} - -RemoveResourceFromDirectoryRequest::~RemoveResourceFromDirectoryRequest() { -} - -GURL RemoveResourceFromDirectoryRequest::GetURL() const { - return url_generator_.GenerateResourceUrlForRemoval( - parent_resource_id_, resource_id_); -} - -URLFetcher::RequestType -RemoveResourceFromDirectoryRequest::GetRequestType() const { - return URLFetcher::DELETE_REQUEST; -} - -std::vector<std::string> -RemoveResourceFromDirectoryRequest::GetExtraRequestHeaders() const { - std::vector<std::string> headers; - headers.push_back(util::kIfMatchAllHeader); - return headers; -} - -//======================= InitiateUploadNewFileRequest ======================= - -InitiateUploadNewFileRequest::InitiateUploadNewFileRequest( - RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const InitiateUploadCallback& callback, - const std::string& content_type, - int64 content_length, - const std::string& parent_resource_id, - const std::string& title) - : InitiateUploadRequestBase(sender, callback, content_type, content_length), - url_generator_(url_generator), - parent_resource_id_(parent_resource_id), - title_(title) { -} - -InitiateUploadNewFileRequest::~InitiateUploadNewFileRequest() {} - -GURL InitiateUploadNewFileRequest::GetURL() const { - return url_generator_.GenerateInitiateUploadNewFileUrl(parent_resource_id_); -} - -net::URLFetcher::RequestType -InitiateUploadNewFileRequest::GetRequestType() const { - return net::URLFetcher::POST; -} - -bool InitiateUploadNewFileRequest::GetContentData( - std::string* upload_content_type, - std::string* upload_content) { - upload_content_type->assign("application/atom+xml"); - XmlWriter xml_writer; - xml_writer.StartWriting(); - xml_writer.StartElement("entry"); - xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom"); - xml_writer.AddAttribute("xmlns:docs", - "http://schemas.google.com/docs/2007"); - xml_writer.WriteElement("title", title_); - xml_writer.EndElement(); // Ends "entry" element. - xml_writer.StopWriting(); - upload_content->assign(xml_writer.GetWrittenString()); - DVLOG(1) << "InitiateUploadNewFile: " << *upload_content_type << ", [" - << *upload_content << "]"; - return true; -} - -//===================== InitiateUploadExistingFileRequest ==================== - -InitiateUploadExistingFileRequest::InitiateUploadExistingFileRequest( - RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const InitiateUploadCallback& callback, - const std::string& content_type, - int64 content_length, - const std::string& resource_id, - const std::string& etag) - : InitiateUploadRequestBase(sender, callback, content_type, content_length), - url_generator_(url_generator), - resource_id_(resource_id), - etag_(etag) { -} - -InitiateUploadExistingFileRequest::~InitiateUploadExistingFileRequest() {} - -GURL InitiateUploadExistingFileRequest::GetURL() const { - return url_generator_.GenerateInitiateUploadExistingFileUrl(resource_id_); -} - -net::URLFetcher::RequestType -InitiateUploadExistingFileRequest::GetRequestType() const { - return net::URLFetcher::PUT; -} - -bool InitiateUploadExistingFileRequest::GetContentData( - std::string* upload_content_type, - std::string* upload_content) { - // According to the document there is no need to send the content-type. - // However, the server would return 500 server error without the - // content-type. - // As its workaround, send "text/plain" content-type here. - *upload_content_type = "text/plain"; - *upload_content = ""; - return true; -} - -std::vector<std::string> -InitiateUploadExistingFileRequest::GetExtraRequestHeaders() const { - std::vector<std::string> headers( - InitiateUploadRequestBase::GetExtraRequestHeaders()); - headers.push_back(util::GenerateIfMatchHeader(etag_)); - return headers; -} - -//============================ ResumeUploadRequest =========================== - -ResumeUploadRequest::ResumeUploadRequest( - RequestSender* sender, - const UploadRangeCallback& callback, - const ProgressCallback& progress_callback, - const GURL& upload_location, - int64 start_position, - int64 end_position, - int64 content_length, - const std::string& content_type, - const base::FilePath& local_file_path) - : ResumeUploadRequestBase(sender, - upload_location, - start_position, - end_position, - content_length, - content_type, - local_file_path), - callback_(callback), - progress_callback_(progress_callback) { - DCHECK(!callback_.is_null()); -} - -ResumeUploadRequest::~ResumeUploadRequest() {} - -void ResumeUploadRequest::OnRangeRequestComplete( - const UploadRangeResponse& response, scoped_ptr<base::Value> value) { - callback_.Run(response, ParseResourceEntry(value.Pass())); -} - -void ResumeUploadRequest::OnURLFetchUploadProgress( - const URLFetcher* source, int64 current, int64 total) { - if (!progress_callback_.is_null()) - progress_callback_.Run(current, total); -} - -//========================== GetUploadStatusRequest ========================== - -GetUploadStatusRequest::GetUploadStatusRequest( - RequestSender* sender, - const UploadRangeCallback& callback, - const GURL& upload_url, - int64 content_length) - : GetUploadStatusRequestBase(sender, upload_url, content_length), - callback_(callback) { - DCHECK(!callback.is_null()); -} - -GetUploadStatusRequest::~GetUploadStatusRequest() {} - -void GetUploadStatusRequest::OnRangeRequestComplete( - const UploadRangeResponse& response, scoped_ptr<base::Value> value) { - callback_.Run(response, ParseResourceEntry(value.Pass())); -} - -//========================== DownloadFileRequest ========================== - -DownloadFileRequest::DownloadFileRequest( - RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const DownloadActionCallback& download_action_callback, - const GetContentCallback& get_content_callback, - const ProgressCallback& progress_callback, - const std::string& resource_id, - const base::FilePath& output_file_path) - : DownloadFileRequestBase( - sender, - download_action_callback, - get_content_callback, - progress_callback, - url_generator.GenerateDownloadFileUrl(resource_id), - output_file_path) { -} - -DownloadFileRequest::~DownloadFileRequest() { -} - } // namespace google_apis diff --git a/google_apis/drive/gdata_wapi_requests.h b/google_apis/drive/gdata_wapi_requests.h index a4587d7..7e64906 100644 --- a/google_apis/drive/gdata_wapi_requests.h +++ b/google_apis/drive/gdata_wapi_requests.h @@ -6,96 +6,12 @@ #define GOOGLE_APIS_DRIVE_GDATA_WAPI_REQUESTS_H_ #include <string> -#include <vector> #include "google_apis/drive/base_requests.h" -#include "google_apis/drive/drive_common_callbacks.h" #include "google_apis/drive/gdata_wapi_url_generator.h" namespace google_apis { -class AccountMetadata; -class GDataWapiUrlGenerator; -class ResourceEntry; - -//============================ GetResourceListRequest ======================== - -// This class performs the request for fetching a resource list. -class GetResourceListRequest : public GetDataRequest { - public: - // override_url: - // If empty, a hard-coded base URL of the WAPI server is used to fetch - // the first page of the feed. This parameter is used for fetching 2nd - // page and onward. - // - // start_changestamp: - // This parameter specifies the starting point of a delta feed or 0 if a - // full feed is necessary. - // - // search_string: - // If non-empty, fetches a list of resources that match the search - // string. - // - // directory_resource_id: - // If non-empty, fetches a list of resources in a particular directory. - // - // callback: - // Called once the feed is fetched. Must not be null. - GetResourceListRequest(RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const GURL& override_url, - int64 start_changestamp, - const std::string& search_string, - const std::string& directory_resource_id, - const GetResourceListCallback& callback); - virtual ~GetResourceListRequest(); - - protected: - // UrlFetchRequestBase overrides. - virtual GURL GetURL() const OVERRIDE; - - private: - const GDataWapiUrlGenerator url_generator_; - const GURL override_url_; - const int64 start_changestamp_; - const std::string search_string_; - const std::string directory_resource_id_; - - DISALLOW_COPY_AND_ASSIGN(GetResourceListRequest); -}; - -//============================ SearchByTitleRequest ========================== - -// This class performs the request for searching resources by title. -class SearchByTitleRequest : public GetDataRequest { - public: - // title: the search query. - // - // directory_resource_id: If given (non-empty), the search target is - // directly under the directory with the |directory_resource_id|. - // If empty, the search target is all the existing resources. - // - // callback: - // Called once the feed is fetched. Must not be null. - SearchByTitleRequest(RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const std::string& title, - const std::string& directory_resource_id, - const GetResourceListCallback& callback); - virtual ~SearchByTitleRequest(); - - protected: - // UrlFetchRequestBase overrides. - virtual GURL GetURL() const OVERRIDE; - - private: - const GDataWapiUrlGenerator url_generator_; - const std::string title_; - const std::string directory_resource_id_; - - DISALLOW_COPY_AND_ASSIGN(SearchByTitleRequest); -}; - //========================= GetResourceEntryRequest ========================== // This class performs the request for fetching a single resource entry. @@ -123,364 +39,6 @@ class GetResourceEntryRequest : public GetDataRequest { DISALLOW_COPY_AND_ASSIGN(GetResourceEntryRequest); }; -//========================= GetAccountMetadataRequest ======================== - -// Callback used for GetAccountMetadata(). -typedef base::Callback<void(GDataErrorCode error, - scoped_ptr<AccountMetadata> account_metadata)> - GetAccountMetadataCallback; - -// This class performs the request for fetching account metadata. -class GetAccountMetadataRequest : public GetDataRequest { - public: - // If |include_installed_apps| is set to true, the result should include - // the list of installed third party applications. - // |callback| must not be null. - GetAccountMetadataRequest(RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const GetAccountMetadataCallback& callback, - bool include_installed_apps); - virtual ~GetAccountMetadataRequest(); - - protected: - // UrlFetchRequestBase overrides. - virtual GURL GetURL() const OVERRIDE; - - private: - const GDataWapiUrlGenerator url_generator_; - const bool include_installed_apps_; - - DISALLOW_COPY_AND_ASSIGN(GetAccountMetadataRequest); -}; - -//=========================== DeleteResourceRequest ========================== - -// This class performs the request for deleting a resource. -// -// In WAPI, "gd:deleted" means that the resource was put in the trash, and -// "docs:removed" means its permanently gone. Since what the class does is to -// put the resource into trash, we have chosen "Delete" in the name, even though -// we are preferring the term "Remove" in drive/google_api code. -class DeleteResourceRequest : public EntryActionRequest { - public: - // |callback| must not be null. - DeleteResourceRequest(RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const EntryActionCallback& callback, - const std::string& resource_id, - const std::string& etag); - virtual ~DeleteResourceRequest(); - - protected: - // UrlFetchRequestBase overrides. - virtual GURL GetURL() const OVERRIDE; - virtual net::URLFetcher::RequestType GetRequestType() const OVERRIDE; - virtual std::vector<std::string> GetExtraRequestHeaders() const OVERRIDE; - - private: - const GDataWapiUrlGenerator url_generator_; - const std::string resource_id_; - const std::string etag_; - - DISALLOW_COPY_AND_ASSIGN(DeleteResourceRequest); -}; - -//========================== CreateDirectoryRequest ========================== - -// This class performs the request for creating a directory. -class CreateDirectoryRequest : public GetDataRequest { - public: - // A new directory will be created under a directory specified by - // |parent_resource_id|. If this parameter is empty, a new directory will - // be created in the root directory. - // |callback| must not be null. - CreateDirectoryRequest(RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const GetDataCallback& callback, - const std::string& parent_resource_id, - const std::string& directory_title); - virtual ~CreateDirectoryRequest(); - - protected: - // UrlFetchRequestBase overrides. - virtual GURL GetURL() const OVERRIDE; - virtual net::URLFetcher::RequestType GetRequestType() const OVERRIDE; - virtual bool GetContentData(std::string* upload_content_type, - std::string* upload_content) OVERRIDE; - - private: - const GDataWapiUrlGenerator url_generator_; - const std::string parent_resource_id_; - const std::string directory_title_; - - DISALLOW_COPY_AND_ASSIGN(CreateDirectoryRequest); -}; - -//=========================== RenameResourceRequest ========================== - -// This class performs the request for renaming a document/file/directory. -class RenameResourceRequest : public EntryActionRequest { - public: - // |callback| must not be null. - RenameResourceRequest(RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const EntryActionCallback& callback, - const std::string& resource_id, - const std::string& new_title); - virtual ~RenameResourceRequest(); - - protected: - // UrlFetchRequestBase overrides. - virtual net::URLFetcher::RequestType GetRequestType() const OVERRIDE; - virtual std::vector<std::string> GetExtraRequestHeaders() const OVERRIDE; - virtual GURL GetURL() const OVERRIDE; - virtual bool GetContentData(std::string* upload_content_type, - std::string* upload_content) OVERRIDE; - - private: - const GDataWapiUrlGenerator url_generator_; - const std::string resource_id_; - const std::string new_title_; - - DISALLOW_COPY_AND_ASSIGN(RenameResourceRequest); -}; - -//=========================== AuthorizeAppRequest ========================== - -// This class performs the request for authorizing an application specified -// by |app_id| to access a document specified by |resource_id|. -class AuthorizeAppRequest : public GetDataRequest { - public: - // |callback| must not be null. - AuthorizeAppRequest(RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const AuthorizeAppCallback& callback, - const std::string& resource_id, - const std::string& app_id); - virtual ~AuthorizeAppRequest(); - - protected: - // UrlFetchRequestBase overrides. - virtual net::URLFetcher::RequestType GetRequestType() const OVERRIDE; - virtual bool GetContentData(std::string* upload_content_type, - std::string* upload_content) OVERRIDE; - virtual std::vector<std::string> GetExtraRequestHeaders() const OVERRIDE; - virtual GURL GetURL() const OVERRIDE; - - private: - const GDataWapiUrlGenerator url_generator_; - const std::string resource_id_; - const std::string app_id_; - - DISALLOW_COPY_AND_ASSIGN(AuthorizeAppRequest); -}; - -//======================= AddResourceToDirectoryRequest ====================== - -// This class performs the request for adding a document/file/directory -// to a directory. -class AddResourceToDirectoryRequest : public EntryActionRequest { - public: - // |callback| must not be null. - AddResourceToDirectoryRequest(RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const EntryActionCallback& callback, - const std::string& parent_resource_id, - const std::string& resource_id); - virtual ~AddResourceToDirectoryRequest(); - - protected: - // UrlFetchRequestBase overrides. - virtual GURL GetURL() const OVERRIDE; - virtual net::URLFetcher::RequestType GetRequestType() const OVERRIDE; - virtual bool GetContentData(std::string* upload_content_type, - std::string* upload_content) OVERRIDE; - - private: - const GDataWapiUrlGenerator url_generator_; - const std::string parent_resource_id_; - const std::string resource_id_; - - DISALLOW_COPY_AND_ASSIGN(AddResourceToDirectoryRequest); -}; - -//==================== RemoveResourceFromDirectoryRequest ==================== - -// This class performs the request for removing a document/file/directory -// from a directory. -class RemoveResourceFromDirectoryRequest : public EntryActionRequest { - public: - // |callback| must not be null. - RemoveResourceFromDirectoryRequest(RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const EntryActionCallback& callback, - const std::string& parent_resource_id, - const std::string& resource_id); - virtual ~RemoveResourceFromDirectoryRequest(); - - protected: - // UrlFetchRequestBase overrides. - virtual GURL GetURL() const OVERRIDE; - virtual net::URLFetcher::RequestType GetRequestType() const OVERRIDE; - virtual std::vector<std::string> GetExtraRequestHeaders() const OVERRIDE; - - private: - const GDataWapiUrlGenerator url_generator_; - const std::string resource_id_; - const std::string parent_resource_id_; - - DISALLOW_COPY_AND_ASSIGN(RemoveResourceFromDirectoryRequest); -}; - -//======================= InitiateUploadNewFileRequest ======================= - -// This class performs the request for initiating the upload of a new file. -class InitiateUploadNewFileRequest : public InitiateUploadRequestBase { - public: - // |title| should be set. - // |parent_upload_url| should be the upload_url() of the parent directory. - // (resumable-create-media URL) - // See also the comments of InitiateUploadRequestBase for more details - // about the other parameters. - InitiateUploadNewFileRequest(RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const InitiateUploadCallback& callback, - const std::string& content_type, - int64 content_length, - const std::string& parent_resource_id, - const std::string& title); - virtual ~InitiateUploadNewFileRequest(); - - protected: - // UrlFetchRequestBase overrides. - virtual GURL GetURL() const OVERRIDE; - virtual net::URLFetcher::RequestType GetRequestType() const OVERRIDE; - virtual bool GetContentData(std::string* upload_content_type, - std::string* upload_content) OVERRIDE; - - private: - const GDataWapiUrlGenerator url_generator_; - const std::string parent_resource_id_; - const std::string title_; - - DISALLOW_COPY_AND_ASSIGN(InitiateUploadNewFileRequest); -}; - -//==================== InitiateUploadExistingFileRequest ===================== - -// This class performs the request for initiating the upload of an existing -// file. -class InitiateUploadExistingFileRequest - : public InitiateUploadRequestBase { - public: - // |upload_url| should be the upload_url() of the file - // (resumable-create-media URL) - // |etag| should be set if it is available to detect the upload confliction. - // See also the comments of InitiateUploadRequestBase for more details - // about the other parameters. - InitiateUploadExistingFileRequest(RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const InitiateUploadCallback& callback, - const std::string& content_type, - int64 content_length, - const std::string& resource_id, - const std::string& etag); - virtual ~InitiateUploadExistingFileRequest(); - - 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 GDataWapiUrlGenerator url_generator_; - const std::string resource_id_; - const std::string etag_; - - DISALLOW_COPY_AND_ASSIGN(InitiateUploadExistingFileRequest); -}; - -//============================ ResumeUploadRequest =========================== - -// Performs the request for resuming the upload of a file. -class ResumeUploadRequest : public ResumeUploadRequestBase { - public: - // See also ResumeUploadRequestBase's comment for parameters meaning. - // |callback| must not be null. - ResumeUploadRequest(RequestSender* sender, - const UploadRangeCallback& callback, - const ProgressCallback& progress_callback, - const GURL& upload_location, - int64 start_position, - int64 end_position, - int64 content_length, - const std::string& content_type, - const base::FilePath& local_file_path); - virtual ~ResumeUploadRequest(); - - protected: - // UploadRangeRequestBase overrides. - virtual void OnRangeRequestComplete( - const UploadRangeResponse& response, - scoped_ptr<base::Value> value) OVERRIDE; - // content::UrlFetcherDelegate overrides. - virtual void OnURLFetchUploadProgress(const net::URLFetcher* source, - int64 current, int64 total) OVERRIDE; - - private: - const UploadRangeCallback callback_; - const ProgressCallback progress_callback_; - - DISALLOW_COPY_AND_ASSIGN(ResumeUploadRequest); -}; - -//========================== GetUploadStatusRequest ========================== - -// Performs the request to request the current upload status of a file. -class GetUploadStatusRequest : public GetUploadStatusRequestBase { - public: - // See also GetUploadStatusRequestBase's comment for parameters meaning. - // |callback| must not be null. - GetUploadStatusRequest(RequestSender* sender, - const UploadRangeCallback& callback, - const GURL& upload_url, - int64 content_length); - virtual ~GetUploadStatusRequest(); - - protected: - // UploadRangeRequestBase overrides. - virtual void OnRangeRequestComplete( - const UploadRangeResponse& response, - scoped_ptr<base::Value> value) OVERRIDE; - - private: - const UploadRangeCallback callback_; - - DISALLOW_COPY_AND_ASSIGN(GetUploadStatusRequest); -}; - - -//========================== DownloadFileRequest ========================== - -// This class performs the request for downloading of a specified file. -class DownloadFileRequest : public DownloadFileRequestBase { - public: - // See also DownloadFileRequestBase's comment for parameters meaning. - DownloadFileRequest(RequestSender* sender, - const GDataWapiUrlGenerator& url_generator, - const DownloadActionCallback& download_action_callback, - const GetContentCallback& get_content_callback, - const ProgressCallback& progress_callback, - const std::string& resource_id, - const base::FilePath& output_file_path); - virtual ~DownloadFileRequest(); - - DISALLOW_COPY_AND_ASSIGN(DownloadFileRequest); -}; - } // namespace google_apis #endif // GOOGLE_APIS_DRIVE_GDATA_WAPI_REQUESTS_H_ diff --git a/google_apis/drive/gdata_wapi_requests_unittest.cc b/google_apis/drive/gdata_wapi_requests_unittest.cc index e302f23..b322dcb 100644 --- a/google_apis/drive/gdata_wapi_requests_unittest.cc +++ b/google_apis/drive/gdata_wapi_requests_unittest.cc @@ -2,19 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <algorithm> -#include <map> - #include "base/bind.h" -#include "base/file_util.h" -#include "base/files/file_path.h" -#include "base/files/scoped_temp_dir.h" -#include "base/json/json_reader.h" -#include "base/json/json_writer.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/stringprintf.h" #include "base/values.h" #include "google_apis/drive/dummy_auth_service.h" #include "google_apis/drive/gdata_wapi_parser.h" @@ -34,14 +24,10 @@ namespace google_apis { namespace { const char kTestUserAgent[] = "test-user-agent"; -const char kTestETag[] = "test_etag"; const char kTestDownloadPathPrefix[] = "/download/"; class GDataWapiRequestsTest : public testing::Test { public: - GDataWapiRequestsTest() { - } - virtual void SetUp() OVERRIDE { request_context_getter_ = new net::TestURLRequestContextGetter( message_loop_.message_loop_proxy()); @@ -51,35 +37,14 @@ class GDataWapiRequestsTest : public testing::Test { message_loop_.message_loop_proxy(), kTestUserAgent)); - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady()); test_server_.RegisterRequestHandler( - base::Bind(&test_util::HandleDownloadFileRequest, - test_server_.base_url(), - base::Unretained(&http_request_))); - test_server_.RegisterRequestHandler( base::Bind(&GDataWapiRequestsTest::HandleResourceFeedRequest, base::Unretained(this))); - test_server_.RegisterRequestHandler( - base::Bind(&GDataWapiRequestsTest::HandleMetadataRequest, - base::Unretained(this))); - test_server_.RegisterRequestHandler( - base::Bind(&GDataWapiRequestsTest::HandleCreateSessionRequest, - base::Unretained(this))); - test_server_.RegisterRequestHandler( - base::Bind(&GDataWapiRequestsTest::HandleUploadRequest, - base::Unretained(this))); - test_server_.RegisterRequestHandler( - base::Bind(&GDataWapiRequestsTest::HandleDownloadRequest, - base::Unretained(this))); GURL test_base_url = test_util::GetBaseUrlForTesting(test_server_.port()); url_generator_.reset(new GDataWapiUrlGenerator( test_base_url, test_base_url.Resolve(kTestDownloadPathPrefix))); - - received_bytes_ = 0; - content_length_ = 0; } protected: @@ -90,16 +55,6 @@ class GDataWapiRequestsTest : public testing::Test { const GURL absolute_url = test_server_.GetURL(request.relative_url); std::string remaining_path; - if (absolute_url.path() == "/feeds/default/private/full" && - request.method == net::test_server::METHOD_POST) { - // This is a request for copying a document. - // TODO(satorux): we should generate valid JSON data for the newly - // copied document but for now, just return "file_entry.json" - scoped_ptr<net::test_server::BasicHttpResponse> result( - test_util::CreateHttpResponseFromFile( - test_util::GetTestFilePath("gdata/file_entry.json"))); - return result.PassAs<net::test_server::HttpResponse>(); - } if (!test_util::RemovePrefix(absolute_url.path(), "/feeds/default/private/full", @@ -107,236 +62,34 @@ class GDataWapiRequestsTest : public testing::Test { return scoped_ptr<net::test_server::HttpResponse>(); } - if (remaining_path.empty()) { - // Process the default feed. + // Process a feed for a single resource ID. + const std::string resource_id = net::UnescapeURLComponent( + remaining_path.substr(1), net::UnescapeRule::URL_SPECIAL_CHARS); + if (resource_id == "file:2_file_resource_id") { scoped_ptr<net::test_server::BasicHttpResponse> result( test_util::CreateHttpResponseFromFile( - test_util::GetTestFilePath("gdata/root_feed.json"))); + test_util::GetTestFilePath("gdata/file_entry.json"))); return result.PassAs<net::test_server::HttpResponse>(); - } else { - // Process a feed for a single resource ID. - const std::string resource_id = net::UnescapeURLComponent( - remaining_path.substr(1), net::UnescapeRule::URL_SPECIAL_CHARS); - if (resource_id == "file:2_file_resource_id") { - scoped_ptr<net::test_server::BasicHttpResponse> result( - test_util::CreateHttpResponseFromFile( - test_util::GetTestFilePath("gdata/file_entry.json"))); - return result.PassAs<net::test_server::HttpResponse>(); - } else if (resource_id == "folder:root/contents" && - request.method == net::test_server::METHOD_POST) { - // This is a request for creating a directory in the root directory. - // TODO(satorux): we should generate valid JSON data for the newly - // created directory but for now, just return "directory_entry.json" - scoped_ptr<net::test_server::BasicHttpResponse> result( - test_util::CreateHttpResponseFromFile( - test_util::GetTestFilePath( - "gdata/directory_entry.json"))); - return result.PassAs<net::test_server::HttpResponse>(); - } else if (resource_id == - "folder:root/contents/file:2_file_resource_id" && - request.method == net::test_server::METHOD_DELETE) { - // This is a request for deleting a file from the root directory. - // TODO(satorux): Investigate what's returned from the server, and - // copy it. For now, just return a random file, as the contents don't - // matter. + } else if (resource_id == "invalid_resource_id") { + // Check if this is an authorization request for an app. + // This emulates to return invalid formatted result from the server. + if (request.method == net::test_server::METHOD_PUT && + request.content.find("<docs:authorizedApp>") != std::string::npos) { scoped_ptr<net::test_server::BasicHttpResponse> result( test_util::CreateHttpResponseFromFile( test_util::GetTestFilePath("gdata/testfile.txt"))); return result.PassAs<net::test_server::HttpResponse>(); - } else if (resource_id == "invalid_resource_id") { - // Check if this is an authorization request for an app. - // This emulates to return invalid formatted result from the server. - if (request.method == net::test_server::METHOD_PUT && - request.content.find("<docs:authorizedApp>") != std::string::npos) { - scoped_ptr<net::test_server::BasicHttpResponse> result( - test_util::CreateHttpResponseFromFile( - test_util::GetTestFilePath("gdata/testfile.txt"))); - return result.PassAs<net::test_server::HttpResponse>(); - } - } - } - - return scoped_ptr<net::test_server::HttpResponse>(); - } - - // Handles a request for fetching a metadata feed. - scoped_ptr<net::test_server::HttpResponse> HandleMetadataRequest( - const net::test_server::HttpRequest& request) { - http_request_ = request; - - const GURL absolute_url = test_server_.GetURL(request.relative_url); - if (absolute_url.path() != "/feeds/metadata/default") - return scoped_ptr<net::test_server::HttpResponse>(); - - scoped_ptr<net::test_server::BasicHttpResponse> result( - test_util::CreateHttpResponseFromFile( - test_util::GetTestFilePath( - "gdata/account_metadata.json"))); - if (absolute_url.query().find("include-installed-apps=true") == - string::npos) { - // Exclude the list of installed apps. - scoped_ptr<base::Value> parsed_content( - base::JSONReader::Read(result->content(), base::JSON_PARSE_RFC)); - CHECK(parsed_content); - - // Remove the install apps node. - base::DictionaryValue* dictionary_value; - CHECK(parsed_content->GetAsDictionary(&dictionary_value)); - dictionary_value->Remove("entry.docs$installedApp", NULL); - - // Write back it as the content of the result. - std::string content; - base::JSONWriter::Write(parsed_content.get(), &content); - result->set_content(content); - } - - return result.PassAs<net::test_server::HttpResponse>(); - } - - // Handles a request for creating a session for uploading. - scoped_ptr<net::test_server::HttpResponse> HandleCreateSessionRequest( - const net::test_server::HttpRequest& request) { - http_request_ = request; - - const GURL absolute_url = test_server_.GetURL(request.relative_url); - if (StartsWithASCII(absolute_url.path(), - "/feeds/upload/create-session/default/private/full", - true)) { // case sensitive - // This is an initiating upload URL. - scoped_ptr<net::test_server::BasicHttpResponse> http_response( - new net::test_server::BasicHttpResponse); - - // Check an ETag. - std::map<std::string, std::string>::const_iterator found = - request.headers.find("If-Match"); - if (found != request.headers.end() && - found->second != "*" && - found->second != kTestETag) { - http_response->set_code(net::HTTP_PRECONDITION_FAILED); - return http_response.PassAs<net::test_server::HttpResponse>(); - } - - // Check if the X-Upload-Content-Length is present. If yes, store the - // length of the file. - found = request.headers.find("X-Upload-Content-Length"); - if (found == request.headers.end() || - !base::StringToInt64(found->second, &content_length_)) { - return scoped_ptr<net::test_server::HttpResponse>(); - } - received_bytes_ = 0; - - http_response->set_code(net::HTTP_OK); - GURL upload_url; - // POST is used for a new file, and PUT is used for an existing file. - if (request.method == net::test_server::METHOD_POST) { - upload_url = test_server_.GetURL("/upload_new_file"); - } else if (request.method == net::test_server::METHOD_PUT) { - upload_url = test_server_.GetURL("/upload_existing_file"); - } else { - return scoped_ptr<net::test_server::HttpResponse>(); } - http_response->AddCustomHeader("Location", upload_url.spec()); - return http_response.PassAs<net::test_server::HttpResponse>(); } return scoped_ptr<net::test_server::HttpResponse>(); } - // Handles a request for uploading content. - scoped_ptr<net::test_server::HttpResponse> HandleUploadRequest( - const net::test_server::HttpRequest& request) { - http_request_ = request; - - const GURL absolute_url = test_server_.GetURL(request.relative_url); - if (absolute_url.path() != "/upload_new_file" && - absolute_url.path() != "/upload_existing_file") { - return scoped_ptr<net::test_server::HttpResponse>(); - } - - // TODO(satorux): We should create a correct JSON data for the uploaded - // file, but for now, just return file_entry.json. - scoped_ptr<net::test_server::BasicHttpResponse> response = - test_util::CreateHttpResponseFromFile( - test_util::GetTestFilePath("gdata/file_entry.json")); - // response.code() is set to SUCCESS. Change it to CREATED if it's a new - // file. - if (absolute_url.path() == "/upload_new_file") - response->set_code(net::HTTP_CREATED); - - // Check if the Content-Range header is present. This must be present if - // the request body is not empty. - if (!request.content.empty()) { - std::map<std::string, std::string>::const_iterator iter = - request.headers.find("Content-Range"); - if (iter == request.headers.end()) - return scoped_ptr<net::test_server::HttpResponse>(); - int64 length = 0; - int64 start_position = 0; - int64 end_position = 0; - if (!test_util::ParseContentRangeHeader(iter->second, - &start_position, - &end_position, - &length)) { - return scoped_ptr<net::test_server::HttpResponse>(); - } - EXPECT_EQ(start_position, received_bytes_); - EXPECT_EQ(length, content_length_); - // end_position is inclusive, but so +1 to change the range to byte size. - received_bytes_ = end_position + 1; - } - - // Add Range header to the response, based on the values of - // Content-Range header in the request. - // The header is annotated only when at least one byte is received. - if (received_bytes_ > 0) { - response->AddCustomHeader( - "Range", - "bytes=0-" + base::Int64ToString(received_bytes_ - 1)); - } - - // Change the code to RESUME_INCOMPLETE if upload is not complete. - if (received_bytes_ < content_length_) - response->set_code(static_cast<net::HttpStatusCode>(308)); - - return response.PassAs<net::test_server::HttpResponse>(); - } - - // Handles a request for downloading a file. - scoped_ptr<net::test_server::HttpResponse> HandleDownloadRequest( - const net::test_server::HttpRequest& request) { - http_request_ = request; - - const GURL absolute_url = test_server_.GetURL(request.relative_url); - std::string id; - if (!test_util::RemovePrefix(absolute_url.path(), - kTestDownloadPathPrefix, - &id)) { - return scoped_ptr<net::test_server::HttpResponse>(); - } - - // For testing, returns a text with |id| repeated 3 times. - scoped_ptr<net::test_server::BasicHttpResponse> response( - new net::test_server::BasicHttpResponse); - response->set_code(net::HTTP_OK); - response->set_content(id + id + id); - response->set_content_type("text/plain"); - return response.PassAs<net::test_server::HttpResponse>(); - } - base::MessageLoopForIO message_loop_; // Test server needs IO thread. net::test_server::EmbeddedTestServer test_server_; scoped_ptr<RequestSender> request_sender_; scoped_ptr<GDataWapiUrlGenerator> url_generator_; scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_; - base::ScopedTempDir temp_dir_; - - // These fields are used to keep the current upload state during a - // test case. These values are updated by the request from - // ResumeUploadRequest, and used to construct the response for - // both ResumeUploadRequest and GetUploadStatusRequest, to emulate - // the WAPI server. - int64 received_bytes_; - int64 content_length_; // The incoming HTTP request is saved so tests can verify the request // parameters like HTTP method (ex. some requests should use DELETE @@ -346,130 +99,6 @@ class GDataWapiRequestsTest : public testing::Test { } // namespace -TEST_F(GDataWapiRequestsTest, GetResourceListRequest_DefaultFeed) { - GDataErrorCode result_code = GDATA_OTHER_ERROR; - scoped_ptr<ResourceList> result_data; - - { - base::RunLoop run_loop; - GetResourceListRequest* request = new GetResourceListRequest( - request_sender_.get(), - *url_generator_, - GURL(), // Pass an empty URL to use the default feed - 0, // start changestamp - std::string(), // search string - std::string(), // directory resource ID - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &result_data))); - request_sender_->StartRequestWithRetry(request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method); - EXPECT_EQ("/feeds/default/private/full?v=3&alt=json&showroot=true&" - "showfolders=true&include-shared=true&max-results=500", - http_request_.relative_url); - - // Sanity check of the result. - scoped_ptr<ResourceList> expected( - ResourceList::ExtractAndParse( - *test_util::LoadJSONFile("gdata/root_feed.json"))); - ASSERT_TRUE(result_data); - EXPECT_EQ(expected->title(), result_data->title()); -} - -TEST_F(GDataWapiRequestsTest, GetResourceListRequest_ValidFeed) { - GDataErrorCode result_code = GDATA_OTHER_ERROR; - scoped_ptr<ResourceList> result_data; - - { - base::RunLoop run_loop; - GetResourceListRequest* request = new GetResourceListRequest( - request_sender_.get(), - *url_generator_, - test_server_.GetURL("/files/gdata/root_feed.json"), - 0, // start changestamp - std::string(), // search string - std::string(), // directory resource ID - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &result_data))); - request_sender_->StartRequestWithRetry(request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method); - EXPECT_EQ("/files/gdata/root_feed.json?v=3&alt=json&showroot=true&" - "showfolders=true&include-shared=true&max-results=500", - http_request_.relative_url); - - scoped_ptr<ResourceList> expected( - ResourceList::ExtractAndParse( - *test_util::LoadJSONFile("gdata/root_feed.json"))); - ASSERT_TRUE(result_data); - EXPECT_EQ(expected->title(), result_data->title()); -} - -TEST_F(GDataWapiRequestsTest, GetResourceListRequest_InvalidFeed) { - // testfile.txt exists but the response is not JSON, so it should - // emit a parse error instead. - GDataErrorCode result_code = GDATA_OTHER_ERROR; - scoped_ptr<ResourceList> result_data; - - { - base::RunLoop run_loop; - GetResourceListRequest* request = new GetResourceListRequest( - request_sender_.get(), - *url_generator_, - test_server_.GetURL("/files/gdata/testfile.txt"), - 0, // start changestamp - std::string(), // search string - std::string(), // directory resource ID - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &result_data))); - request_sender_->StartRequestWithRetry(request); - run_loop.Run(); - } - - EXPECT_EQ(GDATA_PARSE_ERROR, result_code); - EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method); - EXPECT_EQ("/files/gdata/testfile.txt?v=3&alt=json&showroot=true&" - "showfolders=true&include-shared=true&max-results=500", - http_request_.relative_url); - EXPECT_FALSE(result_data); -} - -TEST_F(GDataWapiRequestsTest, SearchByTitleRequest) { - GDataErrorCode result_code = GDATA_OTHER_ERROR; - scoped_ptr<ResourceList> result_data; - - { - base::RunLoop run_loop; - SearchByTitleRequest* request = new SearchByTitleRequest( - request_sender_.get(), - *url_generator_, - "search-title", - std::string(), // directory resource id - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &result_data))); - request_sender_->StartRequestWithRetry(request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method); - EXPECT_EQ("/feeds/default/private/full?v=3&alt=json&showroot=true&" - "showfolders=true&include-shared=true&max-results=500" - "&title=search-title&title-exact=true", - http_request_.relative_url); - EXPECT_TRUE(result_data); -} - TEST_F(GDataWapiRequestsTest, GetResourceEntryRequest_ValidResourceId) { GDataErrorCode result_code = GDATA_OTHER_ERROR; scoped_ptr<base::Value> result_data; @@ -526,1036 +155,4 @@ TEST_F(GDataWapiRequestsTest, GetResourceEntryRequest_InvalidResourceId) { ASSERT_FALSE(result_data); } -TEST_F(GDataWapiRequestsTest, GetAccountMetadataRequest) { - GDataErrorCode result_code = GDATA_OTHER_ERROR; - scoped_ptr<AccountMetadata> result_data; - - { - base::RunLoop run_loop; - GetAccountMetadataRequest* request = new GetAccountMetadataRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &result_data)), - true); // Include installed apps. - request_sender_->StartRequestWithRetry(request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method); - EXPECT_EQ("/feeds/metadata/default?v=3&alt=json&showroot=true" - "&include-installed-apps=true", - http_request_.relative_url); - - scoped_ptr<AccountMetadata> expected( - AccountMetadata::CreateFrom( - *test_util::LoadJSONFile("gdata/account_metadata.json"))); - - ASSERT_TRUE(result_data.get()); - EXPECT_EQ(expected->largest_changestamp(), - result_data->largest_changestamp()); - EXPECT_EQ(expected->quota_bytes_total(), - result_data->quota_bytes_total()); - EXPECT_EQ(expected->quota_bytes_used(), - result_data->quota_bytes_used()); - - // Sanity check for installed apps. - EXPECT_EQ(expected->installed_apps().size(), - result_data->installed_apps().size()); -} - -TEST_F(GDataWapiRequestsTest, - GetAccountMetadataRequestWithoutInstalledApps) { - GDataErrorCode result_code = GDATA_OTHER_ERROR; - scoped_ptr<AccountMetadata> result_data; - - { - base::RunLoop run_loop; - GetAccountMetadataRequest* request = new GetAccountMetadataRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &result_data)), - false); // Exclude installed apps. - request_sender_->StartRequestWithRetry(request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method); - EXPECT_EQ("/feeds/metadata/default?v=3&alt=json&showroot=true", - http_request_.relative_url); - - scoped_ptr<AccountMetadata> expected( - AccountMetadata::CreateFrom( - *test_util::LoadJSONFile("gdata/account_metadata.json"))); - - ASSERT_TRUE(result_data.get()); - EXPECT_EQ(expected->largest_changestamp(), - result_data->largest_changestamp()); - EXPECT_EQ(expected->quota_bytes_total(), - result_data->quota_bytes_total()); - EXPECT_EQ(expected->quota_bytes_used(), - result_data->quota_bytes_used()); - - // Installed apps shouldn't be included. - EXPECT_EQ(0U, result_data->installed_apps().size()); -} - -TEST_F(GDataWapiRequestsTest, DeleteResourceRequest) { - GDataErrorCode result_code = GDATA_OTHER_ERROR; - - { - base::RunLoop run_loop; - DeleteResourceRequest* request = new DeleteResourceRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code)), - "file:2_file_resource_id", - std::string()); - - request_sender_->StartRequestWithRetry(request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(net::test_server::METHOD_DELETE, http_request_.method); - EXPECT_EQ( - "/feeds/default/private/full/file%3A2_file_resource_id?v=3&alt=json" - "&showroot=true", - http_request_.relative_url); - EXPECT_EQ("*", http_request_.headers["If-Match"]); -} - -TEST_F(GDataWapiRequestsTest, DeleteResourceRequestWithETag) { - GDataErrorCode result_code = GDATA_OTHER_ERROR; - - { - base::RunLoop run_loop; - DeleteResourceRequest* request = new DeleteResourceRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code)), - "file:2_file_resource_id", - "etag"); - - request_sender_->StartRequestWithRetry(request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(net::test_server::METHOD_DELETE, http_request_.method); - EXPECT_EQ( - "/feeds/default/private/full/file%3A2_file_resource_id?v=3&alt=json" - "&showroot=true", - http_request_.relative_url); - EXPECT_EQ("etag", http_request_.headers["If-Match"]); -} - -TEST_F(GDataWapiRequestsTest, CreateDirectoryRequest) { - GDataErrorCode result_code = GDATA_OTHER_ERROR; - scoped_ptr<base::Value> result_data; - - // Create "new directory" in the root directory. - { - base::RunLoop run_loop; - CreateDirectoryRequest* request = new CreateDirectoryRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &result_data)), - "folder:root", - "new directory"); - - request_sender_->StartRequestWithRetry(request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method); - EXPECT_EQ("/feeds/default/private/full/folder%3Aroot/contents?v=3&alt=json" - "&showroot=true", - http_request_.relative_url); - EXPECT_EQ("application/atom+xml", http_request_.headers["Content-Type"]); - - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ("<?xml version=\"1.0\"?>\n" - "<entry xmlns=\"http://www.w3.org/2005/Atom\">\n" - " <category scheme=\"http://schemas.google.com/g/2005#kind\" " - "term=\"http://schemas.google.com/docs/2007#folder\"/>\n" - " <title>new directory</title>\n" - "</entry>\n", - http_request_.content); -} - -TEST_F(GDataWapiRequestsTest, RenameResourceRequest) { - GDataErrorCode result_code = GDATA_OTHER_ERROR; - - // Rename a file with a new name "New File". - { - base::RunLoop run_loop; - RenameResourceRequest* request = new RenameResourceRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code)), - "file:2_file_resource_id", - "New File"); - - request_sender_->StartRequestWithRetry(request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method); - EXPECT_EQ( - "/feeds/default/private/full/file%3A2_file_resource_id?v=3&alt=json" - "&showroot=true", - http_request_.relative_url); - EXPECT_EQ("application/atom+xml", http_request_.headers["Content-Type"]); - EXPECT_EQ("*", http_request_.headers["If-Match"]); - - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ("<?xml version=\"1.0\"?>\n" - "<entry xmlns=\"http://www.w3.org/2005/Atom\">\n" - " <title>New File</title>\n" - "</entry>\n", - http_request_.content); -} - -TEST_F(GDataWapiRequestsTest, AuthorizeAppRequest_ValidFeed) { - GDataErrorCode result_code = GDATA_OTHER_ERROR; - GURL result_data; - - // Authorize an app with APP_ID to access to a document. - { - base::RunLoop run_loop; - AuthorizeAppRequest* request = new AuthorizeAppRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &result_data)), - "file:2_file_resource_id", - "the_app_id"); - - request_sender_->StartRequestWithRetry(request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(GURL("https://entry1_open_with_link/"), result_data); - - EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method); - EXPECT_EQ("/feeds/default/private/full/file%3A2_file_resource_id" - "?v=3&alt=json&showroot=true", - http_request_.relative_url); - EXPECT_EQ("application/atom+xml", http_request_.headers["Content-Type"]); - EXPECT_EQ("*", http_request_.headers["If-Match"]); - - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ("<?xml version=\"1.0\"?>\n" - "<entry xmlns=\"http://www.w3.org/2005/Atom\" " - "xmlns:docs=\"http://schemas.google.com/docs/2007\">\n" - " <docs:authorizedApp>the_app_id</docs:authorizedApp>\n" - "</entry>\n", - http_request_.content); -} - -TEST_F(GDataWapiRequestsTest, AuthorizeAppRequest_NotFound) { - GDataErrorCode result_code = GDATA_OTHER_ERROR; - GURL result_data; - - // Authorize an app with APP_ID to access to a document. - { - base::RunLoop run_loop; - AuthorizeAppRequest* request = new AuthorizeAppRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &result_data)), - "file:2_file_resource_id", - "unauthorized_app_id"); - - request_sender_->StartRequestWithRetry(request); - run_loop.Run(); - } - - EXPECT_EQ(GDATA_OTHER_ERROR, result_code); - EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method); - EXPECT_EQ("/feeds/default/private/full/file%3A2_file_resource_id" - "?v=3&alt=json&showroot=true", - http_request_.relative_url); - EXPECT_EQ("application/atom+xml", http_request_.headers["Content-Type"]); - EXPECT_EQ("*", http_request_.headers["If-Match"]); - - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ("<?xml version=\"1.0\"?>\n" - "<entry xmlns=\"http://www.w3.org/2005/Atom\" " - "xmlns:docs=\"http://schemas.google.com/docs/2007\">\n" - " <docs:authorizedApp>unauthorized_app_id</docs:authorizedApp>\n" - "</entry>\n", - http_request_.content); -} - -TEST_F(GDataWapiRequestsTest, AuthorizeAppRequest_InvalidFeed) { - GDataErrorCode result_code = GDATA_OTHER_ERROR; - GURL result_data; - - // Authorize an app with APP_ID to access to a document but an invalid feed. - { - base::RunLoop run_loop; - AuthorizeAppRequest* request = new AuthorizeAppRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &result_data)), - "invalid_resource_id", - "APP_ID"); - - request_sender_->StartRequestWithRetry(request); - run_loop.Run(); - } - - EXPECT_EQ(GDATA_PARSE_ERROR, result_code); - EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method); - EXPECT_EQ("/feeds/default/private/full/invalid_resource_id" - "?v=3&alt=json&showroot=true", - http_request_.relative_url); - EXPECT_EQ("application/atom+xml", http_request_.headers["Content-Type"]); - EXPECT_EQ("*", http_request_.headers["If-Match"]); - - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ("<?xml version=\"1.0\"?>\n" - "<entry xmlns=\"http://www.w3.org/2005/Atom\" " - "xmlns:docs=\"http://schemas.google.com/docs/2007\">\n" - " <docs:authorizedApp>APP_ID</docs:authorizedApp>\n" - "</entry>\n", - http_request_.content); -} - -TEST_F(GDataWapiRequestsTest, AddResourceToDirectoryRequest) { - GDataErrorCode result_code = GDATA_OTHER_ERROR; - - // Add a file to the root directory. - { - base::RunLoop run_loop; - AddResourceToDirectoryRequest* request = - new AddResourceToDirectoryRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code)), - "folder:root", - "file:2_file_resource_id"); - - request_sender_->StartRequestWithRetry(request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method); - EXPECT_EQ("/feeds/default/private/full/folder%3Aroot/contents?v=3&alt=json" - "&showroot=true", - http_request_.relative_url); - EXPECT_EQ("application/atom+xml", http_request_.headers["Content-Type"]); - - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ(base::StringPrintf("<?xml version=\"1.0\"?>\n" - "<entry xmlns=\"http://www.w3.org/2005/Atom\">\n" - " <id>%sfeeds/default/private/full/" - "file%%3A2_file_resource_id</id>\n" - "</entry>\n", - test_server_.base_url().spec().c_str()), - http_request_.content); -} - -TEST_F(GDataWapiRequestsTest, RemoveResourceFromDirectoryRequest) { - GDataErrorCode result_code = GDATA_OTHER_ERROR; - - // Remove a file from the root directory. - { - base::RunLoop run_loop; - RemoveResourceFromDirectoryRequest* request = - new RemoveResourceFromDirectoryRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code)), - "folder:root", - "file:2_file_resource_id"); - - request_sender_->StartRequestWithRetry(request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - // DELETE method should be used, without the body content. - EXPECT_EQ(net::test_server::METHOD_DELETE, http_request_.method); - EXPECT_EQ("/feeds/default/private/full/folder%3Aroot/contents/" - "file%3A2_file_resource_id?v=3&alt=json&showroot=true", - http_request_.relative_url); - EXPECT_EQ("*", http_request_.headers["If-Match"]); - EXPECT_FALSE(http_request_.has_content); -} - -// This test exercises InitiateUploadNewFileRequest and -// ResumeUploadRequest for a scenario of uploading a new file. -TEST_F(GDataWapiRequestsTest, UploadNewFile) { - const std::string kUploadContent = "hello"; - const base::FilePath kTestFilePath = - temp_dir_.path().AppendASCII("upload_file.txt"); - ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kUploadContent)); - - GDataErrorCode result_code = GDATA_OTHER_ERROR; - GURL upload_url; - - // 1) Get the upload URL for uploading a new file. - { - base::RunLoop run_loop; - InitiateUploadNewFileRequest* initiate_request = - new InitiateUploadNewFileRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &upload_url)), - "text/plain", - kUploadContent.size(), - "folder:id", - "New file"); - request_sender_->StartRequestWithRetry(initiate_request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(test_server_.GetURL("/upload_new_file"), upload_url); - EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method); - // convert=false should be passed as files should be uploaded as-is. - EXPECT_EQ( - "/feeds/upload/create-session/default/private/full/folder%3Aid/contents" - "?convert=false&v=3&alt=json&showroot=true", - http_request_.relative_url); - EXPECT_EQ("text/plain", http_request_.headers["X-Upload-Content-Type"]); - EXPECT_EQ("application/atom+xml", http_request_.headers["Content-Type"]); - EXPECT_EQ(base::Int64ToString(kUploadContent.size()), - http_request_.headers["X-Upload-Content-Length"]); - - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ("<?xml version=\"1.0\"?>\n" - "<entry xmlns=\"http://www.w3.org/2005/Atom\" " - "xmlns:docs=\"http://schemas.google.com/docs/2007\">\n" - " <title>New file</title>\n" - "</entry>\n", - http_request_.content); - - // 2) Upload the content to the upload URL. - UploadRangeResponse response; - scoped_ptr<ResourceEntry> new_entry; - - { - base::RunLoop run_loop; - ResumeUploadRequest* resume_request = new ResumeUploadRequest( - request_sender_.get(), - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&response, &new_entry)), - ProgressCallback(), - upload_url, - 0, // start_position - kUploadContent.size(), // end_position (exclusive) - kUploadContent.size(), // content_length, - "text/plain", // content_type - kTestFilePath); - - request_sender_->StartRequestWithRetry(resume_request); - run_loop.Run(); - } - - // METHOD_PUT should be used to upload data. - EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method); - // Request should go to the upload URL. - EXPECT_EQ(upload_url.path(), http_request_.relative_url); - // Content-Range header should be added. - EXPECT_EQ("bytes 0-" + - base::Int64ToString(kUploadContent.size() -1) + "/" + - base::Int64ToString(kUploadContent.size()), - http_request_.headers["Content-Range"]); - // The upload content should be set in the HTTP request. - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ(kUploadContent, http_request_.content); - - // Check the response. - EXPECT_EQ(HTTP_CREATED, response.code); // Because it's a new file - // The start and end positions should be set to -1, if an upload is complete. - EXPECT_EQ(-1, response.start_position_received); - EXPECT_EQ(-1, response.end_position_received); -} - -// This test exercises InitiateUploadNewFileRequest and ResumeUploadRequest -// for a scenario of uploading a new *large* file, which requires multiple -// requests of ResumeUploadRequest. GetUploadRequest is also tested in this -// test case. -TEST_F(GDataWapiRequestsTest, UploadNewLargeFile) { - const size_t kMaxNumBytes = 10; - // This is big enough to cause multiple requests of ResumeUploadRequest - // as we are going to send at most kMaxNumBytes at a time. - // So, sending "kMaxNumBytes * 2 + 1" bytes ensures three - // ResumeUploadRequests, which are start, middle and last requests. - const std::string kUploadContent(kMaxNumBytes * 2 + 1, 'a'); - const base::FilePath kTestFilePath = - temp_dir_.path().AppendASCII("upload_file.txt"); - ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kUploadContent)); - - GDataErrorCode result_code = GDATA_OTHER_ERROR; - GURL upload_url; - - // 1) Get the upload URL for uploading a new file. - { - base::RunLoop run_loop; - InitiateUploadNewFileRequest* initiate_request = - new InitiateUploadNewFileRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &upload_url)), - "text/plain", - kUploadContent.size(), - "folder:id", - "New file"); - request_sender_->StartRequestWithRetry(initiate_request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(test_server_.GetURL("/upload_new_file"), upload_url); - EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method); - // convert=false should be passed as files should be uploaded as-is. - EXPECT_EQ( - "/feeds/upload/create-session/default/private/full/folder%3Aid/contents" - "?convert=false&v=3&alt=json&showroot=true", - http_request_.relative_url); - EXPECT_EQ("text/plain", http_request_.headers["X-Upload-Content-Type"]); - EXPECT_EQ("application/atom+xml", http_request_.headers["Content-Type"]); - EXPECT_EQ(base::Int64ToString(kUploadContent.size()), - http_request_.headers["X-Upload-Content-Length"]); - - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ("<?xml version=\"1.0\"?>\n" - "<entry xmlns=\"http://www.w3.org/2005/Atom\" " - "xmlns:docs=\"http://schemas.google.com/docs/2007\">\n" - " <title>New file</title>\n" - "</entry>\n", - http_request_.content); - - // 2) Before sending any data, check the current status. - // This is an edge case test for GetUploadStatusRequest - // (UploadRangeRequestBase). - { - UploadRangeResponse response; - scoped_ptr<ResourceEntry> new_entry; - - // Check the response by GetUploadStatusRequest. - { - base::RunLoop run_loop; - GetUploadStatusRequest* get_upload_status_request = - new GetUploadStatusRequest( - request_sender_.get(), - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&response, &new_entry)), - upload_url, - kUploadContent.size()); - request_sender_->StartRequestWithRetry(get_upload_status_request); - run_loop.Run(); - } - - // METHOD_PUT should be used to upload data. - EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method); - // Request should go to the upload URL. - EXPECT_EQ(upload_url.path(), http_request_.relative_url); - // Content-Range header should be added. - EXPECT_EQ("bytes */" + base::Int64ToString(kUploadContent.size()), - http_request_.headers["Content-Range"]); - EXPECT_TRUE(http_request_.has_content); - EXPECT_TRUE(http_request_.content.empty()); - - // Check the response. - EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code); - EXPECT_EQ(0, response.start_position_received); - EXPECT_EQ(0, response.end_position_received); - } - - // 3) Upload the content to the upload URL with multiple requests. - size_t num_bytes_consumed = 0; - for (size_t start_position = 0; start_position < kUploadContent.size(); - start_position += kMaxNumBytes) { - SCOPED_TRACE(testing::Message("start_position: ") << start_position); - - // The payload is at most kMaxNumBytes. - const size_t remaining_size = kUploadContent.size() - start_position; - const std::string payload = kUploadContent.substr( - start_position, std::min(kMaxNumBytes, remaining_size)); - num_bytes_consumed += payload.size(); - // The end position is exclusive. - const size_t end_position = start_position + payload.size(); - - UploadRangeResponse response; - scoped_ptr<ResourceEntry> new_entry; - - { - base::RunLoop run_loop; - ResumeUploadRequest* resume_request = new ResumeUploadRequest( - request_sender_.get(), - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&response, &new_entry)), - ProgressCallback(), - upload_url, - start_position, - end_position, - kUploadContent.size(), // content_length, - "text/plain", // content_type - kTestFilePath); - request_sender_->StartRequestWithRetry(resume_request); - run_loop.Run(); - } - - // METHOD_PUT should be used to upload data. - EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method); - // Request should go to the upload URL. - EXPECT_EQ(upload_url.path(), http_request_.relative_url); - // Content-Range header should be added. - EXPECT_EQ("bytes " + - base::Int64ToString(start_position) + "-" + - base::Int64ToString(end_position - 1) + "/" + - base::Int64ToString(kUploadContent.size()), - http_request_.headers["Content-Range"]); - // The upload content should be set in the HTTP request. - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ(payload, http_request_.content); - - // Check the response. - if (payload.size() == remaining_size) { - EXPECT_EQ(HTTP_CREATED, response.code); // Because it's a new file. - // The start and end positions should be set to -1, if an upload is - // complete. - EXPECT_EQ(-1, response.start_position_received); - EXPECT_EQ(-1, response.end_position_received); - // The upload process is completed, so exit from the loop. - break; - } - - EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code); - EXPECT_EQ(0, response.start_position_received); - EXPECT_EQ(static_cast<int64>(end_position), - response.end_position_received); - - // Check the response by GetUploadStatusRequest. - { - base::RunLoop run_loop; - GetUploadStatusRequest* get_upload_status_request = - new GetUploadStatusRequest( - request_sender_.get(), - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&response, &new_entry)), - upload_url, - kUploadContent.size()); - request_sender_->StartRequestWithRetry(get_upload_status_request); - run_loop.Run(); - } - - // METHOD_PUT should be used to upload data. - EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method); - // Request should go to the upload URL. - EXPECT_EQ(upload_url.path(), http_request_.relative_url); - // Content-Range header should be added. - EXPECT_EQ("bytes */" + base::Int64ToString(kUploadContent.size()), - http_request_.headers["Content-Range"]); - EXPECT_TRUE(http_request_.has_content); - EXPECT_TRUE(http_request_.content.empty()); - - // Check the response. - EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code); - EXPECT_EQ(0, response.start_position_received); - EXPECT_EQ(static_cast<int64>(end_position), - response.end_position_received); - } - - EXPECT_EQ(kUploadContent.size(), num_bytes_consumed); -} - -// This test exercises InitiateUploadNewFileRequest and ResumeUploadRequest -// for a scenario of uploading a new *empty* file. -// -// The test is almost identical to UploadNewFile. The only difference is the -// expectation for the Content-Range header. -TEST_F(GDataWapiRequestsTest, UploadNewEmptyFile) { - const std::string kUploadContent; - const base::FilePath kTestFilePath = - temp_dir_.path().AppendASCII("empty_file.txt"); - ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kUploadContent)); - - GDataErrorCode result_code = GDATA_OTHER_ERROR; - GURL upload_url; - - // 1) Get the upload URL for uploading a new file. - { - base::RunLoop run_loop; - InitiateUploadNewFileRequest* initiate_request = - new InitiateUploadNewFileRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &upload_url)), - "text/plain", - kUploadContent.size(), - "folder:id", - "New file"); - request_sender_->StartRequestWithRetry(initiate_request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(test_server_.GetURL("/upload_new_file"), upload_url); - EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method); - // convert=false should be passed as files should be uploaded as-is. - EXPECT_EQ( - "/feeds/upload/create-session/default/private/full/folder%3Aid/contents" - "?convert=false&v=3&alt=json&showroot=true", - http_request_.relative_url); - EXPECT_EQ("text/plain", http_request_.headers["X-Upload-Content-Type"]); - EXPECT_EQ("application/atom+xml", http_request_.headers["Content-Type"]); - EXPECT_EQ(base::Int64ToString(kUploadContent.size()), - http_request_.headers["X-Upload-Content-Length"]); - - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ("<?xml version=\"1.0\"?>\n" - "<entry xmlns=\"http://www.w3.org/2005/Atom\" " - "xmlns:docs=\"http://schemas.google.com/docs/2007\">\n" - " <title>New file</title>\n" - "</entry>\n", - http_request_.content); - - // 2) Upload the content to the upload URL. - UploadRangeResponse response; - scoped_ptr<ResourceEntry> new_entry; - - { - base::RunLoop run_loop; - ResumeUploadRequest* resume_request = new ResumeUploadRequest( - request_sender_.get(), - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&response, &new_entry)), - ProgressCallback(), - upload_url, - 0, // start_position - kUploadContent.size(), // end_position (exclusive) - kUploadContent.size(), // content_length, - "text/plain", // content_type - kTestFilePath); - request_sender_->StartRequestWithRetry(resume_request); - run_loop.Run(); - } - - // METHOD_PUT should be used to upload data. - EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method); - // Request should go to the upload URL. - EXPECT_EQ(upload_url.path(), http_request_.relative_url); - // Content-Range header should not exit if the content is empty. - // We should not generate the header with an invalid value "bytes 0--1/0". - EXPECT_EQ(0U, http_request_.headers.count("Content-Range")); - // The upload content should be set in the HTTP request. - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ(kUploadContent, http_request_.content); - - // Check the response. - EXPECT_EQ(HTTP_CREATED, response.code); // Because it's a new file. - // The start and end positions should be set to -1, if an upload is complete. - EXPECT_EQ(-1, response.start_position_received); - EXPECT_EQ(-1, response.end_position_received); -} - -// This test exercises InitiateUploadExistingFileRequest and -// ResumeUploadRequest for a scenario of updating an existing file. -TEST_F(GDataWapiRequestsTest, UploadExistingFile) { - const std::string kUploadContent = "hello"; - const base::FilePath kTestFilePath = - temp_dir_.path().AppendASCII("upload_file.txt"); - ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kUploadContent)); - - GDataErrorCode result_code = GDATA_OTHER_ERROR; - GURL upload_url; - - // 1) Get the upload URL for uploading an existing file. - { - base::RunLoop run_loop; - InitiateUploadExistingFileRequest* initiate_request = - new InitiateUploadExistingFileRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &upload_url)), - "text/plain", - kUploadContent.size(), - "file:foo", - std::string() /* etag */); - request_sender_->StartRequestWithRetry(initiate_request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(test_server_.GetURL("/upload_existing_file"), upload_url); - // For updating an existing file, METHOD_PUT should be used. - EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method); - // convert=false should be passed as files should be uploaded as-is. - EXPECT_EQ("/feeds/upload/create-session/default/private/full/file%3Afoo" - "?convert=false&v=3&alt=json&showroot=true", - http_request_.relative_url); - // Even though the body is empty, the content type should be set to - // "text/plain". - EXPECT_EQ("text/plain", http_request_.headers["Content-Type"]); - EXPECT_EQ("text/plain", http_request_.headers["X-Upload-Content-Type"]); - EXPECT_EQ(base::Int64ToString(kUploadContent.size()), - http_request_.headers["X-Upload-Content-Length"]); - // For updating an existing file, an empty body should be attached (PUT - // requires a body) - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ("", http_request_.content); - EXPECT_EQ("*", http_request_.headers["If-Match"]); - - // 2) Upload the content to the upload URL. - UploadRangeResponse response; - scoped_ptr<ResourceEntry> new_entry; - - { - base::RunLoop run_loop; - ResumeUploadRequest* resume_request = new ResumeUploadRequest( - request_sender_.get(), - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&response, &new_entry)), - ProgressCallback(), - upload_url, - 0, // start_position - kUploadContent.size(), // end_position (exclusive) - kUploadContent.size(), // content_length, - "text/plain", // content_type - kTestFilePath); - - request_sender_->StartRequestWithRetry(resume_request); - run_loop.Run(); - } - - // METHOD_PUT should be used to upload data. - EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method); - // Request should go to the upload URL. - EXPECT_EQ(upload_url.path(), http_request_.relative_url); - // Content-Range header should be added. - EXPECT_EQ("bytes 0-" + - base::Int64ToString(kUploadContent.size() -1) + "/" + - base::Int64ToString(kUploadContent.size()), - http_request_.headers["Content-Range"]); - // The upload content should be set in the HTTP request. - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ(kUploadContent, http_request_.content); - - // Check the response. - EXPECT_EQ(HTTP_SUCCESS, response.code); // Because it's an existing file. - // The start and end positions should be set to -1, if an upload is complete. - EXPECT_EQ(-1, response.start_position_received); - EXPECT_EQ(-1, response.end_position_received); -} - -// This test exercises InitiateUploadExistingFileRequest and -// ResumeUploadRequest for a scenario of updating an existing file. -TEST_F(GDataWapiRequestsTest, UploadExistingFileWithETag) { - const std::string kUploadContent = "hello"; - const base::FilePath kTestFilePath = - temp_dir_.path().AppendASCII("upload_file.txt"); - ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kUploadContent)); - - GDataErrorCode result_code = GDATA_OTHER_ERROR; - GURL upload_url; - - // 1) Get the upload URL for uploading an existing file. - { - base::RunLoop run_loop; - InitiateUploadExistingFileRequest* initiate_request = - new InitiateUploadExistingFileRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &upload_url)), - "text/plain", - kUploadContent.size(), - "file:foo", - kTestETag); - request_sender_->StartRequestWithRetry(initiate_request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(test_server_.GetURL("/upload_existing_file"), upload_url); - // For updating an existing file, METHOD_PUT should be used. - EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method); - // convert=false should be passed as files should be uploaded as-is. - EXPECT_EQ("/feeds/upload/create-session/default/private/full/file%3Afoo" - "?convert=false&v=3&alt=json&showroot=true", - http_request_.relative_url); - // Even though the body is empty, the content type should be set to - // "text/plain". - EXPECT_EQ("text/plain", http_request_.headers["Content-Type"]); - EXPECT_EQ("text/plain", http_request_.headers["X-Upload-Content-Type"]); - EXPECT_EQ(base::Int64ToString(kUploadContent.size()), - http_request_.headers["X-Upload-Content-Length"]); - // For updating an existing file, an empty body should be attached (PUT - // requires a body) - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ("", http_request_.content); - EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]); - - // 2) Upload the content to the upload URL. - UploadRangeResponse response; - scoped_ptr<ResourceEntry> new_entry; - - { - base::RunLoop run_loop; - ResumeUploadRequest* resume_request = new ResumeUploadRequest( - request_sender_.get(), - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&response, &new_entry)), - ProgressCallback(), - upload_url, - 0, // start_position - kUploadContent.size(), // end_position (exclusive) - kUploadContent.size(), // content_length, - "text/plain", // content_type - kTestFilePath); - request_sender_->StartRequestWithRetry(resume_request); - run_loop.Run(); - } - - // METHOD_PUT should be used to upload data. - EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method); - // Request should go to the upload URL. - EXPECT_EQ(upload_url.path(), http_request_.relative_url); - // Content-Range header should be added. - EXPECT_EQ("bytes 0-" + - base::Int64ToString(kUploadContent.size() -1) + "/" + - base::Int64ToString(kUploadContent.size()), - http_request_.headers["Content-Range"]); - // The upload content should be set in the HTTP request. - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ(kUploadContent, http_request_.content); - - // Check the response. - EXPECT_EQ(HTTP_SUCCESS, response.code); // Because it's an existing file. - // The start and end positions should be set to -1, if an upload is complete. - EXPECT_EQ(-1, response.start_position_received); - EXPECT_EQ(-1, response.end_position_received); -} - -// This test exercises InitiateUploadExistingFileRequest for a scenario of -// confliction on updating an existing file. -TEST_F(GDataWapiRequestsTest, UploadExistingFileWithETagConflict) { - const std::string kUploadContent = "hello"; - const std::string kWrongETag = "wrong_etag"; - GDataErrorCode result_code = GDATA_OTHER_ERROR; - GURL upload_url; - - { - base::RunLoop run_loop; - InitiateUploadExistingFileRequest* initiate_request = - new InitiateUploadExistingFileRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &upload_url)), - "text/plain", - kUploadContent.size(), - "file:foo", - kWrongETag); - request_sender_->StartRequestWithRetry(initiate_request); - run_loop.Run(); - } - - EXPECT_EQ(HTTP_PRECONDITION, result_code); - // For updating an existing file, METHOD_PUT should be used. - EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method); - // convert=false should be passed as files should be uploaded as-is. - EXPECT_EQ("/feeds/upload/create-session/default/private/full/file%3Afoo" - "?convert=false&v=3&alt=json&showroot=true", - http_request_.relative_url); - // Even though the body is empty, the content type should be set to - // "text/plain". - EXPECT_EQ("text/plain", http_request_.headers["Content-Type"]); - EXPECT_EQ("text/plain", http_request_.headers["X-Upload-Content-Type"]); - EXPECT_EQ(base::Int64ToString(kUploadContent.size()), - http_request_.headers["X-Upload-Content-Length"]); - // For updating an existing file, an empty body should be attached (PUT - // requires a body) - EXPECT_TRUE(http_request_.has_content); - EXPECT_EQ("", http_request_.content); - EXPECT_EQ(kWrongETag, http_request_.headers["If-Match"]); -} - -TEST_F(GDataWapiRequestsTest, DownloadFileRequest) { - const base::FilePath kDownloadedFilePath = - temp_dir_.path().AppendASCII("cache_file"); - const std::string kTestIdWithTypeLabel("file:dummyId"); - const std::string kTestId("dummyId"); - - GDataErrorCode result_code = GDATA_OTHER_ERROR; - base::FilePath temp_file; - { - base::RunLoop run_loop; - DownloadFileRequest* request = new DownloadFileRequest( - request_sender_.get(), - *url_generator_, - test_util::CreateQuitCallback( - &run_loop, - test_util::CreateCopyResultCallback(&result_code, &temp_file)), - GetContentCallback(), - ProgressCallback(), - kTestIdWithTypeLabel, - kDownloadedFilePath); - request_sender_->StartRequestWithRetry(request); - run_loop.Run(); - } - - std::string contents; - base::ReadFileToString(temp_file, &contents); - base::DeleteFile(temp_file, false); - - EXPECT_EQ(HTTP_SUCCESS, result_code); - EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method); - EXPECT_EQ(kTestDownloadPathPrefix + kTestId, http_request_.relative_url); - EXPECT_EQ(kDownloadedFilePath, temp_file); - - const std::string expected_contents = kTestId + kTestId + kTestId; - EXPECT_EQ(expected_contents, contents); -} - } // namespace google_apis |