Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / google_apis / drive / drive_api_requests_unittest.cc
blob358715ec2c9dd77cc091d95e195a6f41b0308fff
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.
5 #include "base/bind.h"
6 #include "base/files/file_path.h"
7 #include "base/files/file_util.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/json/json_reader.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/values.h"
15 #include "google_apis/drive/drive_api_parser.h"
16 #include "google_apis/drive/drive_api_requests.h"
17 #include "google_apis/drive/drive_api_url_generator.h"
18 #include "google_apis/drive/dummy_auth_service.h"
19 #include "google_apis/drive/request_sender.h"
20 #include "google_apis/drive/test_util.h"
21 #include "net/test/embedded_test_server/embedded_test_server.h"
22 #include "net/test/embedded_test_server/http_request.h"
23 #include "net/test/embedded_test_server/http_response.h"
24 #include "net/url_request/url_request_test_util.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 namespace google_apis {
29 namespace {
31 const char kTestETag[] = "test_etag";
32 const char kTestUserAgent[] = "test-user-agent";
34 const char kTestChildrenResponse[] =
35 "{\n"
36 "\"kind\": \"drive#childReference\",\n"
37 "\"id\": \"resource_id\",\n"
38 "\"selfLink\": \"self_link\",\n"
39 "\"childLink\": \"child_link\",\n"
40 "}\n";
42 const char kTestPermissionResponse[] =
43 "{\n"
44 "\"kind\": \"drive#permission\",\n"
45 "\"id\": \"resource_id\",\n"
46 "\"selfLink\": \"self_link\",\n"
47 "}\n";
49 const char kTestUploadExistingFilePath[] = "/upload/existingfile/path";
50 const char kTestUploadNewFilePath[] = "/upload/newfile/path";
51 const char kTestDownloadPathPrefix[] = "/host/";
53 // Used as a GetContentCallback.
54 void AppendContent(std::string* out,
55 DriveApiErrorCode error,
56 scoped_ptr<std::string> content) {
57 EXPECT_EQ(HTTP_SUCCESS, error);
58 out->append(*content);
61 class TestBatchableDelegate : public BatchableDelegate {
62 public:
63 TestBatchableDelegate(const GURL url,
64 const std::string& content_type,
65 const std::string& content_data,
66 const base::Closure& callback)
67 : url_(url),
68 content_type_(content_type),
69 content_data_(content_data),
70 callback_(callback) {}
71 GURL GetURL() const override { return url_; }
72 net::URLFetcher::RequestType GetRequestType() const override {
73 return net::URLFetcher::PUT;
75 std::vector<std::string> GetExtraRequestHeaders() const override {
76 return std::vector<std::string>();
78 void Prepare(const PrepareCallback& callback) override {
79 callback.Run(HTTP_SUCCESS);
81 bool GetContentData(std::string* upload_content_type,
82 std::string* upload_content) override {
83 upload_content_type->assign(content_type_);
84 upload_content->assign(content_data_);
85 return true;
87 void NotifyError(DriveApiErrorCode code) override { callback_.Run(); }
88 void NotifyResult(DriveApiErrorCode code,
89 const std::string& body,
90 const base::Closure& closure) override {
91 callback_.Run();
92 closure.Run();
94 void NotifyUploadProgress(const net::URLFetcher* source,
95 int64 current,
96 int64 total) override {
97 progress_values_.push_back(current);
99 const std::vector<int64>& progress_values() const { return progress_values_; }
101 private:
102 GURL url_;
103 std::string content_type_;
104 std::string content_data_;
105 base::Closure callback_;
106 std::vector<int64> progress_values_;
109 void EmptyPreapreCallback(DriveApiErrorCode) {
111 void EmptyClosure() {
114 } // namespace
116 class DriveApiRequestsTest : public testing::Test {
117 public:
118 DriveApiRequestsTest() {
121 void SetUp() override {
122 request_context_getter_ = new net::TestURLRequestContextGetter(
123 message_loop_.task_runner());
125 request_sender_.reset(new RequestSender(new DummyAuthService,
126 request_context_getter_.get(),
127 message_loop_.task_runner(),
128 kTestUserAgent));
130 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
132 ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady());
133 test_server_.RegisterRequestHandler(
134 base::Bind(&DriveApiRequestsTest::HandleChildrenDeleteRequest,
135 base::Unretained(this)));
136 test_server_.RegisterRequestHandler(
137 base::Bind(&DriveApiRequestsTest::HandleDataFileRequest,
138 base::Unretained(this)));
139 test_server_.RegisterRequestHandler(
140 base::Bind(&DriveApiRequestsTest::HandleDeleteRequest,
141 base::Unretained(this)));
142 test_server_.RegisterRequestHandler(
143 base::Bind(&DriveApiRequestsTest::HandlePreconditionFailedRequest,
144 base::Unretained(this)));
145 test_server_.RegisterRequestHandler(
146 base::Bind(&DriveApiRequestsTest::HandleResumeUploadRequest,
147 base::Unretained(this)));
148 test_server_.RegisterRequestHandler(
149 base::Bind(&DriveApiRequestsTest::HandleInitiateUploadRequest,
150 base::Unretained(this)));
151 test_server_.RegisterRequestHandler(
152 base::Bind(&DriveApiRequestsTest::HandleContentResponse,
153 base::Unretained(this)));
154 test_server_.RegisterRequestHandler(
155 base::Bind(&DriveApiRequestsTest::HandleDownloadRequest,
156 base::Unretained(this)));
157 test_server_.RegisterRequestHandler(
158 base::Bind(&DriveApiRequestsTest::HandleBatchUploadRequest,
159 base::Unretained(this)));
161 GURL test_base_url = test_util::GetBaseUrlForTesting(test_server_.port());
162 url_generator_.reset(
163 new DriveApiUrlGenerator(test_base_url, test_base_url));
165 // Reset the server's expected behavior just in case.
166 ResetExpectedResponse();
167 received_bytes_ = 0;
168 content_length_ = 0;
170 // Testing properties used by multiple test cases.
171 drive::Property private_property;
172 private_property.set_key("key1");
173 private_property.set_value("value1");
175 drive::Property public_property;
176 public_property.set_visibility(drive::Property::VISIBILITY_PUBLIC);
177 public_property.set_key("key2");
178 public_property.set_value("value2");
180 testing_properties_.clear();
181 testing_properties_.push_back(private_property);
182 testing_properties_.push_back(public_property);
185 base::MessageLoopForIO message_loop_; // Test server needs IO thread.
186 net::test_server::EmbeddedTestServer test_server_;
187 scoped_ptr<RequestSender> request_sender_;
188 scoped_ptr<DriveApiUrlGenerator> url_generator_;
189 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
190 base::ScopedTempDir temp_dir_;
192 // This is a path to the file which contains expected response from
193 // the server. See also HandleDataFileRequest below.
194 base::FilePath expected_data_file_path_;
196 // This is a path string in the expected response header from the server
197 // for initiating file uploading.
198 std::string expected_upload_path_;
200 // This is a path to the file which contains expected response for
201 // PRECONDITION_FAILED response.
202 base::FilePath expected_precondition_failed_file_path_;
204 // These are content and its type in the expected response from the server.
205 // See also HandleContentResponse below.
206 std::string expected_content_type_;
207 std::string expected_content_;
209 // The incoming HTTP request is saved so tests can verify the request
210 // parameters like HTTP method (ex. some requests should use DELETE
211 // instead of GET).
212 net::test_server::HttpRequest http_request_;
214 // Testing properties used by multiple test cases.
215 drive::Properties testing_properties_;
217 private:
218 void ResetExpectedResponse() {
219 expected_data_file_path_.clear();
220 expected_upload_path_.clear();
221 expected_content_type_.clear();
222 expected_content_.clear();
225 // For "Children: delete" request, the server will return "204 No Content"
226 // response meaning "success".
227 scoped_ptr<net::test_server::HttpResponse> HandleChildrenDeleteRequest(
228 const net::test_server::HttpRequest& request) {
229 if (request.method != net::test_server::METHOD_DELETE ||
230 request.relative_url.find("/children/") == std::string::npos) {
231 // The request is not the "Children: delete" request. Delegate the
232 // processing to the next handler.
233 return scoped_ptr<net::test_server::HttpResponse>();
236 http_request_ = request;
238 // Return the response with just "204 No Content" status code.
239 scoped_ptr<net::test_server::BasicHttpResponse> http_response(
240 new net::test_server::BasicHttpResponse);
241 http_response->set_code(net::HTTP_NO_CONTENT);
242 return http_response.Pass();
245 // Reads the data file of |expected_data_file_path_| and returns its content
246 // for the request.
247 // To use this method, it is necessary to set |expected_data_file_path_|
248 // to the appropriate file path before sending the request to the server.
249 scoped_ptr<net::test_server::HttpResponse> HandleDataFileRequest(
250 const net::test_server::HttpRequest& request) {
251 if (expected_data_file_path_.empty()) {
252 // The file is not specified. Delegate the processing to the next
253 // handler.
254 return scoped_ptr<net::test_server::HttpResponse>();
257 http_request_ = request;
259 // Return the response from the data file.
260 return test_util::CreateHttpResponseFromFile(expected_data_file_path_);
263 // Deletes the resource and returns no content with HTTP_NO_CONTENT status
264 // code.
265 scoped_ptr<net::test_server::HttpResponse> HandleDeleteRequest(
266 const net::test_server::HttpRequest& request) {
267 if (request.method != net::test_server::METHOD_DELETE ||
268 request.relative_url.find("/files/") == std::string::npos) {
269 // The file is not file deletion request. Delegate the processing to the
270 // next handler.
271 return scoped_ptr<net::test_server::HttpResponse>();
274 http_request_ = request;
276 scoped_ptr<net::test_server::BasicHttpResponse> response(
277 new net::test_server::BasicHttpResponse);
278 response->set_code(net::HTTP_NO_CONTENT);
280 return response.Pass();
283 // Returns PRECONDITION_FAILED response for ETag mismatching with error JSON
284 // content specified by |expected_precondition_failed_file_path_|.
285 // To use this method, it is necessary to set the variable to the appropriate
286 // file path before sending the request to the server.
287 scoped_ptr<net::test_server::HttpResponse> HandlePreconditionFailedRequest(
288 const net::test_server::HttpRequest& request) {
289 if (expected_precondition_failed_file_path_.empty()) {
290 // The file is not specified. Delegate the process to the next handler.
291 return scoped_ptr<net::test_server::HttpResponse>();
294 http_request_ = request;
296 scoped_ptr<net::test_server::BasicHttpResponse> response(
297 new net::test_server::BasicHttpResponse);
298 response->set_code(net::HTTP_PRECONDITION_FAILED);
300 std::string content;
301 if (base::ReadFileToString(expected_precondition_failed_file_path_,
302 &content)) {
303 response->set_content(content);
304 response->set_content_type("application/json");
307 return response.Pass();
310 // Returns the response based on set expected upload url.
311 // The response contains the url in its "Location: " header. Also, it doesn't
312 // have any content.
313 // To use this method, it is necessary to set |expected_upload_path_|
314 // to the string representation of the url to be returned.
315 scoped_ptr<net::test_server::HttpResponse> HandleInitiateUploadRequest(
316 const net::test_server::HttpRequest& request) {
317 if (request.relative_url == expected_upload_path_ ||
318 expected_upload_path_.empty()) {
319 // The request is for resume uploading or the expected upload url is not
320 // set. Delegate the processing to the next handler.
321 return scoped_ptr<net::test_server::HttpResponse>();
324 http_request_ = request;
326 scoped_ptr<net::test_server::BasicHttpResponse> response(
327 new net::test_server::BasicHttpResponse);
329 // Check if the X-Upload-Content-Length is present. If yes, store the
330 // length of the file.
331 std::map<std::string, std::string>::const_iterator found =
332 request.headers.find("X-Upload-Content-Length");
333 if (found == request.headers.end() ||
334 !base::StringToInt64(found->second, &content_length_)) {
335 return scoped_ptr<net::test_server::HttpResponse>();
337 received_bytes_ = 0;
339 response->set_code(net::HTTP_OK);
340 response->AddCustomHeader(
341 "Location",
342 test_server_.base_url().Resolve(expected_upload_path_).spec());
343 return response.Pass();
346 scoped_ptr<net::test_server::HttpResponse> HandleResumeUploadRequest(
347 const net::test_server::HttpRequest& request) {
348 if (request.relative_url != expected_upload_path_) {
349 // The request path is different from the expected path for uploading.
350 // Delegate the processing to the next handler.
351 return scoped_ptr<net::test_server::HttpResponse>();
354 http_request_ = request;
356 if (!request.content.empty()) {
357 std::map<std::string, std::string>::const_iterator iter =
358 request.headers.find("Content-Range");
359 if (iter == request.headers.end()) {
360 // The range must be set.
361 return scoped_ptr<net::test_server::HttpResponse>();
364 int64 length = 0;
365 int64 start_position = 0;
366 int64 end_position = 0;
367 if (!test_util::ParseContentRangeHeader(
368 iter->second, &start_position, &end_position, &length)) {
369 // Invalid "Content-Range" value.
370 return scoped_ptr<net::test_server::HttpResponse>();
373 EXPECT_EQ(start_position, received_bytes_);
374 EXPECT_EQ(length, content_length_);
376 // end_position is inclusive, but so +1 to change the range to byte size.
377 received_bytes_ = end_position + 1;
380 if (received_bytes_ < content_length_) {
381 scoped_ptr<net::test_server::BasicHttpResponse> response(
382 new net::test_server::BasicHttpResponse);
383 // Set RESUME INCOMPLETE (308) status code.
384 response->set_code(static_cast<net::HttpStatusCode>(308));
386 // Add Range header to the response, based on the values of
387 // Content-Range header in the request.
388 // The header is annotated only when at least one byte is received.
389 if (received_bytes_ > 0) {
390 response->AddCustomHeader(
391 "Range", "bytes=0-" + base::Int64ToString(received_bytes_ - 1));
394 return response.Pass();
397 // All bytes are received. Return the "success" response with the file's
398 // (dummy) metadata.
399 scoped_ptr<net::test_server::BasicHttpResponse> response =
400 test_util::CreateHttpResponseFromFile(
401 test_util::GetTestFilePath("drive/file_entry.json"));
403 // The response code is CREATED if it is new file uploading.
404 if (http_request_.relative_url == kTestUploadNewFilePath) {
405 response->set_code(net::HTTP_CREATED);
408 return response.Pass();
411 // Returns the response based on set expected content and its type.
412 // To use this method, both |expected_content_type_| and |expected_content_|
413 // must be set in advance.
414 scoped_ptr<net::test_server::HttpResponse> HandleContentResponse(
415 const net::test_server::HttpRequest& request) {
416 if (expected_content_type_.empty() || expected_content_.empty()) {
417 // Expected content is not set. Delegate the processing to the next
418 // handler.
419 return scoped_ptr<net::test_server::HttpResponse>();
422 http_request_ = request;
424 scoped_ptr<net::test_server::BasicHttpResponse> response(
425 new net::test_server::BasicHttpResponse);
426 response->set_code(net::HTTP_OK);
427 response->set_content_type(expected_content_type_);
428 response->set_content(expected_content_);
429 return response.Pass();
432 // Handles a request for downloading a file.
433 scoped_ptr<net::test_server::HttpResponse> HandleDownloadRequest(
434 const net::test_server::HttpRequest& request) {
435 http_request_ = request;
437 const GURL absolute_url = test_server_.GetURL(request.relative_url);
438 std::string id;
439 if (!test_util::RemovePrefix(absolute_url.path(),
440 kTestDownloadPathPrefix,
441 &id)) {
442 return scoped_ptr<net::test_server::HttpResponse>();
445 // For testing, returns a text with |id| repeated 3 times.
446 scoped_ptr<net::test_server::BasicHttpResponse> response(
447 new net::test_server::BasicHttpResponse);
448 response->set_code(net::HTTP_OK);
449 response->set_content(id + id + id);
450 response->set_content_type("text/plain");
451 return response.Pass();
454 scoped_ptr<net::test_server::HttpResponse> HandleBatchUploadRequest(
455 const net::test_server::HttpRequest& request) {
456 http_request_ = request;
458 const GURL absolute_url = test_server_.GetURL(request.relative_url);
459 std::string id;
460 if (absolute_url.path() != "/upload/drive")
461 return scoped_ptr<net::test_server::HttpResponse>();
463 scoped_ptr<net::test_server::BasicHttpResponse> response(
464 new net::test_server::BasicHttpResponse);
465 response->set_code(net::HTTP_OK);
466 response->set_content_type("multipart/mixed; boundary=BOUNDARY");
467 response->set_content(
468 "--BOUNDARY\r\n"
469 "Content-Type: application/http\r\n"
470 "\r\n"
471 "HTTP/1.1 200 OK\r\n"
472 "Content-Type: application/json; charset=UTF-8\r\n"
473 "\r\n"
474 "{\r\n"
475 " \"kind\": \"drive#file\",\r\n"
476 " \"id\": \"file_id_1\"\r\n"
477 "}\r\n"
478 "\r\n"
479 "--BOUNDARY\r\n"
480 "Content-Type: application/http\r\n"
481 "\r\n"
482 "HTTP/1.1 403 Forbidden\r\n"
483 "Content-Type: application/json; charset=UTF-8\r\n"
484 "\r\n"
485 "{\"error\":{\"errors\": ["
486 " {\"reason\": \"userRateLimitExceeded\"}]}}\r\n"
487 "\r\n"
488 "--BOUNDARY--\r\n");
489 return response.Pass();
492 // These are for the current upload file status.
493 int64 received_bytes_;
494 int64 content_length_;
497 TEST_F(DriveApiRequestsTest, DriveApiDataRequest_Fields) {
498 // Make sure that "fields" query param is supported by using its subclass,
499 // AboutGetRequest.
501 // Set an expected data file containing valid result.
502 expected_data_file_path_ = test_util::GetTestFilePath(
503 "drive/about.json");
505 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
506 scoped_ptr<AboutResource> about_resource;
509 base::RunLoop run_loop;
510 drive::AboutGetRequest* request = new drive::AboutGetRequest(
511 request_sender_.get(),
512 *url_generator_,
513 test_util::CreateQuitCallback(
514 &run_loop,
515 test_util::CreateCopyResultCallback(&error, &about_resource)));
516 request->set_fields("kind,quotaBytesTotal,quotaBytesUsedAggregate,"
517 "largestChangeId,rootFolderId");
518 request_sender_->StartRequestWithAuthRetry(request);
519 run_loop.Run();
522 EXPECT_EQ(HTTP_SUCCESS, error);
523 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
524 EXPECT_EQ("/drive/v2/about?"
525 "fields=kind%2CquotaBytesTotal%2CquotaBytesUsedAggregate%2C"
526 "largestChangeId%2CrootFolderId",
527 http_request_.relative_url);
529 scoped_ptr<AboutResource> expected(
530 AboutResource::CreateFrom(
531 *test_util::LoadJSONFile("drive/about.json")));
532 ASSERT_TRUE(about_resource.get());
533 EXPECT_EQ(expected->largest_change_id(), about_resource->largest_change_id());
534 EXPECT_EQ(expected->quota_bytes_total(), about_resource->quota_bytes_total());
535 EXPECT_EQ(expected->quota_bytes_used_aggregate(),
536 about_resource->quota_bytes_used_aggregate());
537 EXPECT_EQ(expected->root_folder_id(), about_resource->root_folder_id());
540 TEST_F(DriveApiRequestsTest, FilesInsertRequest) {
541 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
542 const base::Time::Exploded kLastViewedByMeDate =
543 {2013, 7, 0, 19, 15, 59, 13, 123};
545 // Set an expected data file containing the directory's entry data.
546 expected_data_file_path_ =
547 test_util::GetTestFilePath("drive/directory_entry.json");
549 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
550 scoped_ptr<FileResource> file_resource;
552 // Create "new directory" in the root directory.
554 base::RunLoop run_loop;
555 drive::FilesInsertRequest* request = new drive::FilesInsertRequest(
556 request_sender_.get(),
557 *url_generator_,
558 test_util::CreateQuitCallback(
559 &run_loop,
560 test_util::CreateCopyResultCallback(&error, &file_resource)));
561 request->set_visibility(drive::FILE_VISIBILITY_PRIVATE);
562 request->set_last_viewed_by_me_date(
563 base::Time::FromUTCExploded(kLastViewedByMeDate));
564 request->set_mime_type("application/vnd.google-apps.folder");
565 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
566 request->add_parent("root");
567 request->set_title("new directory");
568 request->set_properties(testing_properties_);
569 request_sender_->StartRequestWithAuthRetry(request);
570 run_loop.Run();
573 EXPECT_EQ(HTTP_SUCCESS, error);
574 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
575 EXPECT_EQ("/drive/v2/files?visibility=PRIVATE", http_request_.relative_url);
576 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
578 EXPECT_TRUE(http_request_.has_content);
579 EXPECT_EQ(
580 "{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
581 "\"mimeType\":\"application/vnd.google-apps.folder\","
582 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
583 "\"parents\":[{\"id\":\"root\"}],"
584 "\"properties\":["
585 "{\"key\":\"key1\",\"value\":\"value1\",\"visibility\":\"PRIVATE\"},"
586 "{\"key\":\"key2\",\"value\":\"value2\",\"visibility\":\"PUBLIC\"}],"
587 "\"title\":\"new directory\"}",
588 http_request_.content);
590 scoped_ptr<FileResource> expected(
591 FileResource::CreateFrom(
592 *test_util::LoadJSONFile("drive/directory_entry.json")));
594 // Sanity check.
595 ASSERT_TRUE(file_resource.get());
597 EXPECT_EQ(expected->file_id(), file_resource->file_id());
598 EXPECT_EQ(expected->title(), file_resource->title());
599 EXPECT_EQ(expected->mime_type(), file_resource->mime_type());
600 EXPECT_EQ(expected->parents().size(), file_resource->parents().size());
603 TEST_F(DriveApiRequestsTest, FilesPatchRequest) {
604 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
605 const base::Time::Exploded kLastViewedByMeDate =
606 {2013, 7, 0, 19, 15, 59, 13, 123};
608 // Set an expected data file containing valid result.
609 expected_data_file_path_ =
610 test_util::GetTestFilePath("drive/file_entry.json");
612 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
613 scoped_ptr<FileResource> file_resource;
616 base::RunLoop run_loop;
617 drive::FilesPatchRequest* request = new drive::FilesPatchRequest(
618 request_sender_.get(),
619 *url_generator_,
620 test_util::CreateQuitCallback(
621 &run_loop,
622 test_util::CreateCopyResultCallback(&error, &file_resource)));
623 request->set_file_id("resource_id");
624 request->set_set_modified_date(true);
625 request->set_update_viewed_date(false);
627 request->set_title("new title");
628 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
629 request->set_last_viewed_by_me_date(
630 base::Time::FromUTCExploded(kLastViewedByMeDate));
631 request->add_parent("parent_resource_id");
633 request->set_properties(testing_properties_);
634 request_sender_->StartRequestWithAuthRetry(request);
635 run_loop.Run();
638 EXPECT_EQ(HTTP_SUCCESS, error);
639 EXPECT_EQ(net::test_server::METHOD_PATCH, http_request_.method);
640 EXPECT_EQ("/drive/v2/files/resource_id"
641 "?setModifiedDate=true&updateViewedDate=false",
642 http_request_.relative_url);
644 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
645 EXPECT_TRUE(http_request_.has_content);
646 EXPECT_EQ(
647 "{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
648 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
649 "\"parents\":[{\"id\":\"parent_resource_id\"}],"
650 "\"properties\":["
651 "{\"key\":\"key1\",\"value\":\"value1\",\"visibility\":\"PRIVATE\"},"
652 "{\"key\":\"key2\",\"value\":\"value2\",\"visibility\":\"PUBLIC\"}],"
653 "\"title\":\"new title\"}",
654 http_request_.content);
655 EXPECT_TRUE(file_resource);
658 TEST_F(DriveApiRequestsTest, AboutGetRequest_ValidJson) {
659 // Set an expected data file containing valid result.
660 expected_data_file_path_ = test_util::GetTestFilePath(
661 "drive/about.json");
663 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
664 scoped_ptr<AboutResource> about_resource;
667 base::RunLoop run_loop;
668 drive::AboutGetRequest* request = new drive::AboutGetRequest(
669 request_sender_.get(),
670 *url_generator_,
671 test_util::CreateQuitCallback(
672 &run_loop,
673 test_util::CreateCopyResultCallback(&error, &about_resource)));
674 request_sender_->StartRequestWithAuthRetry(request);
675 run_loop.Run();
678 EXPECT_EQ(HTTP_SUCCESS, error);
679 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
680 EXPECT_EQ("/drive/v2/about", http_request_.relative_url);
682 scoped_ptr<AboutResource> expected(
683 AboutResource::CreateFrom(
684 *test_util::LoadJSONFile("drive/about.json")));
685 ASSERT_TRUE(about_resource.get());
686 EXPECT_EQ(expected->largest_change_id(), about_resource->largest_change_id());
687 EXPECT_EQ(expected->quota_bytes_total(), about_resource->quota_bytes_total());
688 EXPECT_EQ(expected->quota_bytes_used_aggregate(),
689 about_resource->quota_bytes_used_aggregate());
690 EXPECT_EQ(expected->root_folder_id(), about_resource->root_folder_id());
693 TEST_F(DriveApiRequestsTest, AboutGetRequest_InvalidJson) {
694 // Set an expected data file containing invalid result.
695 expected_data_file_path_ = test_util::GetTestFilePath(
696 "drive/testfile.txt");
698 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
699 scoped_ptr<AboutResource> about_resource;
702 base::RunLoop run_loop;
703 drive::AboutGetRequest* request = new drive::AboutGetRequest(
704 request_sender_.get(),
705 *url_generator_,
706 test_util::CreateQuitCallback(
707 &run_loop,
708 test_util::CreateCopyResultCallback(&error, &about_resource)));
709 request_sender_->StartRequestWithAuthRetry(request);
710 run_loop.Run();
713 // "parse error" should be returned, and the about resource should be NULL.
714 EXPECT_EQ(DRIVE_PARSE_ERROR, error);
715 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
716 EXPECT_EQ("/drive/v2/about", http_request_.relative_url);
717 EXPECT_FALSE(about_resource);
720 TEST_F(DriveApiRequestsTest, AppsListRequest) {
721 // Set an expected data file containing valid result.
722 expected_data_file_path_ = test_util::GetTestFilePath(
723 "drive/applist.json");
725 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
726 scoped_ptr<AppList> app_list;
729 base::RunLoop run_loop;
730 drive::AppsListRequest* request = new drive::AppsListRequest(
731 request_sender_.get(),
732 *url_generator_,
733 false, // use_internal_endpoint
734 test_util::CreateQuitCallback(
735 &run_loop,
736 test_util::CreateCopyResultCallback(&error, &app_list)));
737 request_sender_->StartRequestWithAuthRetry(request);
738 run_loop.Run();
741 EXPECT_EQ(HTTP_SUCCESS, error);
742 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
743 EXPECT_EQ("/drive/v2/apps", http_request_.relative_url);
744 EXPECT_TRUE(app_list);
747 TEST_F(DriveApiRequestsTest, ChangesListRequest) {
748 // Set an expected data file containing valid result.
749 expected_data_file_path_ = test_util::GetTestFilePath(
750 "drive/changelist.json");
752 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
753 scoped_ptr<ChangeList> result;
756 base::RunLoop run_loop;
757 drive::ChangesListRequest* request = new drive::ChangesListRequest(
758 request_sender_.get(), *url_generator_,
759 test_util::CreateQuitCallback(
760 &run_loop,
761 test_util::CreateCopyResultCallback(&error, &result)));
762 request->set_include_deleted(true);
763 request->set_start_change_id(100);
764 request->set_max_results(500);
765 request_sender_->StartRequestWithAuthRetry(request);
766 run_loop.Run();
769 EXPECT_EQ(HTTP_SUCCESS, error);
770 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
771 EXPECT_EQ("/drive/v2/changes?maxResults=500&startChangeId=100",
772 http_request_.relative_url);
773 EXPECT_TRUE(result);
776 TEST_F(DriveApiRequestsTest, ChangesListNextPageRequest) {
777 // Set an expected data file containing valid result.
778 expected_data_file_path_ = test_util::GetTestFilePath(
779 "drive/changelist.json");
781 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
782 scoped_ptr<ChangeList> result;
785 base::RunLoop run_loop;
786 drive::ChangesListNextPageRequest* request =
787 new drive::ChangesListNextPageRequest(
788 request_sender_.get(),
789 test_util::CreateQuitCallback(
790 &run_loop,
791 test_util::CreateCopyResultCallback(&error, &result)));
792 request->set_next_link(test_server_.GetURL("/continue/get/change/list"));
793 request_sender_->StartRequestWithAuthRetry(request);
794 run_loop.Run();
797 EXPECT_EQ(HTTP_SUCCESS, error);
798 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
799 EXPECT_EQ("/continue/get/change/list", http_request_.relative_url);
800 EXPECT_TRUE(result);
803 TEST_F(DriveApiRequestsTest, FilesCopyRequest) {
804 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
806 // Set an expected data file containing the dummy file entry data.
807 // It'd be returned if we copy a file.
808 expected_data_file_path_ =
809 test_util::GetTestFilePath("drive/file_entry.json");
811 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
812 scoped_ptr<FileResource> file_resource;
814 // Copy the file to a new file named "new title".
816 base::RunLoop run_loop;
817 drive::FilesCopyRequest* request = new drive::FilesCopyRequest(
818 request_sender_.get(),
819 *url_generator_,
820 test_util::CreateQuitCallback(
821 &run_loop,
822 test_util::CreateCopyResultCallback(&error, &file_resource)));
823 request->set_visibility(drive::FILE_VISIBILITY_PRIVATE);
824 request->set_file_id("resource_id");
825 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
826 request->add_parent("parent_resource_id");
827 request->set_title("new title");
828 request_sender_->StartRequestWithAuthRetry(request);
829 run_loop.Run();
832 EXPECT_EQ(HTTP_SUCCESS, error);
833 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
834 EXPECT_EQ("/drive/v2/files/resource_id/copy?visibility=PRIVATE",
835 http_request_.relative_url);
836 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
838 EXPECT_TRUE(http_request_.has_content);
839 EXPECT_EQ(
840 "{\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
841 "\"parents\":[{\"id\":\"parent_resource_id\"}],\"title\":\"new title\"}",
842 http_request_.content);
843 EXPECT_TRUE(file_resource);
846 TEST_F(DriveApiRequestsTest, FilesCopyRequest_EmptyParentResourceId) {
847 // Set an expected data file containing the dummy file entry data.
848 // It'd be returned if we copy a file.
849 expected_data_file_path_ =
850 test_util::GetTestFilePath("drive/file_entry.json");
852 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
853 scoped_ptr<FileResource> file_resource;
855 // Copy the file to a new file named "new title".
857 base::RunLoop run_loop;
858 drive::FilesCopyRequest* request = new drive::FilesCopyRequest(
859 request_sender_.get(),
860 *url_generator_,
861 test_util::CreateQuitCallback(
862 &run_loop,
863 test_util::CreateCopyResultCallback(&error, &file_resource)));
864 request->set_file_id("resource_id");
865 request->set_title("new title");
866 request_sender_->StartRequestWithAuthRetry(request);
867 run_loop.Run();
870 EXPECT_EQ(HTTP_SUCCESS, error);
871 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
872 EXPECT_EQ("/drive/v2/files/resource_id/copy", http_request_.relative_url);
873 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
875 EXPECT_TRUE(http_request_.has_content);
876 EXPECT_EQ("{\"title\":\"new title\"}", http_request_.content);
877 EXPECT_TRUE(file_resource);
880 TEST_F(DriveApiRequestsTest, FilesListRequest) {
881 // Set an expected data file containing valid result.
882 expected_data_file_path_ = test_util::GetTestFilePath(
883 "drive/filelist.json");
885 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
886 scoped_ptr<FileList> result;
889 base::RunLoop run_loop;
890 drive::FilesListRequest* request = new drive::FilesListRequest(
891 request_sender_.get(), *url_generator_,
892 test_util::CreateQuitCallback(
893 &run_loop,
894 test_util::CreateCopyResultCallback(&error, &result)));
895 request->set_max_results(50);
896 request->set_q("\"abcde\" in parents");
897 request_sender_->StartRequestWithAuthRetry(request);
898 run_loop.Run();
901 EXPECT_EQ(HTTP_SUCCESS, error);
902 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
903 EXPECT_EQ("/drive/v2/files?maxResults=50&q=%22abcde%22+in+parents",
904 http_request_.relative_url);
905 EXPECT_TRUE(result);
908 TEST_F(DriveApiRequestsTest, FilesListNextPageRequest) {
909 // Set an expected data file containing valid result.
910 expected_data_file_path_ = test_util::GetTestFilePath(
911 "drive/filelist.json");
913 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
914 scoped_ptr<FileList> result;
917 base::RunLoop run_loop;
918 drive::FilesListNextPageRequest* request =
919 new drive::FilesListNextPageRequest(
920 request_sender_.get(),
921 test_util::CreateQuitCallback(
922 &run_loop,
923 test_util::CreateCopyResultCallback(&error, &result)));
924 request->set_next_link(test_server_.GetURL("/continue/get/file/list"));
925 request_sender_->StartRequestWithAuthRetry(request);
926 run_loop.Run();
929 EXPECT_EQ(HTTP_SUCCESS, error);
930 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
931 EXPECT_EQ("/continue/get/file/list", http_request_.relative_url);
932 EXPECT_TRUE(result);
935 TEST_F(DriveApiRequestsTest, FilesDeleteRequest) {
936 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
938 // Delete a resource with the given resource id.
940 base::RunLoop run_loop;
941 drive::FilesDeleteRequest* request = new drive::FilesDeleteRequest(
942 request_sender_.get(),
943 *url_generator_,
944 test_util::CreateQuitCallback(
945 &run_loop, test_util::CreateCopyResultCallback(&error)));
946 request->set_file_id("resource_id");
947 request->set_etag(kTestETag);
948 request_sender_->StartRequestWithAuthRetry(request);
949 run_loop.Run();
952 EXPECT_EQ(HTTP_NO_CONTENT, error);
953 EXPECT_EQ(net::test_server::METHOD_DELETE, http_request_.method);
954 EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
955 EXPECT_EQ("/drive/v2/files/resource_id", http_request_.relative_url);
956 EXPECT_FALSE(http_request_.has_content);
959 TEST_F(DriveApiRequestsTest, FilesTrashRequest) {
960 // Set data for the expected result. Directory entry should be returned
961 // if the trashing entry is a directory, so using it here should be fine.
962 expected_data_file_path_ =
963 test_util::GetTestFilePath("drive/directory_entry.json");
965 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
966 scoped_ptr<FileResource> file_resource;
968 // Trash a resource with the given resource id.
970 base::RunLoop run_loop;
971 drive::FilesTrashRequest* request = new drive::FilesTrashRequest(
972 request_sender_.get(),
973 *url_generator_,
974 test_util::CreateQuitCallback(
975 &run_loop,
976 test_util::CreateCopyResultCallback(&error, &file_resource)));
977 request->set_file_id("resource_id");
978 request_sender_->StartRequestWithAuthRetry(request);
979 run_loop.Run();
982 EXPECT_EQ(HTTP_SUCCESS, error);
983 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
984 EXPECT_EQ("/drive/v2/files/resource_id/trash", http_request_.relative_url);
985 EXPECT_TRUE(http_request_.has_content);
986 EXPECT_TRUE(http_request_.content.empty());
989 TEST_F(DriveApiRequestsTest, ChildrenInsertRequest) {
990 // Set an expected data file containing the children entry.
991 expected_content_type_ = "application/json";
992 expected_content_ = kTestChildrenResponse;
994 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
996 // Add a resource with "resource_id" to a directory with
997 // "parent_resource_id".
999 base::RunLoop run_loop;
1000 drive::ChildrenInsertRequest* request = new drive::ChildrenInsertRequest(
1001 request_sender_.get(),
1002 *url_generator_,
1003 test_util::CreateQuitCallback(
1004 &run_loop,
1005 test_util::CreateCopyResultCallback(&error)));
1006 request->set_folder_id("parent_resource_id");
1007 request->set_id("resource_id");
1008 request_sender_->StartRequestWithAuthRetry(request);
1009 run_loop.Run();
1012 EXPECT_EQ(HTTP_SUCCESS, error);
1013 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1014 EXPECT_EQ("/drive/v2/files/parent_resource_id/children",
1015 http_request_.relative_url);
1016 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1018 EXPECT_TRUE(http_request_.has_content);
1019 EXPECT_EQ("{\"id\":\"resource_id\"}", http_request_.content);
1022 TEST_F(DriveApiRequestsTest, ChildrenDeleteRequest) {
1023 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1025 // Remove a resource with "resource_id" from a directory with
1026 // "parent_resource_id".
1028 base::RunLoop run_loop;
1029 drive::ChildrenDeleteRequest* request = new drive::ChildrenDeleteRequest(
1030 request_sender_.get(),
1031 *url_generator_,
1032 test_util::CreateQuitCallback(
1033 &run_loop,
1034 test_util::CreateCopyResultCallback(&error)));
1035 request->set_child_id("resource_id");
1036 request->set_folder_id("parent_resource_id");
1037 request_sender_->StartRequestWithAuthRetry(request);
1038 run_loop.Run();
1041 EXPECT_EQ(HTTP_NO_CONTENT, error);
1042 EXPECT_EQ(net::test_server::METHOD_DELETE, http_request_.method);
1043 EXPECT_EQ("/drive/v2/files/parent_resource_id/children/resource_id",
1044 http_request_.relative_url);
1045 EXPECT_FALSE(http_request_.has_content);
1048 TEST_F(DriveApiRequestsTest, UploadNewFileRequest) {
1049 // Set an expected url for uploading.
1050 expected_upload_path_ = kTestUploadNewFilePath;
1052 const char kTestContentType[] = "text/plain";
1053 const std::string kTestContent(100, 'a');
1054 const base::FilePath kTestFilePath =
1055 temp_dir_.path().AppendASCII("upload_file.txt");
1056 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1058 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1059 GURL upload_url;
1061 // Initiate uploading a new file to the directory with
1062 // "parent_resource_id".
1064 base::RunLoop run_loop;
1065 drive::InitiateUploadNewFileRequest* request =
1066 new drive::InitiateUploadNewFileRequest(
1067 request_sender_.get(),
1068 *url_generator_,
1069 kTestContentType,
1070 kTestContent.size(),
1071 "parent_resource_id", // The resource id of the parent directory.
1072 "new file title", // The title of the file being uploaded.
1073 test_util::CreateQuitCallback(
1074 &run_loop,
1075 test_util::CreateCopyResultCallback(&error, &upload_url)));
1076 request->set_properties(testing_properties_);
1077 request_sender_->StartRequestWithAuthRetry(request);
1078 run_loop.Run();
1081 EXPECT_EQ(HTTP_SUCCESS, error);
1082 EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1083 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1084 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1085 http_request_.headers["X-Upload-Content-Length"]);
1087 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1088 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
1089 http_request_.relative_url);
1090 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1091 EXPECT_TRUE(http_request_.has_content);
1092 EXPECT_EQ(
1093 "{\"parents\":[{"
1094 "\"id\":\"parent_resource_id\","
1095 "\"kind\":\"drive#fileLink\""
1096 "}],"
1097 "\"properties\":["
1098 "{\"key\":\"key1\",\"value\":\"value1\",\"visibility\":\"PRIVATE\"},"
1099 "{\"key\":\"key2\",\"value\":\"value2\",\"visibility\":\"PUBLIC\"}],"
1100 "\"title\":\"new file title\"}",
1101 http_request_.content);
1103 // Upload the content to the upload URL.
1104 UploadRangeResponse response;
1105 scoped_ptr<FileResource> new_entry;
1108 base::RunLoop run_loop;
1109 drive::ResumeUploadRequest* resume_request =
1110 new drive::ResumeUploadRequest(
1111 request_sender_.get(),
1112 upload_url,
1113 0, // start_position
1114 kTestContent.size(), // end_position (exclusive)
1115 kTestContent.size(), // content_length,
1116 kTestContentType,
1117 kTestFilePath,
1118 test_util::CreateQuitCallback(
1119 &run_loop,
1120 test_util::CreateCopyResultCallback(&response, &new_entry)),
1121 ProgressCallback());
1122 request_sender_->StartRequestWithAuthRetry(resume_request);
1123 run_loop.Run();
1126 // METHOD_PUT should be used to upload data.
1127 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1128 // Request should go to the upload URL.
1129 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1130 // Content-Range header should be added.
1131 EXPECT_EQ("bytes 0-" +
1132 base::Int64ToString(kTestContent.size() - 1) + "/" +
1133 base::Int64ToString(kTestContent.size()),
1134 http_request_.headers["Content-Range"]);
1135 // The upload content should be set in the HTTP request.
1136 EXPECT_TRUE(http_request_.has_content);
1137 EXPECT_EQ(kTestContent, http_request_.content);
1139 // Check the response.
1140 EXPECT_EQ(HTTP_CREATED, response.code); // Because it's a new file
1141 // The start and end positions should be set to -1, if an upload is complete.
1142 EXPECT_EQ(-1, response.start_position_received);
1143 EXPECT_EQ(-1, response.end_position_received);
1146 TEST_F(DriveApiRequestsTest, UploadNewEmptyFileRequest) {
1147 // Set an expected url for uploading.
1148 expected_upload_path_ = kTestUploadNewFilePath;
1150 const char kTestContentType[] = "text/plain";
1151 const char kTestContent[] = "";
1152 const base::FilePath kTestFilePath =
1153 temp_dir_.path().AppendASCII("empty_file.txt");
1154 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1156 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1157 GURL upload_url;
1159 // Initiate uploading a new file to the directory with "parent_resource_id".
1161 base::RunLoop run_loop;
1162 drive::InitiateUploadNewFileRequest* request =
1163 new drive::InitiateUploadNewFileRequest(
1164 request_sender_.get(),
1165 *url_generator_,
1166 kTestContentType,
1168 "parent_resource_id", // The resource id of the parent directory.
1169 "new file title", // The title of the file being uploaded.
1170 test_util::CreateQuitCallback(
1171 &run_loop,
1172 test_util::CreateCopyResultCallback(&error, &upload_url)));
1173 request_sender_->StartRequestWithAuthRetry(request);
1174 run_loop.Run();
1177 EXPECT_EQ(HTTP_SUCCESS, error);
1178 EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1179 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1180 EXPECT_EQ("0", http_request_.headers["X-Upload-Content-Length"]);
1182 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1183 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
1184 http_request_.relative_url);
1185 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1186 EXPECT_TRUE(http_request_.has_content);
1187 EXPECT_EQ("{\"parents\":[{"
1188 "\"id\":\"parent_resource_id\","
1189 "\"kind\":\"drive#fileLink\""
1190 "}],"
1191 "\"title\":\"new file title\"}",
1192 http_request_.content);
1194 // Upload the content to the upload URL.
1195 UploadRangeResponse response;
1196 scoped_ptr<FileResource> new_entry;
1199 base::RunLoop run_loop;
1200 drive::ResumeUploadRequest* resume_request =
1201 new drive::ResumeUploadRequest(
1202 request_sender_.get(),
1203 upload_url,
1204 0, // start_position
1205 0, // end_position (exclusive)
1206 0, // content_length,
1207 kTestContentType,
1208 kTestFilePath,
1209 test_util::CreateQuitCallback(
1210 &run_loop,
1211 test_util::CreateCopyResultCallback(&response, &new_entry)),
1212 ProgressCallback());
1213 request_sender_->StartRequestWithAuthRetry(resume_request);
1214 run_loop.Run();
1217 // METHOD_PUT should be used to upload data.
1218 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1219 // Request should go to the upload URL.
1220 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1221 // Content-Range header should NOT be added.
1222 EXPECT_EQ(0U, http_request_.headers.count("Content-Range"));
1223 // The upload content should be set in the HTTP request.
1224 EXPECT_TRUE(http_request_.has_content);
1225 EXPECT_EQ(kTestContent, http_request_.content);
1227 // Check the response.
1228 EXPECT_EQ(HTTP_CREATED, response.code); // Because it's a new file
1229 // The start and end positions should be set to -1, if an upload is complete.
1230 EXPECT_EQ(-1, response.start_position_received);
1231 EXPECT_EQ(-1, response.end_position_received);
1234 TEST_F(DriveApiRequestsTest, UploadNewLargeFileRequest) {
1235 // Set an expected url for uploading.
1236 expected_upload_path_ = kTestUploadNewFilePath;
1238 const char kTestContentType[] = "text/plain";
1239 const size_t kNumChunkBytes = 10; // Num bytes in a chunk.
1240 const std::string kTestContent(100, 'a');
1241 const base::FilePath kTestFilePath =
1242 temp_dir_.path().AppendASCII("upload_file.txt");
1243 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1245 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1246 GURL upload_url;
1248 // Initiate uploading a new file to the directory with "parent_resource_id".
1250 base::RunLoop run_loop;
1251 drive::InitiateUploadNewFileRequest* request =
1252 new drive::InitiateUploadNewFileRequest(
1253 request_sender_.get(),
1254 *url_generator_,
1255 kTestContentType,
1256 kTestContent.size(),
1257 "parent_resource_id", // The resource id of the parent directory.
1258 "new file title", // The title of the file being uploaded.
1259 test_util::CreateQuitCallback(
1260 &run_loop,
1261 test_util::CreateCopyResultCallback(&error, &upload_url)));
1262 request_sender_->StartRequestWithAuthRetry(request);
1263 run_loop.Run();
1266 EXPECT_EQ(HTTP_SUCCESS, error);
1267 EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1268 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1269 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1270 http_request_.headers["X-Upload-Content-Length"]);
1272 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1273 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
1274 http_request_.relative_url);
1275 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1276 EXPECT_TRUE(http_request_.has_content);
1277 EXPECT_EQ("{\"parents\":[{"
1278 "\"id\":\"parent_resource_id\","
1279 "\"kind\":\"drive#fileLink\""
1280 "}],"
1281 "\"title\":\"new file title\"}",
1282 http_request_.content);
1284 // Before sending any data, check the current status.
1285 // This is an edge case test for GetUploadStatusRequest.
1287 UploadRangeResponse response;
1288 scoped_ptr<FileResource> new_entry;
1290 // Check the response by GetUploadStatusRequest.
1292 base::RunLoop run_loop;
1293 drive::GetUploadStatusRequest* get_upload_status_request =
1294 new drive::GetUploadStatusRequest(
1295 request_sender_.get(),
1296 upload_url,
1297 kTestContent.size(),
1298 test_util::CreateQuitCallback(
1299 &run_loop,
1300 test_util::CreateCopyResultCallback(&response, &new_entry)));
1301 request_sender_->StartRequestWithAuthRetry(get_upload_status_request);
1302 run_loop.Run();
1305 // METHOD_PUT should be used to upload data.
1306 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1307 // Request should go to the upload URL.
1308 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1309 // Content-Range header should be added.
1310 EXPECT_EQ("bytes */" + base::Int64ToString(kTestContent.size()),
1311 http_request_.headers["Content-Range"]);
1312 EXPECT_TRUE(http_request_.has_content);
1313 EXPECT_TRUE(http_request_.content.empty());
1315 // Check the response.
1316 EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code);
1317 EXPECT_EQ(0, response.start_position_received);
1318 EXPECT_EQ(0, response.end_position_received);
1321 // Upload the content to the upload URL.
1322 for (size_t start_position = 0; start_position < kTestContent.size();
1323 start_position += kNumChunkBytes) {
1324 const std::string payload = kTestContent.substr(
1325 start_position,
1326 std::min(kNumChunkBytes, kTestContent.size() - start_position));
1327 const size_t end_position = start_position + payload.size();
1329 UploadRangeResponse response;
1330 scoped_ptr<FileResource> new_entry;
1333 base::RunLoop run_loop;
1334 drive::ResumeUploadRequest* resume_request =
1335 new drive::ResumeUploadRequest(
1336 request_sender_.get(),
1337 upload_url,
1338 start_position,
1339 end_position,
1340 kTestContent.size(), // content_length,
1341 kTestContentType,
1342 kTestFilePath,
1343 test_util::CreateQuitCallback(
1344 &run_loop,
1345 test_util::CreateCopyResultCallback(&response, &new_entry)),
1346 ProgressCallback());
1347 request_sender_->StartRequestWithAuthRetry(resume_request);
1348 run_loop.Run();
1351 // METHOD_PUT should be used to upload data.
1352 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1353 // Request should go to the upload URL.
1354 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1355 // Content-Range header should be added.
1356 EXPECT_EQ("bytes " +
1357 base::Int64ToString(start_position) + "-" +
1358 base::Int64ToString(end_position - 1) + "/" +
1359 base::Int64ToString(kTestContent.size()),
1360 http_request_.headers["Content-Range"]);
1361 // The upload content should be set in the HTTP request.
1362 EXPECT_TRUE(http_request_.has_content);
1363 EXPECT_EQ(payload, http_request_.content);
1365 if (end_position == kTestContent.size()) {
1366 // Check the response.
1367 EXPECT_EQ(HTTP_CREATED, response.code); // Because it's a new file
1368 // The start and end positions should be set to -1, if an upload is
1369 // complete.
1370 EXPECT_EQ(-1, response.start_position_received);
1371 EXPECT_EQ(-1, response.end_position_received);
1372 break;
1375 // Check the response.
1376 EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code);
1377 EXPECT_EQ(0, response.start_position_received);
1378 EXPECT_EQ(static_cast<int64>(end_position), response.end_position_received);
1380 // Check the response by GetUploadStatusRequest.
1382 base::RunLoop run_loop;
1383 drive::GetUploadStatusRequest* get_upload_status_request =
1384 new drive::GetUploadStatusRequest(
1385 request_sender_.get(),
1386 upload_url,
1387 kTestContent.size(),
1388 test_util::CreateQuitCallback(
1389 &run_loop,
1390 test_util::CreateCopyResultCallback(&response, &new_entry)));
1391 request_sender_->StartRequestWithAuthRetry(get_upload_status_request);
1392 run_loop.Run();
1395 // METHOD_PUT should be used to upload data.
1396 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1397 // Request should go to the upload URL.
1398 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1399 // Content-Range header should be added.
1400 EXPECT_EQ("bytes */" + base::Int64ToString(kTestContent.size()),
1401 http_request_.headers["Content-Range"]);
1402 EXPECT_TRUE(http_request_.has_content);
1403 EXPECT_TRUE(http_request_.content.empty());
1405 // Check the response.
1406 EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code);
1407 EXPECT_EQ(0, response.start_position_received);
1408 EXPECT_EQ(static_cast<int64>(end_position),
1409 response.end_position_received);
1413 TEST_F(DriveApiRequestsTest, UploadNewFileWithMetadataRequest) {
1414 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
1415 const base::Time::Exploded kLastViewedByMeDate =
1416 {2013, 7, 0, 19, 15, 59, 13, 123};
1418 // Set an expected url for uploading.
1419 expected_upload_path_ = kTestUploadNewFilePath;
1421 const char kTestContentType[] = "text/plain";
1422 const std::string kTestContent(100, 'a');
1424 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1425 GURL upload_url;
1427 // Initiate uploading a new file to the directory with "parent_resource_id".
1429 base::RunLoop run_loop;
1430 drive::InitiateUploadNewFileRequest* request =
1431 new drive::InitiateUploadNewFileRequest(
1432 request_sender_.get(),
1433 *url_generator_,
1434 kTestContentType,
1435 kTestContent.size(),
1436 "parent_resource_id", // The resource id of the parent directory.
1437 "new file title", // The title of the file being uploaded.
1438 test_util::CreateQuitCallback(
1439 &run_loop,
1440 test_util::CreateCopyResultCallback(&error, &upload_url)));
1441 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
1442 request->set_last_viewed_by_me_date(
1443 base::Time::FromUTCExploded(kLastViewedByMeDate));
1444 request_sender_->StartRequestWithAuthRetry(request);
1445 run_loop.Run();
1448 EXPECT_EQ(HTTP_SUCCESS, error);
1449 EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1450 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1451 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1452 http_request_.headers["X-Upload-Content-Length"]);
1454 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1455 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable&setModifiedDate=true",
1456 http_request_.relative_url);
1457 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1458 EXPECT_TRUE(http_request_.has_content);
1459 EXPECT_EQ("{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
1460 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
1461 "\"parents\":[{\"id\":\"parent_resource_id\","
1462 "\"kind\":\"drive#fileLink\"}],"
1463 "\"title\":\"new file title\"}",
1464 http_request_.content);
1467 TEST_F(DriveApiRequestsTest, UploadExistingFileRequest) {
1468 // Set an expected url for uploading.
1469 expected_upload_path_ = kTestUploadExistingFilePath;
1471 const char kTestContentType[] = "text/plain";
1472 const std::string kTestContent(100, 'a');
1473 const base::FilePath kTestFilePath =
1474 temp_dir_.path().AppendASCII("upload_file.txt");
1475 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1477 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1478 GURL upload_url;
1480 // Initiate uploading a new file to the directory with "parent_resource_id".
1482 base::RunLoop run_loop;
1483 drive::InitiateUploadExistingFileRequest* request =
1484 new drive::InitiateUploadExistingFileRequest(
1485 request_sender_.get(),
1486 *url_generator_,
1487 kTestContentType,
1488 kTestContent.size(),
1489 "resource_id", // The resource id of the file to be overwritten.
1490 std::string(), // No etag.
1491 test_util::CreateQuitCallback(
1492 &run_loop,
1493 test_util::CreateCopyResultCallback(&error, &upload_url)));
1494 request->set_properties(testing_properties_);
1495 request_sender_->StartRequestWithAuthRetry(request);
1496 run_loop.Run();
1499 EXPECT_EQ(HTTP_SUCCESS, error);
1500 EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1501 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1502 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1503 http_request_.headers["X-Upload-Content-Length"]);
1504 EXPECT_EQ("*", http_request_.headers["If-Match"]);
1506 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1507 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1508 http_request_.relative_url);
1509 EXPECT_TRUE(http_request_.has_content);
1510 EXPECT_EQ(
1511 "{\"properties\":["
1512 "{\"key\":\"key1\",\"value\":\"value1\",\"visibility\":\"PRIVATE\"},"
1513 "{\"key\":\"key2\",\"value\":\"value2\",\"visibility\":\"PUBLIC\"}]}",
1514 http_request_.content);
1516 // Upload the content to the upload URL.
1517 UploadRangeResponse response;
1518 scoped_ptr<FileResource> new_entry;
1521 base::RunLoop run_loop;
1522 drive::ResumeUploadRequest* resume_request =
1523 new drive::ResumeUploadRequest(
1524 request_sender_.get(),
1525 upload_url,
1526 0, // start_position
1527 kTestContent.size(), // end_position (exclusive)
1528 kTestContent.size(), // content_length,
1529 kTestContentType,
1530 kTestFilePath,
1531 test_util::CreateQuitCallback(
1532 &run_loop,
1533 test_util::CreateCopyResultCallback(&response, &new_entry)),
1534 ProgressCallback());
1535 request_sender_->StartRequestWithAuthRetry(resume_request);
1536 run_loop.Run();
1539 // METHOD_PUT should be used to upload data.
1540 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1541 // Request should go to the upload URL.
1542 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1543 // Content-Range header should be added.
1544 EXPECT_EQ("bytes 0-" +
1545 base::Int64ToString(kTestContent.size() - 1) + "/" +
1546 base::Int64ToString(kTestContent.size()),
1547 http_request_.headers["Content-Range"]);
1548 // The upload content should be set in the HTTP request.
1549 EXPECT_TRUE(http_request_.has_content);
1550 EXPECT_EQ(kTestContent, http_request_.content);
1552 // Check the response.
1553 EXPECT_EQ(HTTP_SUCCESS, response.code); // Because it's an existing file
1554 // The start and end positions should be set to -1, if an upload is complete.
1555 EXPECT_EQ(-1, response.start_position_received);
1556 EXPECT_EQ(-1, response.end_position_received);
1559 TEST_F(DriveApiRequestsTest, UploadExistingFileRequestWithETag) {
1560 // Set an expected url for uploading.
1561 expected_upload_path_ = kTestUploadExistingFilePath;
1563 const char kTestContentType[] = "text/plain";
1564 const std::string kTestContent(100, 'a');
1565 const base::FilePath kTestFilePath =
1566 temp_dir_.path().AppendASCII("upload_file.txt");
1567 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1569 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1570 GURL upload_url;
1572 // Initiate uploading a new file to the directory with "parent_resource_id".
1574 base::RunLoop run_loop;
1575 drive::InitiateUploadExistingFileRequest* request =
1576 new drive::InitiateUploadExistingFileRequest(
1577 request_sender_.get(),
1578 *url_generator_,
1579 kTestContentType,
1580 kTestContent.size(),
1581 "resource_id", // The resource id of the file to be overwritten.
1582 kTestETag,
1583 test_util::CreateQuitCallback(
1584 &run_loop,
1585 test_util::CreateCopyResultCallback(&error, &upload_url)));
1586 request_sender_->StartRequestWithAuthRetry(request);
1587 run_loop.Run();
1590 EXPECT_EQ(HTTP_SUCCESS, error);
1591 EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1592 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1593 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1594 http_request_.headers["X-Upload-Content-Length"]);
1595 EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
1597 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1598 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1599 http_request_.relative_url);
1600 EXPECT_TRUE(http_request_.has_content);
1601 EXPECT_TRUE(http_request_.content.empty());
1603 // Upload the content to the upload URL.
1604 UploadRangeResponse response;
1605 scoped_ptr<FileResource> new_entry;
1608 base::RunLoop run_loop;
1609 drive::ResumeUploadRequest* resume_request =
1610 new drive::ResumeUploadRequest(
1611 request_sender_.get(),
1612 upload_url,
1613 0, // start_position
1614 kTestContent.size(), // end_position (exclusive)
1615 kTestContent.size(), // content_length,
1616 kTestContentType,
1617 kTestFilePath,
1618 test_util::CreateQuitCallback(
1619 &run_loop,
1620 test_util::CreateCopyResultCallback(&response, &new_entry)),
1621 ProgressCallback());
1622 request_sender_->StartRequestWithAuthRetry(resume_request);
1623 run_loop.Run();
1626 // METHOD_PUT should be used to upload data.
1627 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1628 // Request should go to the upload URL.
1629 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1630 // Content-Range header should be added.
1631 EXPECT_EQ("bytes 0-" +
1632 base::Int64ToString(kTestContent.size() - 1) + "/" +
1633 base::Int64ToString(kTestContent.size()),
1634 http_request_.headers["Content-Range"]);
1635 // The upload content should be set in the HTTP request.
1636 EXPECT_TRUE(http_request_.has_content);
1637 EXPECT_EQ(kTestContent, http_request_.content);
1639 // Check the response.
1640 EXPECT_EQ(HTTP_SUCCESS, response.code); // Because it's an existing file
1641 // The start and end positions should be set to -1, if an upload is complete.
1642 EXPECT_EQ(-1, response.start_position_received);
1643 EXPECT_EQ(-1, response.end_position_received);
1646 TEST_F(DriveApiRequestsTest, UploadExistingFileRequestWithETagConflicting) {
1647 // Set an expected url for uploading.
1648 expected_upload_path_ = kTestUploadExistingFilePath;
1650 // If it turned out that the etag is conflicting, PRECONDITION_FAILED should
1651 // be returned.
1652 expected_precondition_failed_file_path_ =
1653 test_util::GetTestFilePath("drive/error.json");
1655 const char kTestContentType[] = "text/plain";
1656 const std::string kTestContent(100, 'a');
1658 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1659 GURL upload_url;
1661 // Initiate uploading a new file to the directory with "parent_resource_id".
1663 base::RunLoop run_loop;
1664 drive::InitiateUploadExistingFileRequest* request =
1665 new drive::InitiateUploadExistingFileRequest(
1666 request_sender_.get(),
1667 *url_generator_,
1668 kTestContentType,
1669 kTestContent.size(),
1670 "resource_id", // The resource id of the file to be overwritten.
1671 "Conflicting-etag",
1672 test_util::CreateQuitCallback(
1673 &run_loop,
1674 test_util::CreateCopyResultCallback(&error, &upload_url)));
1675 request_sender_->StartRequestWithAuthRetry(request);
1676 run_loop.Run();
1679 EXPECT_EQ(HTTP_PRECONDITION, error);
1680 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1681 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1682 http_request_.headers["X-Upload-Content-Length"]);
1683 EXPECT_EQ("Conflicting-etag", http_request_.headers["If-Match"]);
1685 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1686 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1687 http_request_.relative_url);
1688 EXPECT_TRUE(http_request_.has_content);
1689 EXPECT_TRUE(http_request_.content.empty());
1692 TEST_F(DriveApiRequestsTest,
1693 UploadExistingFileRequestWithETagConflictOnResumeUpload) {
1694 // Set an expected url for uploading.
1695 expected_upload_path_ = kTestUploadExistingFilePath;
1697 const char kTestContentType[] = "text/plain";
1698 const std::string kTestContent(100, 'a');
1699 const base::FilePath kTestFilePath =
1700 temp_dir_.path().AppendASCII("upload_file.txt");
1701 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1703 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1704 GURL upload_url;
1706 // Initiate uploading a new file to the directory with "parent_resource_id".
1708 base::RunLoop run_loop;
1709 drive::InitiateUploadExistingFileRequest* request =
1710 new drive::InitiateUploadExistingFileRequest(
1711 request_sender_.get(),
1712 *url_generator_,
1713 kTestContentType,
1714 kTestContent.size(),
1715 "resource_id", // The resource id of the file to be overwritten.
1716 kTestETag,
1717 test_util::CreateQuitCallback(
1718 &run_loop,
1719 test_util::CreateCopyResultCallback(&error, &upload_url)));
1720 request_sender_->StartRequestWithAuthRetry(request);
1721 run_loop.Run();
1724 EXPECT_EQ(HTTP_SUCCESS, error);
1725 EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1726 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1727 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1728 http_request_.headers["X-Upload-Content-Length"]);
1729 EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
1731 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1732 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1733 http_request_.relative_url);
1734 EXPECT_TRUE(http_request_.has_content);
1735 EXPECT_TRUE(http_request_.content.empty());
1737 // Set PRECONDITION_FAILED to the server. This is the emulation of the
1738 // confliction during uploading.
1739 expected_precondition_failed_file_path_ =
1740 test_util::GetTestFilePath("drive/error.json");
1742 // Upload the content to the upload URL.
1743 UploadRangeResponse response;
1744 scoped_ptr<FileResource> new_entry;
1747 base::RunLoop run_loop;
1748 drive::ResumeUploadRequest* resume_request =
1749 new drive::ResumeUploadRequest(
1750 request_sender_.get(),
1751 upload_url,
1752 0, // start_position
1753 kTestContent.size(), // end_position (exclusive)
1754 kTestContent.size(), // content_length,
1755 kTestContentType,
1756 kTestFilePath,
1757 test_util::CreateQuitCallback(
1758 &run_loop,
1759 test_util::CreateCopyResultCallback(&response, &new_entry)),
1760 ProgressCallback());
1761 request_sender_->StartRequestWithAuthRetry(resume_request);
1762 run_loop.Run();
1765 // METHOD_PUT should be used to upload data.
1766 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1767 // Request should go to the upload URL.
1768 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1769 // Content-Range header should be added.
1770 EXPECT_EQ("bytes 0-" +
1771 base::Int64ToString(kTestContent.size() - 1) + "/" +
1772 base::Int64ToString(kTestContent.size()),
1773 http_request_.headers["Content-Range"]);
1774 // The upload content should be set in the HTTP request.
1775 EXPECT_TRUE(http_request_.has_content);
1776 EXPECT_EQ(kTestContent, http_request_.content);
1778 // Check the response.
1779 EXPECT_EQ(HTTP_PRECONDITION, response.code);
1780 // The start and end positions should be set to -1 for error.
1781 EXPECT_EQ(-1, response.start_position_received);
1782 EXPECT_EQ(-1, response.end_position_received);
1784 // New entry should be NULL.
1785 EXPECT_FALSE(new_entry.get());
1788 TEST_F(DriveApiRequestsTest, UploadExistingFileWithMetadataRequest) {
1789 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
1790 const base::Time::Exploded kLastViewedByMeDate =
1791 {2013, 7, 0, 19, 15, 59, 13, 123};
1793 // Set an expected url for uploading.
1794 expected_upload_path_ = kTestUploadExistingFilePath;
1796 const char kTestContentType[] = "text/plain";
1797 const std::string kTestContent(100, 'a');
1799 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1800 GURL upload_url;
1802 // Initiate uploading a new file to the directory with "parent_resource_id".
1804 base::RunLoop run_loop;
1805 drive::InitiateUploadExistingFileRequest* request =
1806 new drive::InitiateUploadExistingFileRequest(
1807 request_sender_.get(),
1808 *url_generator_,
1809 kTestContentType,
1810 kTestContent.size(),
1811 "resource_id", // The resource id of the file to be overwritten.
1812 kTestETag,
1813 test_util::CreateQuitCallback(
1814 &run_loop,
1815 test_util::CreateCopyResultCallback(&error, &upload_url)));
1816 request->set_parent_resource_id("new_parent_resource_id");
1817 request->set_title("new file title");
1818 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
1819 request->set_last_viewed_by_me_date(
1820 base::Time::FromUTCExploded(kLastViewedByMeDate));
1822 request_sender_->StartRequestWithAuthRetry(request);
1823 run_loop.Run();
1826 EXPECT_EQ(HTTP_SUCCESS, error);
1827 EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1828 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1829 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1830 http_request_.headers["X-Upload-Content-Length"]);
1831 EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
1833 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1834 EXPECT_EQ("/upload/drive/v2/files/resource_id?"
1835 "uploadType=resumable&setModifiedDate=true",
1836 http_request_.relative_url);
1837 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1838 EXPECT_TRUE(http_request_.has_content);
1839 EXPECT_EQ("{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
1840 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
1841 "\"parents\":[{\"id\":\"new_parent_resource_id\","
1842 "\"kind\":\"drive#fileLink\"}],"
1843 "\"title\":\"new file title\"}",
1844 http_request_.content);
1847 TEST_F(DriveApiRequestsTest, DownloadFileRequest) {
1848 const base::FilePath kDownloadedFilePath =
1849 temp_dir_.path().AppendASCII("cache_file");
1850 const std::string kTestId("dummyId");
1852 DriveApiErrorCode result_code = DRIVE_OTHER_ERROR;
1853 base::FilePath temp_file;
1855 base::RunLoop run_loop;
1856 drive::DownloadFileRequest* request = new drive::DownloadFileRequest(
1857 request_sender_.get(),
1858 *url_generator_,
1859 kTestId,
1860 kDownloadedFilePath,
1861 test_util::CreateQuitCallback(
1862 &run_loop,
1863 test_util::CreateCopyResultCallback(&result_code, &temp_file)),
1864 GetContentCallback(),
1865 ProgressCallback());
1866 request_sender_->StartRequestWithAuthRetry(request);
1867 run_loop.Run();
1870 std::string contents;
1871 base::ReadFileToString(temp_file, &contents);
1872 base::DeleteFile(temp_file, false);
1874 EXPECT_EQ(HTTP_SUCCESS, result_code);
1875 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
1876 EXPECT_EQ(kTestDownloadPathPrefix + kTestId, http_request_.relative_url);
1877 EXPECT_EQ(kDownloadedFilePath, temp_file);
1879 const std::string expected_contents = kTestId + kTestId + kTestId;
1880 EXPECT_EQ(expected_contents, contents);
1883 TEST_F(DriveApiRequestsTest, DownloadFileRequest_GetContentCallback) {
1884 const base::FilePath kDownloadedFilePath =
1885 temp_dir_.path().AppendASCII("cache_file");
1886 const std::string kTestId("dummyId");
1888 DriveApiErrorCode result_code = DRIVE_OTHER_ERROR;
1889 base::FilePath temp_file;
1890 std::string contents;
1892 base::RunLoop run_loop;
1893 drive::DownloadFileRequest* request = new drive::DownloadFileRequest(
1894 request_sender_.get(),
1895 *url_generator_,
1896 kTestId,
1897 kDownloadedFilePath,
1898 test_util::CreateQuitCallback(
1899 &run_loop,
1900 test_util::CreateCopyResultCallback(&result_code, &temp_file)),
1901 base::Bind(&AppendContent, &contents),
1902 ProgressCallback());
1903 request_sender_->StartRequestWithAuthRetry(request);
1904 run_loop.Run();
1907 base::DeleteFile(temp_file, false);
1909 EXPECT_EQ(HTTP_SUCCESS, result_code);
1910 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
1911 EXPECT_EQ(kTestDownloadPathPrefix + kTestId, http_request_.relative_url);
1912 EXPECT_EQ(kDownloadedFilePath, temp_file);
1914 const std::string expected_contents = kTestId + kTestId + kTestId;
1915 EXPECT_EQ(expected_contents, contents);
1918 TEST_F(DriveApiRequestsTest, PermissionsInsertRequest) {
1919 expected_content_type_ = "application/json";
1920 expected_content_ = kTestPermissionResponse;
1922 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1924 // Add comment permission to the user "user@example.com".
1926 base::RunLoop run_loop;
1927 drive::PermissionsInsertRequest* request =
1928 new drive::PermissionsInsertRequest(
1929 request_sender_.get(),
1930 *url_generator_,
1931 test_util::CreateQuitCallback(
1932 &run_loop,
1933 test_util::CreateCopyResultCallback(&error)));
1934 request->set_id("resource_id");
1935 request->set_role(drive::PERMISSION_ROLE_COMMENTER);
1936 request->set_type(drive::PERMISSION_TYPE_USER);
1937 request->set_value("user@example.com");
1938 request_sender_->StartRequestWithAuthRetry(request);
1939 run_loop.Run();
1942 EXPECT_EQ(HTTP_SUCCESS, error);
1943 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1944 EXPECT_EQ("/drive/v2/files/resource_id/permissions",
1945 http_request_.relative_url);
1946 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1948 scoped_ptr<base::Value> expected = base::JSONReader::Read(
1949 "{\"additionalRoles\":[\"commenter\"], \"role\":\"reader\", "
1950 "\"type\":\"user\",\"value\":\"user@example.com\"}");
1951 ASSERT_TRUE(expected);
1953 scoped_ptr<base::Value> result =
1954 base::JSONReader::Read(http_request_.content);
1955 EXPECT_TRUE(http_request_.has_content);
1956 EXPECT_TRUE(base::Value::Equals(expected.get(), result.get()));
1958 // Add "can edit" permission to users in "example.com".
1959 error = DRIVE_OTHER_ERROR;
1961 base::RunLoop run_loop;
1962 drive::PermissionsInsertRequest* request =
1963 new drive::PermissionsInsertRequest(
1964 request_sender_.get(),
1965 *url_generator_,
1966 test_util::CreateQuitCallback(
1967 &run_loop,
1968 test_util::CreateCopyResultCallback(&error)));
1969 request->set_id("resource_id2");
1970 request->set_role(drive::PERMISSION_ROLE_WRITER);
1971 request->set_type(drive::PERMISSION_TYPE_DOMAIN);
1972 request->set_value("example.com");
1973 request_sender_->StartRequestWithAuthRetry(request);
1974 run_loop.Run();
1977 EXPECT_EQ(HTTP_SUCCESS, error);
1978 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1979 EXPECT_EQ("/drive/v2/files/resource_id2/permissions",
1980 http_request_.relative_url);
1981 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1983 expected = base::JSONReader::Read(
1984 "{\"role\":\"writer\", \"type\":\"domain\",\"value\":\"example.com\"}");
1985 ASSERT_TRUE(expected);
1987 result = base::JSONReader::Read(http_request_.content);
1988 EXPECT_TRUE(http_request_.has_content);
1989 EXPECT_TRUE(base::Value::Equals(expected.get(), result.get()));
1992 TEST_F(DriveApiRequestsTest, BatchUploadRequest) {
1993 // Preapre constants.
1994 const char kTestContentType[] = "text/plain";
1995 const std::string kTestContent(10, 'a');
1996 const base::FilePath kTestFilePath =
1997 temp_dir_.path().AppendASCII("upload_file.txt");
1998 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
2000 // Create batch request.
2001 drive::BatchUploadRequest* const request =
2002 new drive::BatchUploadRequest(request_sender_.get(), *url_generator_);
2003 request->SetBoundaryForTesting("OUTERBOUNDARY");
2004 request_sender_->StartRequestWithAuthRetry(request);
2006 // Create child request.
2007 DriveApiErrorCode errors[] = {DRIVE_OTHER_ERROR, DRIVE_OTHER_ERROR};
2008 scoped_ptr<FileResource> file_resources[2];
2009 base::RunLoop run_loop[2];
2010 for (int i = 0; i < 2; ++i) {
2011 const FileResourceCallback callback = test_util::CreateQuitCallback(
2012 &run_loop[i],
2013 test_util::CreateCopyResultCallback(&errors[i], &file_resources[i]));
2014 drive::MultipartUploadNewFileDelegate* const child_request =
2015 new drive::MultipartUploadNewFileDelegate(
2016 request_sender_->blocking_task_runner(),
2017 base::StringPrintf("new file title %d", i),
2018 "parent_resource_id", kTestContentType, kTestContent.size(),
2019 base::Time(), base::Time(), kTestFilePath, drive::Properties(),
2020 *url_generator_, callback, ProgressCallback());
2021 child_request->SetBoundaryForTesting("INNERBOUNDARY");
2022 request->AddRequest(child_request);
2024 request->Commit();
2025 run_loop[0].Run();
2026 run_loop[1].Run();
2028 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
2029 EXPECT_EQ("batch", http_request_.headers["X-Goog-Upload-Protocol"]);
2030 EXPECT_EQ("multipart/mixed; boundary=OUTERBOUNDARY",
2031 http_request_.headers["Content-Type"]);
2032 EXPECT_EQ(
2033 "--OUTERBOUNDARY\n"
2034 "Content-Type: application/http\n"
2035 "\n"
2036 "POST /upload/drive/v2/files HTTP/1.1\n"
2037 "Host: 127.0.0.1\n"
2038 "X-Goog-Upload-Protocol: multipart\n"
2039 "Content-Type: multipart/related; boundary=INNERBOUNDARY\n"
2040 "\n"
2041 "--INNERBOUNDARY\n"
2042 "Content-Type: application/json\n"
2043 "\n"
2044 "{\"parents\":[{\"id\":\"parent_resource_id\","
2045 "\"kind\":\"drive#fileLink\"}],\"title\":\"new file title 0\"}\n"
2046 "--INNERBOUNDARY\n"
2047 "Content-Type: text/plain\n"
2048 "\n"
2049 "aaaaaaaaaa\n"
2050 "--INNERBOUNDARY--\n"
2051 "--OUTERBOUNDARY\n"
2052 "Content-Type: application/http\n"
2053 "\n"
2054 "POST /upload/drive/v2/files HTTP/1.1\n"
2055 "Host: 127.0.0.1\n"
2056 "X-Goog-Upload-Protocol: multipart\n"
2057 "Content-Type: multipart/related; boundary=INNERBOUNDARY\n"
2058 "\n"
2059 "--INNERBOUNDARY\n"
2060 "Content-Type: application/json\n"
2061 "\n"
2062 "{\"parents\":[{\"id\":\"parent_resource_id\","
2063 "\"kind\":\"drive#fileLink\"}],\"title\":\"new file title 1\"}\n"
2064 "--INNERBOUNDARY\n"
2065 "Content-Type: text/plain\n"
2066 "\n"
2067 "aaaaaaaaaa\n"
2068 "--INNERBOUNDARY--\n"
2069 "--OUTERBOUNDARY--",
2070 http_request_.content);
2071 EXPECT_EQ(HTTP_SUCCESS, errors[0]);
2072 ASSERT_TRUE(file_resources[0]);
2073 EXPECT_EQ("file_id_1", file_resources[0]->file_id());
2074 ASSERT_FALSE(file_resources[1]);
2075 EXPECT_EQ(HTTP_SERVICE_UNAVAILABLE, errors[1]);
2078 TEST_F(DriveApiRequestsTest, EmptyBatchUploadRequest) {
2079 drive::BatchUploadRequest* const request =
2080 new drive::BatchUploadRequest(request_sender_.get(), *url_generator_);
2081 base::WeakPtr<drive::BatchUploadRequest> weak_ptr =
2082 request->GetWeakPtrAsBatchUploadRequest();
2083 request->Commit();
2084 ASSERT_FALSE(weak_ptr.get());
2087 TEST_F(DriveApiRequestsTest, BatchUploadRequestWithBodyIncludingZero) {
2088 // Create batch request.
2089 drive::BatchUploadRequest* const request =
2090 new drive::BatchUploadRequest(request_sender_.get(), *url_generator_);
2091 request->SetBoundaryForTesting("OUTERBOUNDARY");
2092 request_sender_->StartRequestWithAuthRetry(request);
2094 // Create child request.
2096 base::RunLoop loop;
2097 TestBatchableDelegate* const child_request = new TestBatchableDelegate(
2098 GURL("http://example.com/test"), "application/binary",
2099 std::string("Apple\0Orange\0", 13), loop.QuitClosure());
2100 request->AddRequest(child_request);
2101 request->Commit();
2102 loop.Run();
2105 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
2106 EXPECT_EQ("batch", http_request_.headers["X-Goog-Upload-Protocol"]);
2107 EXPECT_EQ("multipart/mixed; boundary=OUTERBOUNDARY",
2108 http_request_.headers["Content-Type"]);
2109 EXPECT_EQ(
2110 "--OUTERBOUNDARY\n"
2111 "Content-Type: application/http\n"
2112 "\n"
2113 "PUT /test HTTP/1.1\n"
2114 "Host: 127.0.0.1\n"
2115 "X-Goog-Upload-Protocol: multipart\n"
2116 "Content-Type: application/binary\n"
2117 "\n" +
2118 std::string("Apple\0Orange\0", 13) +
2119 "\n"
2120 "--OUTERBOUNDARY--",
2121 http_request_.content);
2124 TEST_F(DriveApiRequestsTest, BatchUploadRequestProgress) {
2125 // Create batch request.
2126 drive::BatchUploadRequest* const request =
2127 new drive::BatchUploadRequest(request_sender_.get(), *url_generator_);
2128 TestBatchableDelegate* requests[] = {
2129 new TestBatchableDelegate(GURL("http://example.com/test"),
2130 "application/binary", std::string(100, 'a'),
2131 base::Bind(&EmptyClosure)),
2132 new TestBatchableDelegate(GURL("http://example.com/test"),
2133 "application/binary", std::string(50, 'b'),
2134 base::Bind(&EmptyClosure)),
2135 new TestBatchableDelegate(GURL("http://example.com/test"),
2136 "application/binary", std::string(0, 'c'),
2137 base::Bind(&EmptyClosure))};
2138 const size_t kExpectedUploadDataPosition[] = {208, 517, 776};
2139 const size_t kExpectedUploadDataSize = 851;
2140 request->AddRequest(requests[0]);
2141 request->AddRequest(requests[1]);
2142 request->AddRequest(requests[2]);
2143 request->Commit();
2144 request->Prepare(base::Bind(&EmptyPreapreCallback));
2146 request->OnURLFetchUploadProgress(nullptr, 0, kExpectedUploadDataSize);
2147 request->OnURLFetchUploadProgress(nullptr, 150, kExpectedUploadDataSize);
2148 EXPECT_EQ(0u, requests[0]->progress_values().size());
2149 EXPECT_EQ(0u, requests[1]->progress_values().size());
2150 EXPECT_EQ(0u, requests[2]->progress_values().size());
2151 request->OnURLFetchUploadProgress(nullptr, kExpectedUploadDataPosition[0],
2152 kExpectedUploadDataSize);
2153 EXPECT_EQ(1u, requests[0]->progress_values().size());
2154 EXPECT_EQ(0u, requests[1]->progress_values().size());
2155 EXPECT_EQ(0u, requests[2]->progress_values().size());
2156 request->OnURLFetchUploadProgress(
2157 nullptr, kExpectedUploadDataPosition[0] + 50, kExpectedUploadDataSize);
2158 EXPECT_EQ(2u, requests[0]->progress_values().size());
2159 EXPECT_EQ(0u, requests[1]->progress_values().size());
2160 EXPECT_EQ(0u, requests[2]->progress_values().size());
2161 request->OnURLFetchUploadProgress(
2162 nullptr, kExpectedUploadDataPosition[1] + 20, kExpectedUploadDataSize);
2163 EXPECT_EQ(3u, requests[0]->progress_values().size());
2164 EXPECT_EQ(1u, requests[1]->progress_values().size());
2165 EXPECT_EQ(0u, requests[2]->progress_values().size());
2166 request->OnURLFetchUploadProgress(nullptr, kExpectedUploadDataPosition[2],
2167 kExpectedUploadDataSize);
2168 EXPECT_EQ(3u, requests[0]->progress_values().size());
2169 EXPECT_EQ(2u, requests[1]->progress_values().size());
2170 EXPECT_EQ(1u, requests[2]->progress_values().size());
2171 request->OnURLFetchUploadProgress(nullptr, kExpectedUploadDataSize,
2172 kExpectedUploadDataSize);
2173 ASSERT_EQ(3u, requests[0]->progress_values().size());
2174 EXPECT_EQ(0, requests[0]->progress_values()[0]);
2175 EXPECT_EQ(50, requests[0]->progress_values()[1]);
2176 EXPECT_EQ(100, requests[0]->progress_values()[2]);
2177 ASSERT_EQ(2u, requests[1]->progress_values().size());
2178 EXPECT_EQ(20, requests[1]->progress_values()[0]);
2179 EXPECT_EQ(50, requests[1]->progress_values()[1]);
2180 ASSERT_EQ(1u, requests[2]->progress_values().size());
2181 EXPECT_EQ(0, requests[2]->progress_values()[0]);
2183 request->Cancel();
2186 TEST(ParseMultipartResponseTest, Empty) {
2187 std::vector<drive::MultipartHttpResponse> parts;
2188 EXPECT_FALSE(drive::ParseMultipartResponse(
2189 "multipart/mixed; boundary=BOUNDARY", "", &parts));
2190 EXPECT_FALSE(drive::ParseMultipartResponse("multipart/mixed; boundary=",
2191 "CONTENT", &parts));
2194 TEST(ParseMultipartResponseTest, Basic) {
2195 std::vector<drive::MultipartHttpResponse> parts;
2196 ASSERT_TRUE(
2197 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2198 "--BOUNDARY\r\n"
2199 "Content-Type: application/http\r\n"
2200 "\r\n"
2201 "HTTP/1.1 200 OK\r\n"
2202 "Header: value\r\n"
2203 "\r\n"
2204 "First line\r\n"
2205 "Second line\r\n"
2206 "--BOUNDARY\r\n"
2207 "Content-Type: application/http\r\n"
2208 "\r\n"
2209 "HTTP/1.1 404 Not Found\r\n"
2210 "Header: value\r\n"
2211 "--BOUNDARY--",
2212 &parts));
2213 ASSERT_EQ(2u, parts.size());
2214 EXPECT_EQ(HTTP_SUCCESS, parts[0].code);
2215 EXPECT_EQ("First line\r\nSecond line", parts[0].body);
2216 EXPECT_EQ(HTTP_NOT_FOUND, parts[1].code);
2217 EXPECT_EQ("", parts[1].body);
2220 TEST(ParseMultipartResponseTest, InvalidStatusLine) {
2221 std::vector<drive::MultipartHttpResponse> parts;
2222 ASSERT_TRUE(
2223 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2224 "--BOUNDARY\r\n"
2225 "Content-Type: application/http\r\n"
2226 "\r\n"
2227 "InvalidStatusLine 200 \r\n"
2228 "Header: value\r\n"
2229 "\r\n"
2230 "{}\r\n"
2231 "--BOUNDARY--",
2232 &parts));
2233 ASSERT_EQ(1u, parts.size());
2234 EXPECT_EQ(DRIVE_PARSE_ERROR, parts[0].code);
2235 EXPECT_EQ("{}", parts[0].body);
2238 TEST(ParseMultipartResponseTest, BoundaryInTheBodyAndPreamble) {
2239 std::vector<drive::MultipartHttpResponse> parts;
2240 ASSERT_TRUE(
2241 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2242 "BOUNDARY\r\n"
2243 "PREUMBLE\r\n"
2244 "--BOUNDARY\r\n"
2245 "Content-Type: application/http\r\n"
2246 "\r\n"
2247 "HTTP/1.1 200 OK\r\n"
2248 "Header: value\r\n"
2249 "\r\n"
2250 "{--BOUNDARY}\r\n"
2251 "--BOUNDARY--",
2252 &parts));
2253 ASSERT_EQ(1u, parts.size());
2254 EXPECT_EQ(HTTP_SUCCESS, parts[0].code);
2255 EXPECT_EQ("{--BOUNDARY}", parts[0].body);
2258 TEST(ParseMultipartResponseTest, QuatedBoundary) {
2259 std::vector<drive::MultipartHttpResponse> parts;
2260 ASSERT_TRUE(
2261 drive::ParseMultipartResponse("multipart/mixed; boundary=\"BOUNDARY\"",
2262 "--BOUNDARY\r\n"
2263 "Content-Type: application/http\r\n"
2264 "\r\n"
2265 "HTTP/1.1 200 OK\r\n"
2266 "Header: value\r\n"
2267 "\r\n"
2268 "BODY\r\n"
2269 "--BOUNDARY--",
2270 &parts));
2271 ASSERT_EQ(1u, parts.size());
2272 EXPECT_EQ(HTTP_SUCCESS, parts[0].code);
2273 EXPECT_EQ("BODY", parts[0].body);
2276 TEST(ParseMultipartResponseTest, BoundaryWithTransportPadding) {
2277 std::vector<drive::MultipartHttpResponse> parts;
2278 ASSERT_TRUE(
2279 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2280 "--BOUNDARY \t\r\n"
2281 "Content-Type: application/http\r\n"
2282 "\r\n"
2283 "HTTP/1.1 200 OK\r\n"
2284 "Header: value\r\n"
2285 "\r\n"
2286 "BODY\r\n"
2287 "--BOUNDARY-- \t",
2288 &parts));
2289 ASSERT_EQ(1u, parts.size());
2290 EXPECT_EQ(HTTP_SUCCESS, parts[0].code);
2291 EXPECT_EQ("BODY", parts[0].body);
2293 } // namespace google_apis