1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "base/file_util.h"
7 #include "base/files/file_path.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/values.h"
13 #include "google_apis/drive/drive_api_parser.h"
14 #include "google_apis/drive/drive_api_requests.h"
15 #include "google_apis/drive/drive_api_url_generator.h"
16 #include "google_apis/drive/dummy_auth_service.h"
17 #include "google_apis/drive/request_sender.h"
18 #include "google_apis/drive/test_util.h"
19 #include "net/test/embedded_test_server/embedded_test_server.h"
20 #include "net/test/embedded_test_server/http_request.h"
21 #include "net/test/embedded_test_server/http_response.h"
22 #include "net/url_request/url_request_test_util.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 namespace google_apis {
29 const char kTestETag[] = "test_etag";
30 const char kTestUserAgent[] = "test-user-agent";
32 const char kTestChildrenResponse[] =
34 "\"kind\": \"drive#childReference\",\n"
35 "\"id\": \"resource_id\",\n"
36 "\"selfLink\": \"self_link\",\n"
37 "\"childLink\": \"child_link\",\n"
40 const char kTestUploadExistingFilePath[] = "/upload/existingfile/path";
41 const char kTestUploadNewFilePath[] = "/upload/newfile/path";
42 const char kTestDownloadPathPrefix[] = "/download/";
44 // Used as a GetContentCallback.
45 void AppendContent(std::string* out,
47 scoped_ptr<std::string> content) {
48 EXPECT_EQ(HTTP_SUCCESS, error);
49 out->append(*content);
54 class DriveApiRequestsTest : public testing::Test {
56 DriveApiRequestsTest() {
59 virtual void SetUp() OVERRIDE {
60 request_context_getter_ = new net::TestURLRequestContextGetter(
61 message_loop_.message_loop_proxy());
63 request_sender_.reset(new RequestSender(new DummyAuthService,
64 request_context_getter_.get(),
65 message_loop_.message_loop_proxy(),
68 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
70 ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady());
71 test_server_.RegisterRequestHandler(
72 base::Bind(&DriveApiRequestsTest::HandleChildrenDeleteRequest,
73 base::Unretained(this)));
74 test_server_.RegisterRequestHandler(
75 base::Bind(&DriveApiRequestsTest::HandleDataFileRequest,
76 base::Unretained(this)));
77 test_server_.RegisterRequestHandler(
78 base::Bind(&DriveApiRequestsTest::HandleDeleteRequest,
79 base::Unretained(this)));
80 test_server_.RegisterRequestHandler(
81 base::Bind(&DriveApiRequestsTest::HandlePreconditionFailedRequest,
82 base::Unretained(this)));
83 test_server_.RegisterRequestHandler(
84 base::Bind(&DriveApiRequestsTest::HandleResumeUploadRequest,
85 base::Unretained(this)));
86 test_server_.RegisterRequestHandler(
87 base::Bind(&DriveApiRequestsTest::HandleInitiateUploadRequest,
88 base::Unretained(this)));
89 test_server_.RegisterRequestHandler(
90 base::Bind(&DriveApiRequestsTest::HandleContentResponse,
91 base::Unretained(this)));
92 test_server_.RegisterRequestHandler(
93 base::Bind(&DriveApiRequestsTest::HandleDownloadRequest,
94 base::Unretained(this)));
96 GURL test_base_url = test_util::GetBaseUrlForTesting(test_server_.port());
97 url_generator_.reset(new DriveApiUrlGenerator(
98 test_base_url, test_base_url.Resolve(kTestDownloadPathPrefix)));
100 // Reset the server's expected behavior just in case.
101 ResetExpectedResponse();
106 base::MessageLoopForIO message_loop_; // Test server needs IO thread.
107 net::test_server::EmbeddedTestServer test_server_;
108 scoped_ptr<RequestSender> request_sender_;
109 scoped_ptr<DriveApiUrlGenerator> url_generator_;
110 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
111 base::ScopedTempDir temp_dir_;
113 // This is a path to the file which contains expected response from
114 // the server. See also HandleDataFileRequest below.
115 base::FilePath expected_data_file_path_;
117 // This is a path string in the expected response header from the server
118 // for initiating file uploading.
119 std::string expected_upload_path_;
121 // This is a path to the file which contains expected response for
122 // PRECONDITION_FAILED response.
123 base::FilePath expected_precondition_failed_file_path_;
125 // These are content and its type in the expected response from the server.
126 // See also HandleContentResponse below.
127 std::string expected_content_type_;
128 std::string expected_content_;
130 // The incoming HTTP request is saved so tests can verify the request
131 // parameters like HTTP method (ex. some requests should use DELETE
133 net::test_server::HttpRequest http_request_;
136 void ResetExpectedResponse() {
137 expected_data_file_path_.clear();
138 expected_upload_path_.clear();
139 expected_content_type_.clear();
140 expected_content_.clear();
143 // For "Children: delete" request, the server will return "204 No Content"
144 // response meaning "success".
145 scoped_ptr<net::test_server::HttpResponse> HandleChildrenDeleteRequest(
146 const net::test_server::HttpRequest& request) {
147 if (request.method != net::test_server::METHOD_DELETE ||
148 request.relative_url.find("/children/") == string::npos) {
149 // The request is not the "Children: delete" request. Delegate the
150 // processing to the next handler.
151 return scoped_ptr<net::test_server::HttpResponse>();
154 http_request_ = request;
156 // Return the response with just "204 No Content" status code.
157 scoped_ptr<net::test_server::BasicHttpResponse> http_response(
158 new net::test_server::BasicHttpResponse);
159 http_response->set_code(net::HTTP_NO_CONTENT);
160 return http_response.PassAs<net::test_server::HttpResponse>();
163 // Reads the data file of |expected_data_file_path_| and returns its content
165 // To use this method, it is necessary to set |expected_data_file_path_|
166 // to the appropriate file path before sending the request to the server.
167 scoped_ptr<net::test_server::HttpResponse> HandleDataFileRequest(
168 const net::test_server::HttpRequest& request) {
169 if (expected_data_file_path_.empty()) {
170 // The file is not specified. Delegate the processing to the next
172 return scoped_ptr<net::test_server::HttpResponse>();
175 http_request_ = request;
177 // Return the response from the data file.
178 return test_util::CreateHttpResponseFromFile(
179 expected_data_file_path_).PassAs<net::test_server::HttpResponse>();
182 // Deletes the resource and returns no content with HTTP_NO_CONTENT status
184 scoped_ptr<net::test_server::HttpResponse> HandleDeleteRequest(
185 const net::test_server::HttpRequest& request) {
186 if (request.method != net::test_server::METHOD_DELETE ||
187 request.relative_url.find("/files/") == string::npos) {
188 // The file is not file deletion request. Delegate the processing to the
190 return scoped_ptr<net::test_server::HttpResponse>();
193 http_request_ = request;
195 scoped_ptr<net::test_server::BasicHttpResponse> response(
196 new net::test_server::BasicHttpResponse);
197 response->set_code(net::HTTP_NO_CONTENT);
199 return response.PassAs<net::test_server::HttpResponse>();
202 // Returns PRECONDITION_FAILED response for ETag mismatching with error JSON
203 // content specified by |expected_precondition_failed_file_path_|.
204 // To use this method, it is necessary to set the variable to the appropriate
205 // file path before sending the request to the server.
206 scoped_ptr<net::test_server::HttpResponse> HandlePreconditionFailedRequest(
207 const net::test_server::HttpRequest& request) {
208 if (expected_precondition_failed_file_path_.empty()) {
209 // The file is not specified. Delegate the process to the next handler.
210 return scoped_ptr<net::test_server::HttpResponse>();
213 http_request_ = request;
215 scoped_ptr<net::test_server::BasicHttpResponse> response(
216 new net::test_server::BasicHttpResponse);
217 response->set_code(net::HTTP_PRECONDITION_FAILED);
220 if (base::ReadFileToString(expected_precondition_failed_file_path_,
222 response->set_content(content);
223 response->set_content_type("application/json");
226 return response.PassAs<net::test_server::HttpResponse>();
229 // Returns the response based on set expected upload url.
230 // The response contains the url in its "Location: " header. Also, it doesn't
232 // To use this method, it is necessary to set |expected_upload_path_|
233 // to the string representation of the url to be returned.
234 scoped_ptr<net::test_server::HttpResponse> HandleInitiateUploadRequest(
235 const net::test_server::HttpRequest& request) {
236 if (request.relative_url == expected_upload_path_ ||
237 expected_upload_path_.empty()) {
238 // The request is for resume uploading or the expected upload url is not
239 // set. Delegate the processing to the next handler.
240 return scoped_ptr<net::test_server::HttpResponse>();
243 http_request_ = request;
245 scoped_ptr<net::test_server::BasicHttpResponse> response(
246 new net::test_server::BasicHttpResponse);
248 // Check if the X-Upload-Content-Length is present. If yes, store the
249 // length of the file.
250 std::map<std::string, std::string>::const_iterator found =
251 request.headers.find("X-Upload-Content-Length");
252 if (found == request.headers.end() ||
253 !base::StringToInt64(found->second, &content_length_)) {
254 return scoped_ptr<net::test_server::HttpResponse>();
258 response->set_code(net::HTTP_OK);
259 response->AddCustomHeader(
261 test_server_.base_url().Resolve(expected_upload_path_).spec());
262 return response.PassAs<net::test_server::HttpResponse>();
265 scoped_ptr<net::test_server::HttpResponse> HandleResumeUploadRequest(
266 const net::test_server::HttpRequest& request) {
267 if (request.relative_url != expected_upload_path_) {
268 // The request path is different from the expected path for uploading.
269 // Delegate the processing to the next handler.
270 return scoped_ptr<net::test_server::HttpResponse>();
273 http_request_ = request;
275 if (!request.content.empty()) {
276 std::map<std::string, std::string>::const_iterator iter =
277 request.headers.find("Content-Range");
278 if (iter == request.headers.end()) {
279 // The range must be set.
280 return scoped_ptr<net::test_server::HttpResponse>();
284 int64 start_position = 0;
285 int64 end_position = 0;
286 if (!test_util::ParseContentRangeHeader(
287 iter->second, &start_position, &end_position, &length)) {
288 // Invalid "Content-Range" value.
289 return scoped_ptr<net::test_server::HttpResponse>();
292 EXPECT_EQ(start_position, received_bytes_);
293 EXPECT_EQ(length, content_length_);
295 // end_position is inclusive, but so +1 to change the range to byte size.
296 received_bytes_ = end_position + 1;
299 if (received_bytes_ < content_length_) {
300 scoped_ptr<net::test_server::BasicHttpResponse> response(
301 new net::test_server::BasicHttpResponse);
302 // Set RESUME INCOMPLETE (308) status code.
303 response->set_code(static_cast<net::HttpStatusCode>(308));
305 // Add Range header to the response, based on the values of
306 // Content-Range header in the request.
307 // The header is annotated only when at least one byte is received.
308 if (received_bytes_ > 0) {
309 response->AddCustomHeader(
310 "Range", "bytes=0-" + base::Int64ToString(received_bytes_ - 1));
313 return response.PassAs<net::test_server::HttpResponse>();
316 // All bytes are received. Return the "success" response with the file's
318 scoped_ptr<net::test_server::BasicHttpResponse> response =
319 test_util::CreateHttpResponseFromFile(
320 test_util::GetTestFilePath("drive/file_entry.json"));
322 // The response code is CREATED if it is new file uploading.
323 if (http_request_.relative_url == kTestUploadNewFilePath) {
324 response->set_code(net::HTTP_CREATED);
327 return response.PassAs<net::test_server::HttpResponse>();
330 // Returns the response based on set expected content and its type.
331 // To use this method, both |expected_content_type_| and |expected_content_|
332 // must be set in advance.
333 scoped_ptr<net::test_server::HttpResponse> HandleContentResponse(
334 const net::test_server::HttpRequest& request) {
335 if (expected_content_type_.empty() || expected_content_.empty()) {
336 // Expected content is not set. Delegate the processing to the next
338 return scoped_ptr<net::test_server::HttpResponse>();
341 http_request_ = request;
343 scoped_ptr<net::test_server::BasicHttpResponse> response(
344 new net::test_server::BasicHttpResponse);
345 response->set_code(net::HTTP_OK);
346 response->set_content_type(expected_content_type_);
347 response->set_content(expected_content_);
348 return response.PassAs<net::test_server::HttpResponse>();
351 // Handles a request for downloading a file.
352 scoped_ptr<net::test_server::HttpResponse> HandleDownloadRequest(
353 const net::test_server::HttpRequest& request) {
354 http_request_ = request;
356 const GURL absolute_url = test_server_.GetURL(request.relative_url);
358 if (!test_util::RemovePrefix(absolute_url.path(),
359 kTestDownloadPathPrefix,
361 return scoped_ptr<net::test_server::HttpResponse>();
364 // For testing, returns a text with |id| repeated 3 times.
365 scoped_ptr<net::test_server::BasicHttpResponse> response(
366 new net::test_server::BasicHttpResponse);
367 response->set_code(net::HTTP_OK);
368 response->set_content(id + id + id);
369 response->set_content_type("text/plain");
370 return response.PassAs<net::test_server::HttpResponse>();
373 // These are for the current upload file status.
374 int64 received_bytes_;
375 int64 content_length_;
378 TEST_F(DriveApiRequestsTest, DriveApiDataRequest_Fields) {
379 // Make sure that "fields" query param is supported by using its subclass,
382 // Set an expected data file containing valid result.
383 expected_data_file_path_ = test_util::GetTestFilePath(
386 GDataErrorCode error = GDATA_OTHER_ERROR;
387 scoped_ptr<AboutResource> about_resource;
390 base::RunLoop run_loop;
391 drive::AboutGetRequest* request = new drive::AboutGetRequest(
392 request_sender_.get(),
394 test_util::CreateQuitCallback(
396 test_util::CreateCopyResultCallback(&error, &about_resource)));
398 "kind,quotaBytesTotal,quotaBytesUsed,largestChangeId,rootFolderId");
399 request_sender_->StartRequestWithRetry(request);
403 EXPECT_EQ(HTTP_SUCCESS, error);
404 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
405 EXPECT_EQ("/drive/v2/about?"
406 "fields=kind%2CquotaBytesTotal%2CquotaBytesUsed%2C"
407 "largestChangeId%2CrootFolderId",
408 http_request_.relative_url);
410 scoped_ptr<AboutResource> expected(
411 AboutResource::CreateFrom(
412 *test_util::LoadJSONFile("drive/about.json")));
413 ASSERT_TRUE(about_resource.get());
414 EXPECT_EQ(expected->largest_change_id(), about_resource->largest_change_id());
415 EXPECT_EQ(expected->quota_bytes_total(), about_resource->quota_bytes_total());
416 EXPECT_EQ(expected->quota_bytes_used(), about_resource->quota_bytes_used());
417 EXPECT_EQ(expected->root_folder_id(), about_resource->root_folder_id());
420 TEST_F(DriveApiRequestsTest, FilesInsertRequest) {
421 // Set an expected data file containing the directory's entry data.
422 expected_data_file_path_ =
423 test_util::GetTestFilePath("drive/directory_entry.json");
425 GDataErrorCode error = GDATA_OTHER_ERROR;
426 scoped_ptr<FileResource> file_resource;
428 // Create "new directory" in the root directory.
430 base::RunLoop run_loop;
431 drive::FilesInsertRequest* request = new drive::FilesInsertRequest(
432 request_sender_.get(),
434 test_util::CreateQuitCallback(
436 test_util::CreateCopyResultCallback(&error, &file_resource)));
437 request->set_mime_type("application/vnd.google-apps.folder");
438 request->add_parent("root");
439 request->set_title("new directory");
440 request_sender_->StartRequestWithRetry(request);
444 EXPECT_EQ(HTTP_SUCCESS, error);
445 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
446 EXPECT_EQ("/drive/v2/files", http_request_.relative_url);
447 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
449 EXPECT_TRUE(http_request_.has_content);
451 scoped_ptr<FileResource> expected(
452 FileResource::CreateFrom(
453 *test_util::LoadJSONFile("drive/directory_entry.json")));
456 ASSERT_TRUE(file_resource.get());
458 EXPECT_EQ(expected->file_id(), file_resource->file_id());
459 EXPECT_EQ(expected->title(), file_resource->title());
460 EXPECT_EQ(expected->mime_type(), file_resource->mime_type());
461 EXPECT_EQ(expected->parents().size(), file_resource->parents().size());
464 TEST_F(DriveApiRequestsTest, FilesPatchRequest) {
465 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
466 const base::Time::Exploded kLastViewedByMeDate =
467 {2013, 7, 0, 19, 15, 59, 13, 123};
469 // Set an expected data file containing valid result.
470 expected_data_file_path_ =
471 test_util::GetTestFilePath("drive/file_entry.json");
473 GDataErrorCode error = GDATA_OTHER_ERROR;
474 scoped_ptr<FileResource> file_resource;
477 base::RunLoop run_loop;
478 drive::FilesPatchRequest* request = new drive::FilesPatchRequest(
479 request_sender_.get(),
481 test_util::CreateQuitCallback(
483 test_util::CreateCopyResultCallback(&error, &file_resource)));
484 request->set_file_id("resource_id");
485 request->set_set_modified_date(true);
486 request->set_update_viewed_date(false);
488 request->set_title("new title");
489 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
490 request->set_last_viewed_by_me_date(
491 base::Time::FromUTCExploded(kLastViewedByMeDate));
492 request->add_parent("parent_resource_id");
494 request_sender_->StartRequestWithRetry(request);
498 EXPECT_EQ(HTTP_SUCCESS, error);
499 EXPECT_EQ(net::test_server::METHOD_PATCH, http_request_.method);
500 EXPECT_EQ("/drive/v2/files/resource_id"
501 "?setModifiedDate=true&updateViewedDate=false",
502 http_request_.relative_url);
504 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
505 EXPECT_TRUE(http_request_.has_content);
506 EXPECT_EQ("{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
507 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
508 "\"parents\":[{\"id\":\"parent_resource_id\"}],"
509 "\"title\":\"new title\"}",
510 http_request_.content);
511 EXPECT_TRUE(file_resource);
514 TEST_F(DriveApiRequestsTest, AboutGetRequest_ValidJson) {
515 // Set an expected data file containing valid result.
516 expected_data_file_path_ = test_util::GetTestFilePath(
519 GDataErrorCode error = GDATA_OTHER_ERROR;
520 scoped_ptr<AboutResource> about_resource;
523 base::RunLoop run_loop;
524 drive::AboutGetRequest* request = new drive::AboutGetRequest(
525 request_sender_.get(),
527 test_util::CreateQuitCallback(
529 test_util::CreateCopyResultCallback(&error, &about_resource)));
530 request_sender_->StartRequestWithRetry(request);
534 EXPECT_EQ(HTTP_SUCCESS, error);
535 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
536 EXPECT_EQ("/drive/v2/about", http_request_.relative_url);
538 scoped_ptr<AboutResource> expected(
539 AboutResource::CreateFrom(
540 *test_util::LoadJSONFile("drive/about.json")));
541 ASSERT_TRUE(about_resource.get());
542 EXPECT_EQ(expected->largest_change_id(), about_resource->largest_change_id());
543 EXPECT_EQ(expected->quota_bytes_total(), about_resource->quota_bytes_total());
544 EXPECT_EQ(expected->quota_bytes_used(), about_resource->quota_bytes_used());
545 EXPECT_EQ(expected->root_folder_id(), about_resource->root_folder_id());
548 TEST_F(DriveApiRequestsTest, AboutGetRequest_InvalidJson) {
549 // Set an expected data file containing invalid result.
550 expected_data_file_path_ = test_util::GetTestFilePath(
551 "gdata/testfile.txt");
553 GDataErrorCode error = GDATA_OTHER_ERROR;
554 scoped_ptr<AboutResource> about_resource;
557 base::RunLoop run_loop;
558 drive::AboutGetRequest* request = new drive::AboutGetRequest(
559 request_sender_.get(),
561 test_util::CreateQuitCallback(
563 test_util::CreateCopyResultCallback(&error, &about_resource)));
564 request_sender_->StartRequestWithRetry(request);
568 // "parse error" should be returned, and the about resource should be NULL.
569 EXPECT_EQ(GDATA_PARSE_ERROR, error);
570 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
571 EXPECT_EQ("/drive/v2/about", http_request_.relative_url);
572 EXPECT_FALSE(about_resource);
575 TEST_F(DriveApiRequestsTest, AppsListRequest) {
576 // Set an expected data file containing valid result.
577 expected_data_file_path_ = test_util::GetTestFilePath(
578 "drive/applist.json");
580 GDataErrorCode error = GDATA_OTHER_ERROR;
581 scoped_ptr<AppList> app_list;
584 base::RunLoop run_loop;
585 drive::AppsListRequest* request = new drive::AppsListRequest(
586 request_sender_.get(),
588 test_util::CreateQuitCallback(
590 test_util::CreateCopyResultCallback(&error, &app_list)));
591 request_sender_->StartRequestWithRetry(request);
595 EXPECT_EQ(HTTP_SUCCESS, error);
596 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
597 EXPECT_EQ("/drive/v2/apps", http_request_.relative_url);
598 EXPECT_TRUE(app_list);
601 TEST_F(DriveApiRequestsTest, ChangesListRequest) {
602 // Set an expected data file containing valid result.
603 expected_data_file_path_ = test_util::GetTestFilePath(
604 "drive/changelist.json");
606 GDataErrorCode error = GDATA_OTHER_ERROR;
607 scoped_ptr<ChangeList> result;
610 base::RunLoop run_loop;
611 drive::ChangesListRequest* request = new drive::ChangesListRequest(
612 request_sender_.get(), *url_generator_,
613 test_util::CreateQuitCallback(
615 test_util::CreateCopyResultCallback(&error, &result)));
616 request->set_include_deleted(true);
617 request->set_start_change_id(100);
618 request->set_max_results(500);
619 request_sender_->StartRequestWithRetry(request);
623 EXPECT_EQ(HTTP_SUCCESS, error);
624 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
625 EXPECT_EQ("/drive/v2/changes?maxResults=500&startChangeId=100",
626 http_request_.relative_url);
630 TEST_F(DriveApiRequestsTest, ChangesListNextPageRequest) {
631 // Set an expected data file containing valid result.
632 expected_data_file_path_ = test_util::GetTestFilePath(
633 "drive/changelist.json");
635 GDataErrorCode error = GDATA_OTHER_ERROR;
636 scoped_ptr<ChangeList> result;
639 base::RunLoop run_loop;
640 drive::ChangesListNextPageRequest* request =
641 new drive::ChangesListNextPageRequest(
642 request_sender_.get(),
643 test_util::CreateQuitCallback(
645 test_util::CreateCopyResultCallback(&error, &result)));
646 request->set_next_link(test_server_.GetURL("/continue/get/change/list"));
647 request_sender_->StartRequestWithRetry(request);
651 EXPECT_EQ(HTTP_SUCCESS, error);
652 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
653 EXPECT_EQ("/continue/get/change/list", http_request_.relative_url);
657 TEST_F(DriveApiRequestsTest, FilesCopyRequest) {
658 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
660 // Set an expected data file containing the dummy file entry data.
661 // It'd be returned if we copy a file.
662 expected_data_file_path_ =
663 test_util::GetTestFilePath("drive/file_entry.json");
665 GDataErrorCode error = GDATA_OTHER_ERROR;
666 scoped_ptr<FileResource> file_resource;
668 // Copy the file to a new file named "new title".
670 base::RunLoop run_loop;
671 drive::FilesCopyRequest* request = new drive::FilesCopyRequest(
672 request_sender_.get(),
674 test_util::CreateQuitCallback(
676 test_util::CreateCopyResultCallback(&error, &file_resource)));
677 request->set_file_id("resource_id");
678 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
679 request->add_parent("parent_resource_id");
680 request->set_title("new title");
681 request_sender_->StartRequestWithRetry(request);
685 EXPECT_EQ(HTTP_SUCCESS, error);
686 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
687 EXPECT_EQ("/drive/v2/files/resource_id/copy", http_request_.relative_url);
688 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
690 EXPECT_TRUE(http_request_.has_content);
692 "{\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
693 "\"parents\":[{\"id\":\"parent_resource_id\"}],\"title\":\"new title\"}",
694 http_request_.content);
695 EXPECT_TRUE(file_resource);
698 TEST_F(DriveApiRequestsTest, FilesCopyRequest_EmptyParentResourceId) {
699 // Set an expected data file containing the dummy file entry data.
700 // It'd be returned if we copy a file.
701 expected_data_file_path_ =
702 test_util::GetTestFilePath("drive/file_entry.json");
704 GDataErrorCode error = GDATA_OTHER_ERROR;
705 scoped_ptr<FileResource> file_resource;
707 // Copy the file to a new file named "new title".
709 base::RunLoop run_loop;
710 drive::FilesCopyRequest* request = new drive::FilesCopyRequest(
711 request_sender_.get(),
713 test_util::CreateQuitCallback(
715 test_util::CreateCopyResultCallback(&error, &file_resource)));
716 request->set_file_id("resource_id");
717 request->set_title("new title");
718 request_sender_->StartRequestWithRetry(request);
722 EXPECT_EQ(HTTP_SUCCESS, error);
723 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
724 EXPECT_EQ("/drive/v2/files/resource_id/copy", http_request_.relative_url);
725 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
727 EXPECT_TRUE(http_request_.has_content);
728 EXPECT_EQ("{\"title\":\"new title\"}", http_request_.content);
729 EXPECT_TRUE(file_resource);
732 TEST_F(DriveApiRequestsTest, FilesListRequest) {
733 // Set an expected data file containing valid result.
734 expected_data_file_path_ = test_util::GetTestFilePath(
735 "drive/filelist.json");
737 GDataErrorCode error = GDATA_OTHER_ERROR;
738 scoped_ptr<FileList> result;
741 base::RunLoop run_loop;
742 drive::FilesListRequest* request = new drive::FilesListRequest(
743 request_sender_.get(), *url_generator_,
744 test_util::CreateQuitCallback(
746 test_util::CreateCopyResultCallback(&error, &result)));
747 request->set_max_results(50);
748 request->set_q("\"abcde\" in parents");
749 request_sender_->StartRequestWithRetry(request);
753 EXPECT_EQ(HTTP_SUCCESS, error);
754 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
755 EXPECT_EQ("/drive/v2/files?maxResults=50&q=%22abcde%22+in+parents",
756 http_request_.relative_url);
760 TEST_F(DriveApiRequestsTest, FilesListNextPageRequest) {
761 // Set an expected data file containing valid result.
762 expected_data_file_path_ = test_util::GetTestFilePath(
763 "drive/filelist.json");
765 GDataErrorCode error = GDATA_OTHER_ERROR;
766 scoped_ptr<FileList> result;
769 base::RunLoop run_loop;
770 drive::FilesListNextPageRequest* request =
771 new drive::FilesListNextPageRequest(
772 request_sender_.get(),
773 test_util::CreateQuitCallback(
775 test_util::CreateCopyResultCallback(&error, &result)));
776 request->set_next_link(test_server_.GetURL("/continue/get/file/list"));
777 request_sender_->StartRequestWithRetry(request);
781 EXPECT_EQ(HTTP_SUCCESS, error);
782 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
783 EXPECT_EQ("/continue/get/file/list", http_request_.relative_url);
787 TEST_F(DriveApiRequestsTest, FilesDeleteRequest) {
788 GDataErrorCode error = GDATA_OTHER_ERROR;
790 // Delete a resource with the given resource id.
792 base::RunLoop run_loop;
793 drive::FilesDeleteRequest* request = new drive::FilesDeleteRequest(
794 request_sender_.get(),
796 test_util::CreateQuitCallback(
797 &run_loop, test_util::CreateCopyResultCallback(&error)));
798 request->set_file_id("resource_id");
799 request->set_etag(kTestETag);
800 request_sender_->StartRequestWithRetry(request);
804 EXPECT_EQ(HTTP_NO_CONTENT, error);
805 EXPECT_EQ(net::test_server::METHOD_DELETE, http_request_.method);
806 EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
807 EXPECT_EQ("/drive/v2/files/resource_id", http_request_.relative_url);
808 EXPECT_FALSE(http_request_.has_content);
811 TEST_F(DriveApiRequestsTest, FilesTrashRequest) {
812 // Set data for the expected result. Directory entry should be returned
813 // if the trashing entry is a directory, so using it here should be fine.
814 expected_data_file_path_ =
815 test_util::GetTestFilePath("drive/directory_entry.json");
817 GDataErrorCode error = GDATA_OTHER_ERROR;
818 scoped_ptr<FileResource> file_resource;
820 // Trash a resource with the given resource id.
822 base::RunLoop run_loop;
823 drive::FilesTrashRequest* request = new drive::FilesTrashRequest(
824 request_sender_.get(),
826 test_util::CreateQuitCallback(
828 test_util::CreateCopyResultCallback(&error, &file_resource)));
829 request->set_file_id("resource_id");
830 request_sender_->StartRequestWithRetry(request);
834 EXPECT_EQ(HTTP_SUCCESS, error);
835 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
836 EXPECT_EQ("/drive/v2/files/resource_id/trash", http_request_.relative_url);
837 EXPECT_TRUE(http_request_.has_content);
838 EXPECT_TRUE(http_request_.content.empty());
841 TEST_F(DriveApiRequestsTest, ChildrenInsertRequest) {
842 // Set an expected data file containing the children entry.
843 expected_content_type_ = "application/json";
844 expected_content_ = kTestChildrenResponse;
846 GDataErrorCode error = GDATA_OTHER_ERROR;
848 // Add a resource with "resource_id" to a directory with
849 // "parent_resource_id".
851 base::RunLoop run_loop;
852 drive::ChildrenInsertRequest* request = new drive::ChildrenInsertRequest(
853 request_sender_.get(),
855 test_util::CreateQuitCallback(
857 test_util::CreateCopyResultCallback(&error)));
858 request->set_folder_id("parent_resource_id");
859 request->set_id("resource_id");
860 request_sender_->StartRequestWithRetry(request);
864 EXPECT_EQ(HTTP_SUCCESS, error);
865 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
866 EXPECT_EQ("/drive/v2/files/parent_resource_id/children",
867 http_request_.relative_url);
868 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
870 EXPECT_TRUE(http_request_.has_content);
871 EXPECT_EQ("{\"id\":\"resource_id\"}", http_request_.content);
874 TEST_F(DriveApiRequestsTest, ChildrenDeleteRequest) {
875 GDataErrorCode error = GDATA_OTHER_ERROR;
877 // Remove a resource with "resource_id" from a directory with
878 // "parent_resource_id".
880 base::RunLoop run_loop;
881 drive::ChildrenDeleteRequest* request = new drive::ChildrenDeleteRequest(
882 request_sender_.get(),
884 test_util::CreateQuitCallback(
886 test_util::CreateCopyResultCallback(&error)));
887 request->set_child_id("resource_id");
888 request->set_folder_id("parent_resource_id");
889 request_sender_->StartRequestWithRetry(request);
893 EXPECT_EQ(HTTP_NO_CONTENT, error);
894 EXPECT_EQ(net::test_server::METHOD_DELETE, http_request_.method);
895 EXPECT_EQ("/drive/v2/files/parent_resource_id/children/resource_id",
896 http_request_.relative_url);
897 EXPECT_FALSE(http_request_.has_content);
900 TEST_F(DriveApiRequestsTest, UploadNewFileRequest) {
901 // Set an expected url for uploading.
902 expected_upload_path_ = kTestUploadNewFilePath;
904 const char kTestContentType[] = "text/plain";
905 const std::string kTestContent(100, 'a');
906 const base::FilePath kTestFilePath =
907 temp_dir_.path().AppendASCII("upload_file.txt");
908 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
910 GDataErrorCode error = GDATA_OTHER_ERROR;
913 // Initiate uploading a new file to the directory with
914 // "parent_resource_id".
916 base::RunLoop run_loop;
917 drive::InitiateUploadNewFileRequest* request =
918 new drive::InitiateUploadNewFileRequest(
919 request_sender_.get(),
923 "parent_resource_id", // The resource id of the parent directory.
924 "new file title", // The title of the file being uploaded.
925 test_util::CreateQuitCallback(
927 test_util::CreateCopyResultCallback(&error, &upload_url)));
928 request_sender_->StartRequestWithRetry(request);
932 EXPECT_EQ(HTTP_SUCCESS, error);
933 EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
934 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
935 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
936 http_request_.headers["X-Upload-Content-Length"]);
938 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
939 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
940 http_request_.relative_url);
941 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
942 EXPECT_TRUE(http_request_.has_content);
943 EXPECT_EQ("{\"parents\":[{"
944 "\"id\":\"parent_resource_id\","
945 "\"kind\":\"drive#fileLink\""
947 "\"title\":\"new file title\"}",
948 http_request_.content);
950 // Upload the content to the upload URL.
951 UploadRangeResponse response;
952 scoped_ptr<FileResource> new_entry;
955 base::RunLoop run_loop;
956 drive::ResumeUploadRequest* resume_request =
957 new drive::ResumeUploadRequest(
958 request_sender_.get(),
961 kTestContent.size(), // end_position (exclusive)
962 kTestContent.size(), // content_length,
965 test_util::CreateQuitCallback(
967 test_util::CreateCopyResultCallback(&response, &new_entry)),
969 request_sender_->StartRequestWithRetry(resume_request);
973 // METHOD_PUT should be used to upload data.
974 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
975 // Request should go to the upload URL.
976 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
977 // Content-Range header should be added.
978 EXPECT_EQ("bytes 0-" +
979 base::Int64ToString(kTestContent.size() - 1) + "/" +
980 base::Int64ToString(kTestContent.size()),
981 http_request_.headers["Content-Range"]);
982 // The upload content should be set in the HTTP request.
983 EXPECT_TRUE(http_request_.has_content);
984 EXPECT_EQ(kTestContent, http_request_.content);
986 // Check the response.
987 EXPECT_EQ(HTTP_CREATED, response.code); // Because it's a new file
988 // The start and end positions should be set to -1, if an upload is complete.
989 EXPECT_EQ(-1, response.start_position_received);
990 EXPECT_EQ(-1, response.end_position_received);
993 TEST_F(DriveApiRequestsTest, UploadNewEmptyFileRequest) {
994 // Set an expected url for uploading.
995 expected_upload_path_ = kTestUploadNewFilePath;
997 const char kTestContentType[] = "text/plain";
998 const char kTestContent[] = "";
999 const base::FilePath kTestFilePath =
1000 temp_dir_.path().AppendASCII("empty_file.txt");
1001 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1003 GDataErrorCode error = GDATA_OTHER_ERROR;
1006 // Initiate uploading a new file to the directory with "parent_resource_id".
1008 base::RunLoop run_loop;
1009 drive::InitiateUploadNewFileRequest* request =
1010 new drive::InitiateUploadNewFileRequest(
1011 request_sender_.get(),
1015 "parent_resource_id", // The resource id of the parent directory.
1016 "new file title", // The title of the file being uploaded.
1017 test_util::CreateQuitCallback(
1019 test_util::CreateCopyResultCallback(&error, &upload_url)));
1020 request_sender_->StartRequestWithRetry(request);
1024 EXPECT_EQ(HTTP_SUCCESS, error);
1025 EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1026 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1027 EXPECT_EQ("0", http_request_.headers["X-Upload-Content-Length"]);
1029 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1030 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
1031 http_request_.relative_url);
1032 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1033 EXPECT_TRUE(http_request_.has_content);
1034 EXPECT_EQ("{\"parents\":[{"
1035 "\"id\":\"parent_resource_id\","
1036 "\"kind\":\"drive#fileLink\""
1038 "\"title\":\"new file title\"}",
1039 http_request_.content);
1041 // Upload the content to the upload URL.
1042 UploadRangeResponse response;
1043 scoped_ptr<FileResource> new_entry;
1046 base::RunLoop run_loop;
1047 drive::ResumeUploadRequest* resume_request =
1048 new drive::ResumeUploadRequest(
1049 request_sender_.get(),
1051 0, // start_position
1052 0, // end_position (exclusive)
1053 0, // content_length,
1056 test_util::CreateQuitCallback(
1058 test_util::CreateCopyResultCallback(&response, &new_entry)),
1059 ProgressCallback());
1060 request_sender_->StartRequestWithRetry(resume_request);
1064 // METHOD_PUT should be used to upload data.
1065 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1066 // Request should go to the upload URL.
1067 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1068 // Content-Range header should NOT be added.
1069 EXPECT_EQ(0U, http_request_.headers.count("Content-Range"));
1070 // The upload content should be set in the HTTP request.
1071 EXPECT_TRUE(http_request_.has_content);
1072 EXPECT_EQ(kTestContent, http_request_.content);
1074 // Check the response.
1075 EXPECT_EQ(HTTP_CREATED, response.code); // Because it's a new file
1076 // The start and end positions should be set to -1, if an upload is complete.
1077 EXPECT_EQ(-1, response.start_position_received);
1078 EXPECT_EQ(-1, response.end_position_received);
1081 TEST_F(DriveApiRequestsTest, UploadNewLargeFileRequest) {
1082 // Set an expected url for uploading.
1083 expected_upload_path_ = kTestUploadNewFilePath;
1085 const char kTestContentType[] = "text/plain";
1086 const size_t kNumChunkBytes = 10; // Num bytes in a chunk.
1087 const std::string kTestContent(100, 'a');
1088 const base::FilePath kTestFilePath =
1089 temp_dir_.path().AppendASCII("upload_file.txt");
1090 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1092 GDataErrorCode error = GDATA_OTHER_ERROR;
1095 // Initiate uploading a new file to the directory with "parent_resource_id".
1097 base::RunLoop run_loop;
1098 drive::InitiateUploadNewFileRequest* request =
1099 new drive::InitiateUploadNewFileRequest(
1100 request_sender_.get(),
1103 kTestContent.size(),
1104 "parent_resource_id", // The resource id of the parent directory.
1105 "new file title", // The title of the file being uploaded.
1106 test_util::CreateQuitCallback(
1108 test_util::CreateCopyResultCallback(&error, &upload_url)));
1109 request_sender_->StartRequestWithRetry(request);
1113 EXPECT_EQ(HTTP_SUCCESS, error);
1114 EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1115 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1116 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1117 http_request_.headers["X-Upload-Content-Length"]);
1119 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1120 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
1121 http_request_.relative_url);
1122 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1123 EXPECT_TRUE(http_request_.has_content);
1124 EXPECT_EQ("{\"parents\":[{"
1125 "\"id\":\"parent_resource_id\","
1126 "\"kind\":\"drive#fileLink\""
1128 "\"title\":\"new file title\"}",
1129 http_request_.content);
1131 // Before sending any data, check the current status.
1132 // This is an edge case test for GetUploadStatusRequest.
1134 UploadRangeResponse response;
1135 scoped_ptr<FileResource> new_entry;
1137 // Check the response by GetUploadStatusRequest.
1139 base::RunLoop run_loop;
1140 drive::GetUploadStatusRequest* get_upload_status_request =
1141 new drive::GetUploadStatusRequest(
1142 request_sender_.get(),
1144 kTestContent.size(),
1145 test_util::CreateQuitCallback(
1147 test_util::CreateCopyResultCallback(&response, &new_entry)));
1148 request_sender_->StartRequestWithRetry(get_upload_status_request);
1152 // METHOD_PUT should be used to upload data.
1153 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1154 // Request should go to the upload URL.
1155 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1156 // Content-Range header should be added.
1157 EXPECT_EQ("bytes */" + base::Int64ToString(kTestContent.size()),
1158 http_request_.headers["Content-Range"]);
1159 EXPECT_TRUE(http_request_.has_content);
1160 EXPECT_TRUE(http_request_.content.empty());
1162 // Check the response.
1163 EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code);
1164 EXPECT_EQ(0, response.start_position_received);
1165 EXPECT_EQ(0, response.end_position_received);
1168 // Upload the content to the upload URL.
1169 for (size_t start_position = 0; start_position < kTestContent.size();
1170 start_position += kNumChunkBytes) {
1171 const std::string payload = kTestContent.substr(
1173 std::min(kNumChunkBytes, kTestContent.size() - start_position));
1174 const size_t end_position = start_position + payload.size();
1176 UploadRangeResponse response;
1177 scoped_ptr<FileResource> new_entry;
1180 base::RunLoop run_loop;
1181 drive::ResumeUploadRequest* resume_request =
1182 new drive::ResumeUploadRequest(
1183 request_sender_.get(),
1187 kTestContent.size(), // content_length,
1190 test_util::CreateQuitCallback(
1192 test_util::CreateCopyResultCallback(&response, &new_entry)),
1193 ProgressCallback());
1194 request_sender_->StartRequestWithRetry(resume_request);
1198 // METHOD_PUT should be used to upload data.
1199 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1200 // Request should go to the upload URL.
1201 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1202 // Content-Range header should be added.
1203 EXPECT_EQ("bytes " +
1204 base::Int64ToString(start_position) + "-" +
1205 base::Int64ToString(end_position - 1) + "/" +
1206 base::Int64ToString(kTestContent.size()),
1207 http_request_.headers["Content-Range"]);
1208 // The upload content should be set in the HTTP request.
1209 EXPECT_TRUE(http_request_.has_content);
1210 EXPECT_EQ(payload, http_request_.content);
1212 if (end_position == kTestContent.size()) {
1213 // Check the response.
1214 EXPECT_EQ(HTTP_CREATED, response.code); // Because it's a new file
1215 // The start and end positions should be set to -1, if an upload is
1217 EXPECT_EQ(-1, response.start_position_received);
1218 EXPECT_EQ(-1, response.end_position_received);
1222 // Check the response.
1223 EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code);
1224 EXPECT_EQ(0, response.start_position_received);
1225 EXPECT_EQ(static_cast<int64>(end_position), response.end_position_received);
1227 // Check the response by GetUploadStatusRequest.
1229 base::RunLoop run_loop;
1230 drive::GetUploadStatusRequest* get_upload_status_request =
1231 new drive::GetUploadStatusRequest(
1232 request_sender_.get(),
1234 kTestContent.size(),
1235 test_util::CreateQuitCallback(
1237 test_util::CreateCopyResultCallback(&response, &new_entry)));
1238 request_sender_->StartRequestWithRetry(get_upload_status_request);
1242 // METHOD_PUT should be used to upload data.
1243 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1244 // Request should go to the upload URL.
1245 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1246 // Content-Range header should be added.
1247 EXPECT_EQ("bytes */" + base::Int64ToString(kTestContent.size()),
1248 http_request_.headers["Content-Range"]);
1249 EXPECT_TRUE(http_request_.has_content);
1250 EXPECT_TRUE(http_request_.content.empty());
1252 // Check the response.
1253 EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code);
1254 EXPECT_EQ(0, response.start_position_received);
1255 EXPECT_EQ(static_cast<int64>(end_position),
1256 response.end_position_received);
1260 TEST_F(DriveApiRequestsTest, UploadNewFileWithMetadataRequest) {
1261 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
1262 const base::Time::Exploded kLastViewedByMeDate =
1263 {2013, 7, 0, 19, 15, 59, 13, 123};
1265 // Set an expected url for uploading.
1266 expected_upload_path_ = kTestUploadNewFilePath;
1268 const char kTestContentType[] = "text/plain";
1269 const std::string kTestContent(100, 'a');
1271 GDataErrorCode error = GDATA_OTHER_ERROR;
1274 // Initiate uploading a new file to the directory with "parent_resource_id".
1276 base::RunLoop run_loop;
1277 drive::InitiateUploadNewFileRequest* request =
1278 new drive::InitiateUploadNewFileRequest(
1279 request_sender_.get(),
1282 kTestContent.size(),
1283 "parent_resource_id", // The resource id of the parent directory.
1284 "new file title", // The title of the file being uploaded.
1285 test_util::CreateQuitCallback(
1287 test_util::CreateCopyResultCallback(&error, &upload_url)));
1288 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
1289 request->set_last_viewed_by_me_date(
1290 base::Time::FromUTCExploded(kLastViewedByMeDate));
1291 request_sender_->StartRequestWithRetry(request);
1295 EXPECT_EQ(HTTP_SUCCESS, error);
1296 EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1297 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1298 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1299 http_request_.headers["X-Upload-Content-Length"]);
1301 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1302 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable&setModifiedDate=true",
1303 http_request_.relative_url);
1304 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1305 EXPECT_TRUE(http_request_.has_content);
1306 EXPECT_EQ("{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
1307 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
1308 "\"parents\":[{\"id\":\"parent_resource_id\","
1309 "\"kind\":\"drive#fileLink\"}],"
1310 "\"title\":\"new file title\"}",
1311 http_request_.content);
1314 TEST_F(DriveApiRequestsTest, UploadExistingFileRequest) {
1315 // Set an expected url for uploading.
1316 expected_upload_path_ = kTestUploadExistingFilePath;
1318 const char kTestContentType[] = "text/plain";
1319 const std::string kTestContent(100, 'a');
1320 const base::FilePath kTestFilePath =
1321 temp_dir_.path().AppendASCII("upload_file.txt");
1322 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1324 GDataErrorCode error = GDATA_OTHER_ERROR;
1327 // Initiate uploading a new file to the directory with "parent_resource_id".
1329 base::RunLoop run_loop;
1330 drive::InitiateUploadExistingFileRequest* request =
1331 new drive::InitiateUploadExistingFileRequest(
1332 request_sender_.get(),
1335 kTestContent.size(),
1336 "resource_id", // The resource id of the file to be overwritten.
1337 std::string(), // No etag.
1338 test_util::CreateQuitCallback(
1340 test_util::CreateCopyResultCallback(&error, &upload_url)));
1341 request_sender_->StartRequestWithRetry(request);
1345 EXPECT_EQ(HTTP_SUCCESS, error);
1346 EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1347 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1348 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1349 http_request_.headers["X-Upload-Content-Length"]);
1350 EXPECT_EQ("*", http_request_.headers["If-Match"]);
1352 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1353 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1354 http_request_.relative_url);
1355 EXPECT_TRUE(http_request_.has_content);
1356 EXPECT_TRUE(http_request_.content.empty());
1358 // Upload the content to the upload URL.
1359 UploadRangeResponse response;
1360 scoped_ptr<FileResource> new_entry;
1363 base::RunLoop run_loop;
1364 drive::ResumeUploadRequest* resume_request =
1365 new drive::ResumeUploadRequest(
1366 request_sender_.get(),
1368 0, // start_position
1369 kTestContent.size(), // end_position (exclusive)
1370 kTestContent.size(), // content_length,
1373 test_util::CreateQuitCallback(
1375 test_util::CreateCopyResultCallback(&response, &new_entry)),
1376 ProgressCallback());
1377 request_sender_->StartRequestWithRetry(resume_request);
1381 // METHOD_PUT should be used to upload data.
1382 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1383 // Request should go to the upload URL.
1384 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1385 // Content-Range header should be added.
1386 EXPECT_EQ("bytes 0-" +
1387 base::Int64ToString(kTestContent.size() - 1) + "/" +
1388 base::Int64ToString(kTestContent.size()),
1389 http_request_.headers["Content-Range"]);
1390 // The upload content should be set in the HTTP request.
1391 EXPECT_TRUE(http_request_.has_content);
1392 EXPECT_EQ(kTestContent, http_request_.content);
1394 // Check the response.
1395 EXPECT_EQ(HTTP_SUCCESS, response.code); // Because it's an existing file
1396 // The start and end positions should be set to -1, if an upload is complete.
1397 EXPECT_EQ(-1, response.start_position_received);
1398 EXPECT_EQ(-1, response.end_position_received);
1401 TEST_F(DriveApiRequestsTest, UploadExistingFileRequestWithETag) {
1402 // Set an expected url for uploading.
1403 expected_upload_path_ = kTestUploadExistingFilePath;
1405 const char kTestContentType[] = "text/plain";
1406 const std::string kTestContent(100, 'a');
1407 const base::FilePath kTestFilePath =
1408 temp_dir_.path().AppendASCII("upload_file.txt");
1409 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1411 GDataErrorCode error = GDATA_OTHER_ERROR;
1414 // Initiate uploading a new file to the directory with "parent_resource_id".
1416 base::RunLoop run_loop;
1417 drive::InitiateUploadExistingFileRequest* request =
1418 new drive::InitiateUploadExistingFileRequest(
1419 request_sender_.get(),
1422 kTestContent.size(),
1423 "resource_id", // The resource id of the file to be overwritten.
1425 test_util::CreateQuitCallback(
1427 test_util::CreateCopyResultCallback(&error, &upload_url)));
1428 request_sender_->StartRequestWithRetry(request);
1432 EXPECT_EQ(HTTP_SUCCESS, error);
1433 EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1434 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1435 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1436 http_request_.headers["X-Upload-Content-Length"]);
1437 EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
1439 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1440 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1441 http_request_.relative_url);
1442 EXPECT_TRUE(http_request_.has_content);
1443 EXPECT_TRUE(http_request_.content.empty());
1445 // Upload the content to the upload URL.
1446 UploadRangeResponse response;
1447 scoped_ptr<FileResource> new_entry;
1450 base::RunLoop run_loop;
1451 drive::ResumeUploadRequest* resume_request =
1452 new drive::ResumeUploadRequest(
1453 request_sender_.get(),
1455 0, // start_position
1456 kTestContent.size(), // end_position (exclusive)
1457 kTestContent.size(), // content_length,
1460 test_util::CreateQuitCallback(
1462 test_util::CreateCopyResultCallback(&response, &new_entry)),
1463 ProgressCallback());
1464 request_sender_->StartRequestWithRetry(resume_request);
1468 // METHOD_PUT should be used to upload data.
1469 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1470 // Request should go to the upload URL.
1471 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1472 // Content-Range header should be added.
1473 EXPECT_EQ("bytes 0-" +
1474 base::Int64ToString(kTestContent.size() - 1) + "/" +
1475 base::Int64ToString(kTestContent.size()),
1476 http_request_.headers["Content-Range"]);
1477 // The upload content should be set in the HTTP request.
1478 EXPECT_TRUE(http_request_.has_content);
1479 EXPECT_EQ(kTestContent, http_request_.content);
1481 // Check the response.
1482 EXPECT_EQ(HTTP_SUCCESS, response.code); // Because it's an existing file
1483 // The start and end positions should be set to -1, if an upload is complete.
1484 EXPECT_EQ(-1, response.start_position_received);
1485 EXPECT_EQ(-1, response.end_position_received);
1488 TEST_F(DriveApiRequestsTest, UploadExistingFileRequestWithETagConflicting) {
1489 // Set an expected url for uploading.
1490 expected_upload_path_ = kTestUploadExistingFilePath;
1492 // If it turned out that the etag is conflicting, PRECONDITION_FAILED should
1494 expected_precondition_failed_file_path_ =
1495 test_util::GetTestFilePath("drive/error.json");
1497 const char kTestContentType[] = "text/plain";
1498 const std::string kTestContent(100, 'a');
1500 GDataErrorCode error = GDATA_OTHER_ERROR;
1503 // Initiate uploading a new file to the directory with "parent_resource_id".
1505 base::RunLoop run_loop;
1506 drive::InitiateUploadExistingFileRequest* request =
1507 new drive::InitiateUploadExistingFileRequest(
1508 request_sender_.get(),
1511 kTestContent.size(),
1512 "resource_id", // The resource id of the file to be overwritten.
1514 test_util::CreateQuitCallback(
1516 test_util::CreateCopyResultCallback(&error, &upload_url)));
1517 request_sender_->StartRequestWithRetry(request);
1521 EXPECT_EQ(HTTP_PRECONDITION, error);
1522 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1523 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1524 http_request_.headers["X-Upload-Content-Length"]);
1525 EXPECT_EQ("Conflicting-etag", http_request_.headers["If-Match"]);
1527 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1528 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1529 http_request_.relative_url);
1530 EXPECT_TRUE(http_request_.has_content);
1531 EXPECT_TRUE(http_request_.content.empty());
1534 TEST_F(DriveApiRequestsTest,
1535 UploadExistingFileRequestWithETagConflictOnResumeUpload) {
1536 // Set an expected url for uploading.
1537 expected_upload_path_ = kTestUploadExistingFilePath;
1539 const char kTestContentType[] = "text/plain";
1540 const std::string kTestContent(100, 'a');
1541 const base::FilePath kTestFilePath =
1542 temp_dir_.path().AppendASCII("upload_file.txt");
1543 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1545 GDataErrorCode error = GDATA_OTHER_ERROR;
1548 // Initiate uploading a new file to the directory with "parent_resource_id".
1550 base::RunLoop run_loop;
1551 drive::InitiateUploadExistingFileRequest* request =
1552 new drive::InitiateUploadExistingFileRequest(
1553 request_sender_.get(),
1556 kTestContent.size(),
1557 "resource_id", // The resource id of the file to be overwritten.
1559 test_util::CreateQuitCallback(
1561 test_util::CreateCopyResultCallback(&error, &upload_url)));
1562 request_sender_->StartRequestWithRetry(request);
1566 EXPECT_EQ(HTTP_SUCCESS, error);
1567 EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1568 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1569 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1570 http_request_.headers["X-Upload-Content-Length"]);
1571 EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
1573 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1574 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1575 http_request_.relative_url);
1576 EXPECT_TRUE(http_request_.has_content);
1577 EXPECT_TRUE(http_request_.content.empty());
1579 // Set PRECONDITION_FAILED to the server. This is the emulation of the
1580 // confliction during uploading.
1581 expected_precondition_failed_file_path_ =
1582 test_util::GetTestFilePath("drive/error.json");
1584 // Upload the content to the upload URL.
1585 UploadRangeResponse response;
1586 scoped_ptr<FileResource> new_entry;
1589 base::RunLoop run_loop;
1590 drive::ResumeUploadRequest* resume_request =
1591 new drive::ResumeUploadRequest(
1592 request_sender_.get(),
1594 0, // start_position
1595 kTestContent.size(), // end_position (exclusive)
1596 kTestContent.size(), // content_length,
1599 test_util::CreateQuitCallback(
1601 test_util::CreateCopyResultCallback(&response, &new_entry)),
1602 ProgressCallback());
1603 request_sender_->StartRequestWithRetry(resume_request);
1607 // METHOD_PUT should be used to upload data.
1608 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1609 // Request should go to the upload URL.
1610 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1611 // Content-Range header should be added.
1612 EXPECT_EQ("bytes 0-" +
1613 base::Int64ToString(kTestContent.size() - 1) + "/" +
1614 base::Int64ToString(kTestContent.size()),
1615 http_request_.headers["Content-Range"]);
1616 // The upload content should be set in the HTTP request.
1617 EXPECT_TRUE(http_request_.has_content);
1618 EXPECT_EQ(kTestContent, http_request_.content);
1620 // Check the response.
1621 EXPECT_EQ(HTTP_PRECONDITION, response.code);
1622 // The start and end positions should be set to -1 for error.
1623 EXPECT_EQ(-1, response.start_position_received);
1624 EXPECT_EQ(-1, response.end_position_received);
1626 // New entry should be NULL.
1627 EXPECT_FALSE(new_entry.get());
1630 TEST_F(DriveApiRequestsTest, UploadExistingFileWithMetadataRequest) {
1631 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
1632 const base::Time::Exploded kLastViewedByMeDate =
1633 {2013, 7, 0, 19, 15, 59, 13, 123};
1635 // Set an expected url for uploading.
1636 expected_upload_path_ = kTestUploadExistingFilePath;
1638 const char kTestContentType[] = "text/plain";
1639 const std::string kTestContent(100, 'a');
1641 GDataErrorCode error = GDATA_OTHER_ERROR;
1644 // Initiate uploading a new file to the directory with "parent_resource_id".
1646 base::RunLoop run_loop;
1647 drive::InitiateUploadExistingFileRequest* request =
1648 new drive::InitiateUploadExistingFileRequest(
1649 request_sender_.get(),
1652 kTestContent.size(),
1653 "resource_id", // The resource id of the file to be overwritten.
1655 test_util::CreateQuitCallback(
1657 test_util::CreateCopyResultCallback(&error, &upload_url)));
1658 request->set_parent_resource_id("new_parent_resource_id");
1659 request->set_title("new file title");
1660 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
1661 request->set_last_viewed_by_me_date(
1662 base::Time::FromUTCExploded(kLastViewedByMeDate));
1664 request_sender_->StartRequestWithRetry(request);
1668 EXPECT_EQ(HTTP_SUCCESS, error);
1669 EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1670 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1671 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1672 http_request_.headers["X-Upload-Content-Length"]);
1673 EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
1675 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1676 EXPECT_EQ("/upload/drive/v2/files/resource_id?"
1677 "uploadType=resumable&setModifiedDate=true",
1678 http_request_.relative_url);
1679 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1680 EXPECT_TRUE(http_request_.has_content);
1681 EXPECT_EQ("{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
1682 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
1683 "\"parents\":[{\"id\":\"new_parent_resource_id\","
1684 "\"kind\":\"drive#fileLink\"}],"
1685 "\"title\":\"new file title\"}",
1686 http_request_.content);
1689 TEST_F(DriveApiRequestsTest, DownloadFileRequest) {
1690 const base::FilePath kDownloadedFilePath =
1691 temp_dir_.path().AppendASCII("cache_file");
1692 const std::string kTestId("dummyId");
1694 GDataErrorCode result_code = GDATA_OTHER_ERROR;
1695 base::FilePath temp_file;
1697 base::RunLoop run_loop;
1698 drive::DownloadFileRequest* request = new drive::DownloadFileRequest(
1699 request_sender_.get(),
1702 kDownloadedFilePath,
1703 test_util::CreateQuitCallback(
1705 test_util::CreateCopyResultCallback(&result_code, &temp_file)),
1706 GetContentCallback(),
1707 ProgressCallback());
1708 request_sender_->StartRequestWithRetry(request);
1712 std::string contents;
1713 base::ReadFileToString(temp_file, &contents);
1714 base::DeleteFile(temp_file, false);
1716 EXPECT_EQ(HTTP_SUCCESS, result_code);
1717 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
1718 EXPECT_EQ(kTestDownloadPathPrefix + kTestId, http_request_.relative_url);
1719 EXPECT_EQ(kDownloadedFilePath, temp_file);
1721 const std::string expected_contents = kTestId + kTestId + kTestId;
1722 EXPECT_EQ(expected_contents, contents);
1725 TEST_F(DriveApiRequestsTest, DownloadFileRequest_GetContentCallback) {
1726 const base::FilePath kDownloadedFilePath =
1727 temp_dir_.path().AppendASCII("cache_file");
1728 const std::string kTestId("dummyId");
1730 GDataErrorCode result_code = GDATA_OTHER_ERROR;
1731 base::FilePath temp_file;
1732 std::string contents;
1734 base::RunLoop run_loop;
1735 drive::DownloadFileRequest* request = new drive::DownloadFileRequest(
1736 request_sender_.get(),
1739 kDownloadedFilePath,
1740 test_util::CreateQuitCallback(
1742 test_util::CreateCopyResultCallback(&result_code, &temp_file)),
1743 base::Bind(&AppendContent, &contents),
1744 ProgressCallback());
1745 request_sender_->StartRequestWithRetry(request);
1749 base::DeleteFile(temp_file, false);
1751 EXPECT_EQ(HTTP_SUCCESS, result_code);
1752 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
1753 EXPECT_EQ(kTestDownloadPathPrefix + kTestId, http_request_.relative_url);
1754 EXPECT_EQ(kDownloadedFilePath, temp_file);
1756 const std::string expected_contents = kTestId + kTestId + kTestId;
1757 EXPECT_EQ(expected_contents, contents);
1760 } // namespace google_apis