Add ICU message format support
[chromium-blink-merge.git] / google_apis / drive / drive_api_requests_unittest.cc
blob8ca6e1718a3bba1190458d40d2a85f66cbb8bd9c
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_last_viewed_by_me_date(
562 base::Time::FromUTCExploded(kLastViewedByMeDate));
563 request->set_mime_type("application/vnd.google-apps.folder");
564 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
565 request->add_parent("root");
566 request->set_title("new directory");
567 request->set_properties(testing_properties_);
568 request_sender_->StartRequestWithAuthRetry(request);
569 run_loop.Run();
572 EXPECT_EQ(HTTP_SUCCESS, error);
573 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
574 EXPECT_EQ("/drive/v2/files", http_request_.relative_url);
575 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
577 EXPECT_TRUE(http_request_.has_content);
578 EXPECT_EQ(
579 "{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
580 "\"mimeType\":\"application/vnd.google-apps.folder\","
581 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
582 "\"parents\":[{\"id\":\"root\"}],"
583 "\"properties\":["
584 "{\"key\":\"key1\",\"value\":\"value1\",\"visibility\":\"PRIVATE\"},"
585 "{\"key\":\"key2\",\"value\":\"value2\",\"visibility\":\"PUBLIC\"}],"
586 "\"title\":\"new directory\"}",
587 http_request_.content);
589 scoped_ptr<FileResource> expected(
590 FileResource::CreateFrom(
591 *test_util::LoadJSONFile("drive/directory_entry.json")));
593 // Sanity check.
594 ASSERT_TRUE(file_resource.get());
596 EXPECT_EQ(expected->file_id(), file_resource->file_id());
597 EXPECT_EQ(expected->title(), file_resource->title());
598 EXPECT_EQ(expected->mime_type(), file_resource->mime_type());
599 EXPECT_EQ(expected->parents().size(), file_resource->parents().size());
602 TEST_F(DriveApiRequestsTest, FilesPatchRequest) {
603 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
604 const base::Time::Exploded kLastViewedByMeDate =
605 {2013, 7, 0, 19, 15, 59, 13, 123};
607 // Set an expected data file containing valid result.
608 expected_data_file_path_ =
609 test_util::GetTestFilePath("drive/file_entry.json");
611 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
612 scoped_ptr<FileResource> file_resource;
615 base::RunLoop run_loop;
616 drive::FilesPatchRequest* request = new drive::FilesPatchRequest(
617 request_sender_.get(),
618 *url_generator_,
619 test_util::CreateQuitCallback(
620 &run_loop,
621 test_util::CreateCopyResultCallback(&error, &file_resource)));
622 request->set_file_id("resource_id");
623 request->set_set_modified_date(true);
624 request->set_update_viewed_date(false);
626 request->set_title("new title");
627 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
628 request->set_last_viewed_by_me_date(
629 base::Time::FromUTCExploded(kLastViewedByMeDate));
630 request->add_parent("parent_resource_id");
632 request->set_properties(testing_properties_);
633 request_sender_->StartRequestWithAuthRetry(request);
634 run_loop.Run();
637 EXPECT_EQ(HTTP_SUCCESS, error);
638 EXPECT_EQ(net::test_server::METHOD_PATCH, http_request_.method);
639 EXPECT_EQ("/drive/v2/files/resource_id"
640 "?setModifiedDate=true&updateViewedDate=false",
641 http_request_.relative_url);
643 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
644 EXPECT_TRUE(http_request_.has_content);
645 EXPECT_EQ(
646 "{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
647 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
648 "\"parents\":[{\"id\":\"parent_resource_id\"}],"
649 "\"properties\":["
650 "{\"key\":\"key1\",\"value\":\"value1\",\"visibility\":\"PRIVATE\"},"
651 "{\"key\":\"key2\",\"value\":\"value2\",\"visibility\":\"PUBLIC\"}],"
652 "\"title\":\"new title\"}",
653 http_request_.content);
654 EXPECT_TRUE(file_resource);
657 TEST_F(DriveApiRequestsTest, AboutGetRequest_ValidJson) {
658 // Set an expected data file containing valid result.
659 expected_data_file_path_ = test_util::GetTestFilePath(
660 "drive/about.json");
662 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
663 scoped_ptr<AboutResource> about_resource;
666 base::RunLoop run_loop;
667 drive::AboutGetRequest* request = new drive::AboutGetRequest(
668 request_sender_.get(),
669 *url_generator_,
670 test_util::CreateQuitCallback(
671 &run_loop,
672 test_util::CreateCopyResultCallback(&error, &about_resource)));
673 request_sender_->StartRequestWithAuthRetry(request);
674 run_loop.Run();
677 EXPECT_EQ(HTTP_SUCCESS, error);
678 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
679 EXPECT_EQ("/drive/v2/about", http_request_.relative_url);
681 scoped_ptr<AboutResource> expected(
682 AboutResource::CreateFrom(
683 *test_util::LoadJSONFile("drive/about.json")));
684 ASSERT_TRUE(about_resource.get());
685 EXPECT_EQ(expected->largest_change_id(), about_resource->largest_change_id());
686 EXPECT_EQ(expected->quota_bytes_total(), about_resource->quota_bytes_total());
687 EXPECT_EQ(expected->quota_bytes_used_aggregate(),
688 about_resource->quota_bytes_used_aggregate());
689 EXPECT_EQ(expected->root_folder_id(), about_resource->root_folder_id());
692 TEST_F(DriveApiRequestsTest, AboutGetRequest_InvalidJson) {
693 // Set an expected data file containing invalid result.
694 expected_data_file_path_ = test_util::GetTestFilePath(
695 "drive/testfile.txt");
697 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
698 scoped_ptr<AboutResource> about_resource;
701 base::RunLoop run_loop;
702 drive::AboutGetRequest* request = new drive::AboutGetRequest(
703 request_sender_.get(),
704 *url_generator_,
705 test_util::CreateQuitCallback(
706 &run_loop,
707 test_util::CreateCopyResultCallback(&error, &about_resource)));
708 request_sender_->StartRequestWithAuthRetry(request);
709 run_loop.Run();
712 // "parse error" should be returned, and the about resource should be NULL.
713 EXPECT_EQ(DRIVE_PARSE_ERROR, error);
714 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
715 EXPECT_EQ("/drive/v2/about", http_request_.relative_url);
716 EXPECT_FALSE(about_resource);
719 TEST_F(DriveApiRequestsTest, AppsListRequest) {
720 // Set an expected data file containing valid result.
721 expected_data_file_path_ = test_util::GetTestFilePath(
722 "drive/applist.json");
724 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
725 scoped_ptr<AppList> app_list;
728 base::RunLoop run_loop;
729 drive::AppsListRequest* request = new drive::AppsListRequest(
730 request_sender_.get(),
731 *url_generator_,
732 false, // use_internal_endpoint
733 test_util::CreateQuitCallback(
734 &run_loop,
735 test_util::CreateCopyResultCallback(&error, &app_list)));
736 request_sender_->StartRequestWithAuthRetry(request);
737 run_loop.Run();
740 EXPECT_EQ(HTTP_SUCCESS, error);
741 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
742 EXPECT_EQ("/drive/v2/apps", http_request_.relative_url);
743 EXPECT_TRUE(app_list);
746 TEST_F(DriveApiRequestsTest, ChangesListRequest) {
747 // Set an expected data file containing valid result.
748 expected_data_file_path_ = test_util::GetTestFilePath(
749 "drive/changelist.json");
751 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
752 scoped_ptr<ChangeList> result;
755 base::RunLoop run_loop;
756 drive::ChangesListRequest* request = new drive::ChangesListRequest(
757 request_sender_.get(), *url_generator_,
758 test_util::CreateQuitCallback(
759 &run_loop,
760 test_util::CreateCopyResultCallback(&error, &result)));
761 request->set_include_deleted(true);
762 request->set_start_change_id(100);
763 request->set_max_results(500);
764 request_sender_->StartRequestWithAuthRetry(request);
765 run_loop.Run();
768 EXPECT_EQ(HTTP_SUCCESS, error);
769 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
770 EXPECT_EQ("/drive/v2/changes?maxResults=500&startChangeId=100",
771 http_request_.relative_url);
772 EXPECT_TRUE(result);
775 TEST_F(DriveApiRequestsTest, ChangesListNextPageRequest) {
776 // Set an expected data file containing valid result.
777 expected_data_file_path_ = test_util::GetTestFilePath(
778 "drive/changelist.json");
780 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
781 scoped_ptr<ChangeList> result;
784 base::RunLoop run_loop;
785 drive::ChangesListNextPageRequest* request =
786 new drive::ChangesListNextPageRequest(
787 request_sender_.get(),
788 test_util::CreateQuitCallback(
789 &run_loop,
790 test_util::CreateCopyResultCallback(&error, &result)));
791 request->set_next_link(test_server_.GetURL("/continue/get/change/list"));
792 request_sender_->StartRequestWithAuthRetry(request);
793 run_loop.Run();
796 EXPECT_EQ(HTTP_SUCCESS, error);
797 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
798 EXPECT_EQ("/continue/get/change/list", http_request_.relative_url);
799 EXPECT_TRUE(result);
802 TEST_F(DriveApiRequestsTest, FilesCopyRequest) {
803 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
805 // Set an expected data file containing the dummy file entry data.
806 // It'd be returned if we copy a file.
807 expected_data_file_path_ =
808 test_util::GetTestFilePath("drive/file_entry.json");
810 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
811 scoped_ptr<FileResource> file_resource;
813 // Copy the file to a new file named "new title".
815 base::RunLoop run_loop;
816 drive::FilesCopyRequest* request = new drive::FilesCopyRequest(
817 request_sender_.get(),
818 *url_generator_,
819 test_util::CreateQuitCallback(
820 &run_loop,
821 test_util::CreateCopyResultCallback(&error, &file_resource)));
822 request->set_file_id("resource_id");
823 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
824 request->add_parent("parent_resource_id");
825 request->set_title("new title");
826 request_sender_->StartRequestWithAuthRetry(request);
827 run_loop.Run();
830 EXPECT_EQ(HTTP_SUCCESS, error);
831 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
832 EXPECT_EQ("/drive/v2/files/resource_id/copy", http_request_.relative_url);
833 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
835 EXPECT_TRUE(http_request_.has_content);
836 EXPECT_EQ(
837 "{\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
838 "\"parents\":[{\"id\":\"parent_resource_id\"}],\"title\":\"new title\"}",
839 http_request_.content);
840 EXPECT_TRUE(file_resource);
843 TEST_F(DriveApiRequestsTest, FilesCopyRequest_EmptyParentResourceId) {
844 // Set an expected data file containing the dummy file entry data.
845 // It'd be returned if we copy a file.
846 expected_data_file_path_ =
847 test_util::GetTestFilePath("drive/file_entry.json");
849 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
850 scoped_ptr<FileResource> file_resource;
852 // Copy the file to a new file named "new title".
854 base::RunLoop run_loop;
855 drive::FilesCopyRequest* request = new drive::FilesCopyRequest(
856 request_sender_.get(),
857 *url_generator_,
858 test_util::CreateQuitCallback(
859 &run_loop,
860 test_util::CreateCopyResultCallback(&error, &file_resource)));
861 request->set_file_id("resource_id");
862 request->set_title("new title");
863 request_sender_->StartRequestWithAuthRetry(request);
864 run_loop.Run();
867 EXPECT_EQ(HTTP_SUCCESS, error);
868 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
869 EXPECT_EQ("/drive/v2/files/resource_id/copy", http_request_.relative_url);
870 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
872 EXPECT_TRUE(http_request_.has_content);
873 EXPECT_EQ("{\"title\":\"new title\"}", http_request_.content);
874 EXPECT_TRUE(file_resource);
877 TEST_F(DriveApiRequestsTest, FilesListRequest) {
878 // Set an expected data file containing valid result.
879 expected_data_file_path_ = test_util::GetTestFilePath(
880 "drive/filelist.json");
882 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
883 scoped_ptr<FileList> result;
886 base::RunLoop run_loop;
887 drive::FilesListRequest* request = new drive::FilesListRequest(
888 request_sender_.get(), *url_generator_,
889 test_util::CreateQuitCallback(
890 &run_loop,
891 test_util::CreateCopyResultCallback(&error, &result)));
892 request->set_max_results(50);
893 request->set_q("\"abcde\" in parents");
894 request_sender_->StartRequestWithAuthRetry(request);
895 run_loop.Run();
898 EXPECT_EQ(HTTP_SUCCESS, error);
899 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
900 EXPECT_EQ("/drive/v2/files?maxResults=50&q=%22abcde%22+in+parents",
901 http_request_.relative_url);
902 EXPECT_TRUE(result);
905 TEST_F(DriveApiRequestsTest, FilesListNextPageRequest) {
906 // Set an expected data file containing valid result.
907 expected_data_file_path_ = test_util::GetTestFilePath(
908 "drive/filelist.json");
910 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
911 scoped_ptr<FileList> result;
914 base::RunLoop run_loop;
915 drive::FilesListNextPageRequest* request =
916 new drive::FilesListNextPageRequest(
917 request_sender_.get(),
918 test_util::CreateQuitCallback(
919 &run_loop,
920 test_util::CreateCopyResultCallback(&error, &result)));
921 request->set_next_link(test_server_.GetURL("/continue/get/file/list"));
922 request_sender_->StartRequestWithAuthRetry(request);
923 run_loop.Run();
926 EXPECT_EQ(HTTP_SUCCESS, error);
927 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
928 EXPECT_EQ("/continue/get/file/list", http_request_.relative_url);
929 EXPECT_TRUE(result);
932 TEST_F(DriveApiRequestsTest, FilesDeleteRequest) {
933 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
935 // Delete a resource with the given resource id.
937 base::RunLoop run_loop;
938 drive::FilesDeleteRequest* request = new drive::FilesDeleteRequest(
939 request_sender_.get(),
940 *url_generator_,
941 test_util::CreateQuitCallback(
942 &run_loop, test_util::CreateCopyResultCallback(&error)));
943 request->set_file_id("resource_id");
944 request->set_etag(kTestETag);
945 request_sender_->StartRequestWithAuthRetry(request);
946 run_loop.Run();
949 EXPECT_EQ(HTTP_NO_CONTENT, error);
950 EXPECT_EQ(net::test_server::METHOD_DELETE, http_request_.method);
951 EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
952 EXPECT_EQ("/drive/v2/files/resource_id", http_request_.relative_url);
953 EXPECT_FALSE(http_request_.has_content);
956 TEST_F(DriveApiRequestsTest, FilesTrashRequest) {
957 // Set data for the expected result. Directory entry should be returned
958 // if the trashing entry is a directory, so using it here should be fine.
959 expected_data_file_path_ =
960 test_util::GetTestFilePath("drive/directory_entry.json");
962 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
963 scoped_ptr<FileResource> file_resource;
965 // Trash a resource with the given resource id.
967 base::RunLoop run_loop;
968 drive::FilesTrashRequest* request = new drive::FilesTrashRequest(
969 request_sender_.get(),
970 *url_generator_,
971 test_util::CreateQuitCallback(
972 &run_loop,
973 test_util::CreateCopyResultCallback(&error, &file_resource)));
974 request->set_file_id("resource_id");
975 request_sender_->StartRequestWithAuthRetry(request);
976 run_loop.Run();
979 EXPECT_EQ(HTTP_SUCCESS, error);
980 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
981 EXPECT_EQ("/drive/v2/files/resource_id/trash", http_request_.relative_url);
982 EXPECT_TRUE(http_request_.has_content);
983 EXPECT_TRUE(http_request_.content.empty());
986 TEST_F(DriveApiRequestsTest, ChildrenInsertRequest) {
987 // Set an expected data file containing the children entry.
988 expected_content_type_ = "application/json";
989 expected_content_ = kTestChildrenResponse;
991 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
993 // Add a resource with "resource_id" to a directory with
994 // "parent_resource_id".
996 base::RunLoop run_loop;
997 drive::ChildrenInsertRequest* request = new drive::ChildrenInsertRequest(
998 request_sender_.get(),
999 *url_generator_,
1000 test_util::CreateQuitCallback(
1001 &run_loop,
1002 test_util::CreateCopyResultCallback(&error)));
1003 request->set_folder_id("parent_resource_id");
1004 request->set_id("resource_id");
1005 request_sender_->StartRequestWithAuthRetry(request);
1006 run_loop.Run();
1009 EXPECT_EQ(HTTP_SUCCESS, error);
1010 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1011 EXPECT_EQ("/drive/v2/files/parent_resource_id/children",
1012 http_request_.relative_url);
1013 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1015 EXPECT_TRUE(http_request_.has_content);
1016 EXPECT_EQ("{\"id\":\"resource_id\"}", http_request_.content);
1019 TEST_F(DriveApiRequestsTest, ChildrenDeleteRequest) {
1020 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1022 // Remove a resource with "resource_id" from a directory with
1023 // "parent_resource_id".
1025 base::RunLoop run_loop;
1026 drive::ChildrenDeleteRequest* request = new drive::ChildrenDeleteRequest(
1027 request_sender_.get(),
1028 *url_generator_,
1029 test_util::CreateQuitCallback(
1030 &run_loop,
1031 test_util::CreateCopyResultCallback(&error)));
1032 request->set_child_id("resource_id");
1033 request->set_folder_id("parent_resource_id");
1034 request_sender_->StartRequestWithAuthRetry(request);
1035 run_loop.Run();
1038 EXPECT_EQ(HTTP_NO_CONTENT, error);
1039 EXPECT_EQ(net::test_server::METHOD_DELETE, http_request_.method);
1040 EXPECT_EQ("/drive/v2/files/parent_resource_id/children/resource_id",
1041 http_request_.relative_url);
1042 EXPECT_FALSE(http_request_.has_content);
1045 TEST_F(DriveApiRequestsTest, UploadNewFileRequest) {
1046 // Set an expected url for uploading.
1047 expected_upload_path_ = kTestUploadNewFilePath;
1049 const char kTestContentType[] = "text/plain";
1050 const std::string kTestContent(100, 'a');
1051 const base::FilePath kTestFilePath =
1052 temp_dir_.path().AppendASCII("upload_file.txt");
1053 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1055 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1056 GURL upload_url;
1058 // Initiate uploading a new file to the directory with
1059 // "parent_resource_id".
1061 base::RunLoop run_loop;
1062 drive::InitiateUploadNewFileRequest* request =
1063 new drive::InitiateUploadNewFileRequest(
1064 request_sender_.get(),
1065 *url_generator_,
1066 kTestContentType,
1067 kTestContent.size(),
1068 "parent_resource_id", // The resource id of the parent directory.
1069 "new file title", // The title of the file being uploaded.
1070 test_util::CreateQuitCallback(
1071 &run_loop,
1072 test_util::CreateCopyResultCallback(&error, &upload_url)));
1073 request->set_properties(testing_properties_);
1074 request_sender_->StartRequestWithAuthRetry(request);
1075 run_loop.Run();
1078 EXPECT_EQ(HTTP_SUCCESS, error);
1079 EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1080 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1081 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1082 http_request_.headers["X-Upload-Content-Length"]);
1084 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1085 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
1086 http_request_.relative_url);
1087 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1088 EXPECT_TRUE(http_request_.has_content);
1089 EXPECT_EQ(
1090 "{\"parents\":[{"
1091 "\"id\":\"parent_resource_id\","
1092 "\"kind\":\"drive#fileLink\""
1093 "}],"
1094 "\"properties\":["
1095 "{\"key\":\"key1\",\"value\":\"value1\",\"visibility\":\"PRIVATE\"},"
1096 "{\"key\":\"key2\",\"value\":\"value2\",\"visibility\":\"PUBLIC\"}],"
1097 "\"title\":\"new file title\"}",
1098 http_request_.content);
1100 // Upload the content to the upload URL.
1101 UploadRangeResponse response;
1102 scoped_ptr<FileResource> new_entry;
1105 base::RunLoop run_loop;
1106 drive::ResumeUploadRequest* resume_request =
1107 new drive::ResumeUploadRequest(
1108 request_sender_.get(),
1109 upload_url,
1110 0, // start_position
1111 kTestContent.size(), // end_position (exclusive)
1112 kTestContent.size(), // content_length,
1113 kTestContentType,
1114 kTestFilePath,
1115 test_util::CreateQuitCallback(
1116 &run_loop,
1117 test_util::CreateCopyResultCallback(&response, &new_entry)),
1118 ProgressCallback());
1119 request_sender_->StartRequestWithAuthRetry(resume_request);
1120 run_loop.Run();
1123 // METHOD_PUT should be used to upload data.
1124 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1125 // Request should go to the upload URL.
1126 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1127 // Content-Range header should be added.
1128 EXPECT_EQ("bytes 0-" +
1129 base::Int64ToString(kTestContent.size() - 1) + "/" +
1130 base::Int64ToString(kTestContent.size()),
1131 http_request_.headers["Content-Range"]);
1132 // The upload content should be set in the HTTP request.
1133 EXPECT_TRUE(http_request_.has_content);
1134 EXPECT_EQ(kTestContent, http_request_.content);
1136 // Check the response.
1137 EXPECT_EQ(HTTP_CREATED, response.code); // Because it's a new file
1138 // The start and end positions should be set to -1, if an upload is complete.
1139 EXPECT_EQ(-1, response.start_position_received);
1140 EXPECT_EQ(-1, response.end_position_received);
1143 TEST_F(DriveApiRequestsTest, UploadNewEmptyFileRequest) {
1144 // Set an expected url for uploading.
1145 expected_upload_path_ = kTestUploadNewFilePath;
1147 const char kTestContentType[] = "text/plain";
1148 const char kTestContent[] = "";
1149 const base::FilePath kTestFilePath =
1150 temp_dir_.path().AppendASCII("empty_file.txt");
1151 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1153 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1154 GURL upload_url;
1156 // Initiate uploading a new file to the directory with "parent_resource_id".
1158 base::RunLoop run_loop;
1159 drive::InitiateUploadNewFileRequest* request =
1160 new drive::InitiateUploadNewFileRequest(
1161 request_sender_.get(),
1162 *url_generator_,
1163 kTestContentType,
1165 "parent_resource_id", // The resource id of the parent directory.
1166 "new file title", // The title of the file being uploaded.
1167 test_util::CreateQuitCallback(
1168 &run_loop,
1169 test_util::CreateCopyResultCallback(&error, &upload_url)));
1170 request_sender_->StartRequestWithAuthRetry(request);
1171 run_loop.Run();
1174 EXPECT_EQ(HTTP_SUCCESS, error);
1175 EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1176 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1177 EXPECT_EQ("0", http_request_.headers["X-Upload-Content-Length"]);
1179 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1180 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
1181 http_request_.relative_url);
1182 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1183 EXPECT_TRUE(http_request_.has_content);
1184 EXPECT_EQ("{\"parents\":[{"
1185 "\"id\":\"parent_resource_id\","
1186 "\"kind\":\"drive#fileLink\""
1187 "}],"
1188 "\"title\":\"new file title\"}",
1189 http_request_.content);
1191 // Upload the content to the upload URL.
1192 UploadRangeResponse response;
1193 scoped_ptr<FileResource> new_entry;
1196 base::RunLoop run_loop;
1197 drive::ResumeUploadRequest* resume_request =
1198 new drive::ResumeUploadRequest(
1199 request_sender_.get(),
1200 upload_url,
1201 0, // start_position
1202 0, // end_position (exclusive)
1203 0, // content_length,
1204 kTestContentType,
1205 kTestFilePath,
1206 test_util::CreateQuitCallback(
1207 &run_loop,
1208 test_util::CreateCopyResultCallback(&response, &new_entry)),
1209 ProgressCallback());
1210 request_sender_->StartRequestWithAuthRetry(resume_request);
1211 run_loop.Run();
1214 // METHOD_PUT should be used to upload data.
1215 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1216 // Request should go to the upload URL.
1217 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1218 // Content-Range header should NOT be added.
1219 EXPECT_EQ(0U, http_request_.headers.count("Content-Range"));
1220 // The upload content should be set in the HTTP request.
1221 EXPECT_TRUE(http_request_.has_content);
1222 EXPECT_EQ(kTestContent, http_request_.content);
1224 // Check the response.
1225 EXPECT_EQ(HTTP_CREATED, response.code); // Because it's a new file
1226 // The start and end positions should be set to -1, if an upload is complete.
1227 EXPECT_EQ(-1, response.start_position_received);
1228 EXPECT_EQ(-1, response.end_position_received);
1231 TEST_F(DriveApiRequestsTest, UploadNewLargeFileRequest) {
1232 // Set an expected url for uploading.
1233 expected_upload_path_ = kTestUploadNewFilePath;
1235 const char kTestContentType[] = "text/plain";
1236 const size_t kNumChunkBytes = 10; // Num bytes in a chunk.
1237 const std::string kTestContent(100, 'a');
1238 const base::FilePath kTestFilePath =
1239 temp_dir_.path().AppendASCII("upload_file.txt");
1240 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1242 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1243 GURL upload_url;
1245 // Initiate uploading a new file to the directory with "parent_resource_id".
1247 base::RunLoop run_loop;
1248 drive::InitiateUploadNewFileRequest* request =
1249 new drive::InitiateUploadNewFileRequest(
1250 request_sender_.get(),
1251 *url_generator_,
1252 kTestContentType,
1253 kTestContent.size(),
1254 "parent_resource_id", // The resource id of the parent directory.
1255 "new file title", // The title of the file being uploaded.
1256 test_util::CreateQuitCallback(
1257 &run_loop,
1258 test_util::CreateCopyResultCallback(&error, &upload_url)));
1259 request_sender_->StartRequestWithAuthRetry(request);
1260 run_loop.Run();
1263 EXPECT_EQ(HTTP_SUCCESS, error);
1264 EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1265 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1266 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1267 http_request_.headers["X-Upload-Content-Length"]);
1269 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1270 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
1271 http_request_.relative_url);
1272 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1273 EXPECT_TRUE(http_request_.has_content);
1274 EXPECT_EQ("{\"parents\":[{"
1275 "\"id\":\"parent_resource_id\","
1276 "\"kind\":\"drive#fileLink\""
1277 "}],"
1278 "\"title\":\"new file title\"}",
1279 http_request_.content);
1281 // Before sending any data, check the current status.
1282 // This is an edge case test for GetUploadStatusRequest.
1284 UploadRangeResponse response;
1285 scoped_ptr<FileResource> new_entry;
1287 // Check the response by GetUploadStatusRequest.
1289 base::RunLoop run_loop;
1290 drive::GetUploadStatusRequest* get_upload_status_request =
1291 new drive::GetUploadStatusRequest(
1292 request_sender_.get(),
1293 upload_url,
1294 kTestContent.size(),
1295 test_util::CreateQuitCallback(
1296 &run_loop,
1297 test_util::CreateCopyResultCallback(&response, &new_entry)));
1298 request_sender_->StartRequestWithAuthRetry(get_upload_status_request);
1299 run_loop.Run();
1302 // METHOD_PUT should be used to upload data.
1303 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1304 // Request should go to the upload URL.
1305 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1306 // Content-Range header should be added.
1307 EXPECT_EQ("bytes */" + base::Int64ToString(kTestContent.size()),
1308 http_request_.headers["Content-Range"]);
1309 EXPECT_TRUE(http_request_.has_content);
1310 EXPECT_TRUE(http_request_.content.empty());
1312 // Check the response.
1313 EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code);
1314 EXPECT_EQ(0, response.start_position_received);
1315 EXPECT_EQ(0, response.end_position_received);
1318 // Upload the content to the upload URL.
1319 for (size_t start_position = 0; start_position < kTestContent.size();
1320 start_position += kNumChunkBytes) {
1321 const std::string payload = kTestContent.substr(
1322 start_position,
1323 std::min(kNumChunkBytes, kTestContent.size() - start_position));
1324 const size_t end_position = start_position + payload.size();
1326 UploadRangeResponse response;
1327 scoped_ptr<FileResource> new_entry;
1330 base::RunLoop run_loop;
1331 drive::ResumeUploadRequest* resume_request =
1332 new drive::ResumeUploadRequest(
1333 request_sender_.get(),
1334 upload_url,
1335 start_position,
1336 end_position,
1337 kTestContent.size(), // content_length,
1338 kTestContentType,
1339 kTestFilePath,
1340 test_util::CreateQuitCallback(
1341 &run_loop,
1342 test_util::CreateCopyResultCallback(&response, &new_entry)),
1343 ProgressCallback());
1344 request_sender_->StartRequestWithAuthRetry(resume_request);
1345 run_loop.Run();
1348 // METHOD_PUT should be used to upload data.
1349 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1350 // Request should go to the upload URL.
1351 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1352 // Content-Range header should be added.
1353 EXPECT_EQ("bytes " +
1354 base::Int64ToString(start_position) + "-" +
1355 base::Int64ToString(end_position - 1) + "/" +
1356 base::Int64ToString(kTestContent.size()),
1357 http_request_.headers["Content-Range"]);
1358 // The upload content should be set in the HTTP request.
1359 EXPECT_TRUE(http_request_.has_content);
1360 EXPECT_EQ(payload, http_request_.content);
1362 if (end_position == kTestContent.size()) {
1363 // Check the response.
1364 EXPECT_EQ(HTTP_CREATED, response.code); // Because it's a new file
1365 // The start and end positions should be set to -1, if an upload is
1366 // complete.
1367 EXPECT_EQ(-1, response.start_position_received);
1368 EXPECT_EQ(-1, response.end_position_received);
1369 break;
1372 // Check the response.
1373 EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code);
1374 EXPECT_EQ(0, response.start_position_received);
1375 EXPECT_EQ(static_cast<int64>(end_position), response.end_position_received);
1377 // Check the response by GetUploadStatusRequest.
1379 base::RunLoop run_loop;
1380 drive::GetUploadStatusRequest* get_upload_status_request =
1381 new drive::GetUploadStatusRequest(
1382 request_sender_.get(),
1383 upload_url,
1384 kTestContent.size(),
1385 test_util::CreateQuitCallback(
1386 &run_loop,
1387 test_util::CreateCopyResultCallback(&response, &new_entry)));
1388 request_sender_->StartRequestWithAuthRetry(get_upload_status_request);
1389 run_loop.Run();
1392 // METHOD_PUT should be used to upload data.
1393 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1394 // Request should go to the upload URL.
1395 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1396 // Content-Range header should be added.
1397 EXPECT_EQ("bytes */" + base::Int64ToString(kTestContent.size()),
1398 http_request_.headers["Content-Range"]);
1399 EXPECT_TRUE(http_request_.has_content);
1400 EXPECT_TRUE(http_request_.content.empty());
1402 // Check the response.
1403 EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code);
1404 EXPECT_EQ(0, response.start_position_received);
1405 EXPECT_EQ(static_cast<int64>(end_position),
1406 response.end_position_received);
1410 TEST_F(DriveApiRequestsTest, UploadNewFileWithMetadataRequest) {
1411 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
1412 const base::Time::Exploded kLastViewedByMeDate =
1413 {2013, 7, 0, 19, 15, 59, 13, 123};
1415 // Set an expected url for uploading.
1416 expected_upload_path_ = kTestUploadNewFilePath;
1418 const char kTestContentType[] = "text/plain";
1419 const std::string kTestContent(100, 'a');
1421 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1422 GURL upload_url;
1424 // Initiate uploading a new file to the directory with "parent_resource_id".
1426 base::RunLoop run_loop;
1427 drive::InitiateUploadNewFileRequest* request =
1428 new drive::InitiateUploadNewFileRequest(
1429 request_sender_.get(),
1430 *url_generator_,
1431 kTestContentType,
1432 kTestContent.size(),
1433 "parent_resource_id", // The resource id of the parent directory.
1434 "new file title", // The title of the file being uploaded.
1435 test_util::CreateQuitCallback(
1436 &run_loop,
1437 test_util::CreateCopyResultCallback(&error, &upload_url)));
1438 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
1439 request->set_last_viewed_by_me_date(
1440 base::Time::FromUTCExploded(kLastViewedByMeDate));
1441 request_sender_->StartRequestWithAuthRetry(request);
1442 run_loop.Run();
1445 EXPECT_EQ(HTTP_SUCCESS, error);
1446 EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1447 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1448 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1449 http_request_.headers["X-Upload-Content-Length"]);
1451 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1452 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable&setModifiedDate=true",
1453 http_request_.relative_url);
1454 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1455 EXPECT_TRUE(http_request_.has_content);
1456 EXPECT_EQ("{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
1457 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
1458 "\"parents\":[{\"id\":\"parent_resource_id\","
1459 "\"kind\":\"drive#fileLink\"}],"
1460 "\"title\":\"new file title\"}",
1461 http_request_.content);
1464 TEST_F(DriveApiRequestsTest, UploadExistingFileRequest) {
1465 // Set an expected url for uploading.
1466 expected_upload_path_ = kTestUploadExistingFilePath;
1468 const char kTestContentType[] = "text/plain";
1469 const std::string kTestContent(100, 'a');
1470 const base::FilePath kTestFilePath =
1471 temp_dir_.path().AppendASCII("upload_file.txt");
1472 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1474 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1475 GURL upload_url;
1477 // Initiate uploading a new file to the directory with "parent_resource_id".
1479 base::RunLoop run_loop;
1480 drive::InitiateUploadExistingFileRequest* request =
1481 new drive::InitiateUploadExistingFileRequest(
1482 request_sender_.get(),
1483 *url_generator_,
1484 kTestContentType,
1485 kTestContent.size(),
1486 "resource_id", // The resource id of the file to be overwritten.
1487 std::string(), // No etag.
1488 test_util::CreateQuitCallback(
1489 &run_loop,
1490 test_util::CreateCopyResultCallback(&error, &upload_url)));
1491 request->set_properties(testing_properties_);
1492 request_sender_->StartRequestWithAuthRetry(request);
1493 run_loop.Run();
1496 EXPECT_EQ(HTTP_SUCCESS, error);
1497 EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1498 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1499 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1500 http_request_.headers["X-Upload-Content-Length"]);
1501 EXPECT_EQ("*", http_request_.headers["If-Match"]);
1503 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1504 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1505 http_request_.relative_url);
1506 EXPECT_TRUE(http_request_.has_content);
1507 EXPECT_EQ(
1508 "{\"properties\":["
1509 "{\"key\":\"key1\",\"value\":\"value1\",\"visibility\":\"PRIVATE\"},"
1510 "{\"key\":\"key2\",\"value\":\"value2\",\"visibility\":\"PUBLIC\"}]}",
1511 http_request_.content);
1513 // Upload the content to the upload URL.
1514 UploadRangeResponse response;
1515 scoped_ptr<FileResource> new_entry;
1518 base::RunLoop run_loop;
1519 drive::ResumeUploadRequest* resume_request =
1520 new drive::ResumeUploadRequest(
1521 request_sender_.get(),
1522 upload_url,
1523 0, // start_position
1524 kTestContent.size(), // end_position (exclusive)
1525 kTestContent.size(), // content_length,
1526 kTestContentType,
1527 kTestFilePath,
1528 test_util::CreateQuitCallback(
1529 &run_loop,
1530 test_util::CreateCopyResultCallback(&response, &new_entry)),
1531 ProgressCallback());
1532 request_sender_->StartRequestWithAuthRetry(resume_request);
1533 run_loop.Run();
1536 // METHOD_PUT should be used to upload data.
1537 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1538 // Request should go to the upload URL.
1539 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1540 // Content-Range header should be added.
1541 EXPECT_EQ("bytes 0-" +
1542 base::Int64ToString(kTestContent.size() - 1) + "/" +
1543 base::Int64ToString(kTestContent.size()),
1544 http_request_.headers["Content-Range"]);
1545 // The upload content should be set in the HTTP request.
1546 EXPECT_TRUE(http_request_.has_content);
1547 EXPECT_EQ(kTestContent, http_request_.content);
1549 // Check the response.
1550 EXPECT_EQ(HTTP_SUCCESS, response.code); // Because it's an existing file
1551 // The start and end positions should be set to -1, if an upload is complete.
1552 EXPECT_EQ(-1, response.start_position_received);
1553 EXPECT_EQ(-1, response.end_position_received);
1556 TEST_F(DriveApiRequestsTest, UploadExistingFileRequestWithETag) {
1557 // Set an expected url for uploading.
1558 expected_upload_path_ = kTestUploadExistingFilePath;
1560 const char kTestContentType[] = "text/plain";
1561 const std::string kTestContent(100, 'a');
1562 const base::FilePath kTestFilePath =
1563 temp_dir_.path().AppendASCII("upload_file.txt");
1564 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1566 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1567 GURL upload_url;
1569 // Initiate uploading a new file to the directory with "parent_resource_id".
1571 base::RunLoop run_loop;
1572 drive::InitiateUploadExistingFileRequest* request =
1573 new drive::InitiateUploadExistingFileRequest(
1574 request_sender_.get(),
1575 *url_generator_,
1576 kTestContentType,
1577 kTestContent.size(),
1578 "resource_id", // The resource id of the file to be overwritten.
1579 kTestETag,
1580 test_util::CreateQuitCallback(
1581 &run_loop,
1582 test_util::CreateCopyResultCallback(&error, &upload_url)));
1583 request_sender_->StartRequestWithAuthRetry(request);
1584 run_loop.Run();
1587 EXPECT_EQ(HTTP_SUCCESS, error);
1588 EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1589 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1590 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1591 http_request_.headers["X-Upload-Content-Length"]);
1592 EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
1594 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1595 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1596 http_request_.relative_url);
1597 EXPECT_TRUE(http_request_.has_content);
1598 EXPECT_TRUE(http_request_.content.empty());
1600 // Upload the content to the upload URL.
1601 UploadRangeResponse response;
1602 scoped_ptr<FileResource> new_entry;
1605 base::RunLoop run_loop;
1606 drive::ResumeUploadRequest* resume_request =
1607 new drive::ResumeUploadRequest(
1608 request_sender_.get(),
1609 upload_url,
1610 0, // start_position
1611 kTestContent.size(), // end_position (exclusive)
1612 kTestContent.size(), // content_length,
1613 kTestContentType,
1614 kTestFilePath,
1615 test_util::CreateQuitCallback(
1616 &run_loop,
1617 test_util::CreateCopyResultCallback(&response, &new_entry)),
1618 ProgressCallback());
1619 request_sender_->StartRequestWithAuthRetry(resume_request);
1620 run_loop.Run();
1623 // METHOD_PUT should be used to upload data.
1624 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1625 // Request should go to the upload URL.
1626 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1627 // Content-Range header should be added.
1628 EXPECT_EQ("bytes 0-" +
1629 base::Int64ToString(kTestContent.size() - 1) + "/" +
1630 base::Int64ToString(kTestContent.size()),
1631 http_request_.headers["Content-Range"]);
1632 // The upload content should be set in the HTTP request.
1633 EXPECT_TRUE(http_request_.has_content);
1634 EXPECT_EQ(kTestContent, http_request_.content);
1636 // Check the response.
1637 EXPECT_EQ(HTTP_SUCCESS, response.code); // Because it's an existing file
1638 // The start and end positions should be set to -1, if an upload is complete.
1639 EXPECT_EQ(-1, response.start_position_received);
1640 EXPECT_EQ(-1, response.end_position_received);
1643 TEST_F(DriveApiRequestsTest, UploadExistingFileRequestWithETagConflicting) {
1644 // Set an expected url for uploading.
1645 expected_upload_path_ = kTestUploadExistingFilePath;
1647 // If it turned out that the etag is conflicting, PRECONDITION_FAILED should
1648 // be returned.
1649 expected_precondition_failed_file_path_ =
1650 test_util::GetTestFilePath("drive/error.json");
1652 const char kTestContentType[] = "text/plain";
1653 const std::string kTestContent(100, 'a');
1655 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1656 GURL upload_url;
1658 // Initiate uploading a new file to the directory with "parent_resource_id".
1660 base::RunLoop run_loop;
1661 drive::InitiateUploadExistingFileRequest* request =
1662 new drive::InitiateUploadExistingFileRequest(
1663 request_sender_.get(),
1664 *url_generator_,
1665 kTestContentType,
1666 kTestContent.size(),
1667 "resource_id", // The resource id of the file to be overwritten.
1668 "Conflicting-etag",
1669 test_util::CreateQuitCallback(
1670 &run_loop,
1671 test_util::CreateCopyResultCallback(&error, &upload_url)));
1672 request_sender_->StartRequestWithAuthRetry(request);
1673 run_loop.Run();
1676 EXPECT_EQ(HTTP_PRECONDITION, error);
1677 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1678 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1679 http_request_.headers["X-Upload-Content-Length"]);
1680 EXPECT_EQ("Conflicting-etag", http_request_.headers["If-Match"]);
1682 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1683 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1684 http_request_.relative_url);
1685 EXPECT_TRUE(http_request_.has_content);
1686 EXPECT_TRUE(http_request_.content.empty());
1689 TEST_F(DriveApiRequestsTest,
1690 UploadExistingFileRequestWithETagConflictOnResumeUpload) {
1691 // Set an expected url for uploading.
1692 expected_upload_path_ = kTestUploadExistingFilePath;
1694 const char kTestContentType[] = "text/plain";
1695 const std::string kTestContent(100, 'a');
1696 const base::FilePath kTestFilePath =
1697 temp_dir_.path().AppendASCII("upload_file.txt");
1698 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1700 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1701 GURL upload_url;
1703 // Initiate uploading a new file to the directory with "parent_resource_id".
1705 base::RunLoop run_loop;
1706 drive::InitiateUploadExistingFileRequest* request =
1707 new drive::InitiateUploadExistingFileRequest(
1708 request_sender_.get(),
1709 *url_generator_,
1710 kTestContentType,
1711 kTestContent.size(),
1712 "resource_id", // The resource id of the file to be overwritten.
1713 kTestETag,
1714 test_util::CreateQuitCallback(
1715 &run_loop,
1716 test_util::CreateCopyResultCallback(&error, &upload_url)));
1717 request_sender_->StartRequestWithAuthRetry(request);
1718 run_loop.Run();
1721 EXPECT_EQ(HTTP_SUCCESS, error);
1722 EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1723 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1724 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1725 http_request_.headers["X-Upload-Content-Length"]);
1726 EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
1728 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1729 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1730 http_request_.relative_url);
1731 EXPECT_TRUE(http_request_.has_content);
1732 EXPECT_TRUE(http_request_.content.empty());
1734 // Set PRECONDITION_FAILED to the server. This is the emulation of the
1735 // confliction during uploading.
1736 expected_precondition_failed_file_path_ =
1737 test_util::GetTestFilePath("drive/error.json");
1739 // Upload the content to the upload URL.
1740 UploadRangeResponse response;
1741 scoped_ptr<FileResource> new_entry;
1744 base::RunLoop run_loop;
1745 drive::ResumeUploadRequest* resume_request =
1746 new drive::ResumeUploadRequest(
1747 request_sender_.get(),
1748 upload_url,
1749 0, // start_position
1750 kTestContent.size(), // end_position (exclusive)
1751 kTestContent.size(), // content_length,
1752 kTestContentType,
1753 kTestFilePath,
1754 test_util::CreateQuitCallback(
1755 &run_loop,
1756 test_util::CreateCopyResultCallback(&response, &new_entry)),
1757 ProgressCallback());
1758 request_sender_->StartRequestWithAuthRetry(resume_request);
1759 run_loop.Run();
1762 // METHOD_PUT should be used to upload data.
1763 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1764 // Request should go to the upload URL.
1765 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1766 // Content-Range header should be added.
1767 EXPECT_EQ("bytes 0-" +
1768 base::Int64ToString(kTestContent.size() - 1) + "/" +
1769 base::Int64ToString(kTestContent.size()),
1770 http_request_.headers["Content-Range"]);
1771 // The upload content should be set in the HTTP request.
1772 EXPECT_TRUE(http_request_.has_content);
1773 EXPECT_EQ(kTestContent, http_request_.content);
1775 // Check the response.
1776 EXPECT_EQ(HTTP_PRECONDITION, response.code);
1777 // The start and end positions should be set to -1 for error.
1778 EXPECT_EQ(-1, response.start_position_received);
1779 EXPECT_EQ(-1, response.end_position_received);
1781 // New entry should be NULL.
1782 EXPECT_FALSE(new_entry.get());
1785 TEST_F(DriveApiRequestsTest, UploadExistingFileWithMetadataRequest) {
1786 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
1787 const base::Time::Exploded kLastViewedByMeDate =
1788 {2013, 7, 0, 19, 15, 59, 13, 123};
1790 // Set an expected url for uploading.
1791 expected_upload_path_ = kTestUploadExistingFilePath;
1793 const char kTestContentType[] = "text/plain";
1794 const std::string kTestContent(100, 'a');
1796 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1797 GURL upload_url;
1799 // Initiate uploading a new file to the directory with "parent_resource_id".
1801 base::RunLoop run_loop;
1802 drive::InitiateUploadExistingFileRequest* request =
1803 new drive::InitiateUploadExistingFileRequest(
1804 request_sender_.get(),
1805 *url_generator_,
1806 kTestContentType,
1807 kTestContent.size(),
1808 "resource_id", // The resource id of the file to be overwritten.
1809 kTestETag,
1810 test_util::CreateQuitCallback(
1811 &run_loop,
1812 test_util::CreateCopyResultCallback(&error, &upload_url)));
1813 request->set_parent_resource_id("new_parent_resource_id");
1814 request->set_title("new file title");
1815 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
1816 request->set_last_viewed_by_me_date(
1817 base::Time::FromUTCExploded(kLastViewedByMeDate));
1819 request_sender_->StartRequestWithAuthRetry(request);
1820 run_loop.Run();
1823 EXPECT_EQ(HTTP_SUCCESS, error);
1824 EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1825 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1826 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1827 http_request_.headers["X-Upload-Content-Length"]);
1828 EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
1830 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1831 EXPECT_EQ("/upload/drive/v2/files/resource_id?"
1832 "uploadType=resumable&setModifiedDate=true",
1833 http_request_.relative_url);
1834 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1835 EXPECT_TRUE(http_request_.has_content);
1836 EXPECT_EQ("{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
1837 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
1838 "\"parents\":[{\"id\":\"new_parent_resource_id\","
1839 "\"kind\":\"drive#fileLink\"}],"
1840 "\"title\":\"new file title\"}",
1841 http_request_.content);
1844 TEST_F(DriveApiRequestsTest, DownloadFileRequest) {
1845 const base::FilePath kDownloadedFilePath =
1846 temp_dir_.path().AppendASCII("cache_file");
1847 const std::string kTestId("dummyId");
1849 DriveApiErrorCode result_code = DRIVE_OTHER_ERROR;
1850 base::FilePath temp_file;
1852 base::RunLoop run_loop;
1853 drive::DownloadFileRequest* request = new drive::DownloadFileRequest(
1854 request_sender_.get(),
1855 *url_generator_,
1856 kTestId,
1857 kDownloadedFilePath,
1858 test_util::CreateQuitCallback(
1859 &run_loop,
1860 test_util::CreateCopyResultCallback(&result_code, &temp_file)),
1861 GetContentCallback(),
1862 ProgressCallback());
1863 request_sender_->StartRequestWithAuthRetry(request);
1864 run_loop.Run();
1867 std::string contents;
1868 base::ReadFileToString(temp_file, &contents);
1869 base::DeleteFile(temp_file, false);
1871 EXPECT_EQ(HTTP_SUCCESS, result_code);
1872 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
1873 EXPECT_EQ(kTestDownloadPathPrefix + kTestId, http_request_.relative_url);
1874 EXPECT_EQ(kDownloadedFilePath, temp_file);
1876 const std::string expected_contents = kTestId + kTestId + kTestId;
1877 EXPECT_EQ(expected_contents, contents);
1880 TEST_F(DriveApiRequestsTest, DownloadFileRequest_GetContentCallback) {
1881 const base::FilePath kDownloadedFilePath =
1882 temp_dir_.path().AppendASCII("cache_file");
1883 const std::string kTestId("dummyId");
1885 DriveApiErrorCode result_code = DRIVE_OTHER_ERROR;
1886 base::FilePath temp_file;
1887 std::string contents;
1889 base::RunLoop run_loop;
1890 drive::DownloadFileRequest* request = new drive::DownloadFileRequest(
1891 request_sender_.get(),
1892 *url_generator_,
1893 kTestId,
1894 kDownloadedFilePath,
1895 test_util::CreateQuitCallback(
1896 &run_loop,
1897 test_util::CreateCopyResultCallback(&result_code, &temp_file)),
1898 base::Bind(&AppendContent, &contents),
1899 ProgressCallback());
1900 request_sender_->StartRequestWithAuthRetry(request);
1901 run_loop.Run();
1904 base::DeleteFile(temp_file, false);
1906 EXPECT_EQ(HTTP_SUCCESS, result_code);
1907 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
1908 EXPECT_EQ(kTestDownloadPathPrefix + kTestId, http_request_.relative_url);
1909 EXPECT_EQ(kDownloadedFilePath, temp_file);
1911 const std::string expected_contents = kTestId + kTestId + kTestId;
1912 EXPECT_EQ(expected_contents, contents);
1915 TEST_F(DriveApiRequestsTest, PermissionsInsertRequest) {
1916 expected_content_type_ = "application/json";
1917 expected_content_ = kTestPermissionResponse;
1919 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1921 // Add comment permission to the user "user@example.com".
1923 base::RunLoop run_loop;
1924 drive::PermissionsInsertRequest* request =
1925 new drive::PermissionsInsertRequest(
1926 request_sender_.get(),
1927 *url_generator_,
1928 test_util::CreateQuitCallback(
1929 &run_loop,
1930 test_util::CreateCopyResultCallback(&error)));
1931 request->set_id("resource_id");
1932 request->set_role(drive::PERMISSION_ROLE_COMMENTER);
1933 request->set_type(drive::PERMISSION_TYPE_USER);
1934 request->set_value("user@example.com");
1935 request_sender_->StartRequestWithAuthRetry(request);
1936 run_loop.Run();
1939 EXPECT_EQ(HTTP_SUCCESS, error);
1940 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1941 EXPECT_EQ("/drive/v2/files/resource_id/permissions",
1942 http_request_.relative_url);
1943 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1945 scoped_ptr<base::Value> expected(base::JSONReader::DeprecatedRead(
1946 "{\"additionalRoles\":[\"commenter\"], \"role\":\"reader\", "
1947 "\"type\":\"user\",\"value\":\"user@example.com\"}"));
1948 ASSERT_TRUE(expected);
1950 scoped_ptr<base::Value> result =
1951 base::JSONReader::Read(http_request_.content);
1952 EXPECT_TRUE(http_request_.has_content);
1953 EXPECT_TRUE(base::Value::Equals(expected.get(), result.get()));
1955 // Add "can edit" permission to users in "example.com".
1956 error = DRIVE_OTHER_ERROR;
1958 base::RunLoop run_loop;
1959 drive::PermissionsInsertRequest* request =
1960 new drive::PermissionsInsertRequest(
1961 request_sender_.get(),
1962 *url_generator_,
1963 test_util::CreateQuitCallback(
1964 &run_loop,
1965 test_util::CreateCopyResultCallback(&error)));
1966 request->set_id("resource_id2");
1967 request->set_role(drive::PERMISSION_ROLE_WRITER);
1968 request->set_type(drive::PERMISSION_TYPE_DOMAIN);
1969 request->set_value("example.com");
1970 request_sender_->StartRequestWithAuthRetry(request);
1971 run_loop.Run();
1974 EXPECT_EQ(HTTP_SUCCESS, error);
1975 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1976 EXPECT_EQ("/drive/v2/files/resource_id2/permissions",
1977 http_request_.relative_url);
1978 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1980 expected.reset(base::JSONReader::DeprecatedRead(
1981 "{\"role\":\"writer\", \"type\":\"domain\",\"value\":\"example.com\"}"));
1982 ASSERT_TRUE(expected);
1984 result.reset(base::JSONReader::DeprecatedRead(http_request_.content));
1985 EXPECT_TRUE(http_request_.has_content);
1986 EXPECT_TRUE(base::Value::Equals(expected.get(), result.get()));
1989 TEST_F(DriveApiRequestsTest, BatchUploadRequest) {
1990 // Preapre constants.
1991 const char kTestContentType[] = "text/plain";
1992 const std::string kTestContent(10, 'a');
1993 const base::FilePath kTestFilePath =
1994 temp_dir_.path().AppendASCII("upload_file.txt");
1995 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1997 // Create batch request.
1998 drive::BatchUploadRequest* const request =
1999 new drive::BatchUploadRequest(request_sender_.get(), *url_generator_);
2000 request->SetBoundaryForTesting("OUTERBOUNDARY");
2001 request_sender_->StartRequestWithAuthRetry(request);
2003 // Create child request.
2004 DriveApiErrorCode errors[] = {DRIVE_OTHER_ERROR, DRIVE_OTHER_ERROR};
2005 scoped_ptr<FileResource> file_resources[2];
2006 base::RunLoop run_loop[2];
2007 for (int i = 0; i < 2; ++i) {
2008 const FileResourceCallback callback = test_util::CreateQuitCallback(
2009 &run_loop[i],
2010 test_util::CreateCopyResultCallback(&errors[i], &file_resources[i]));
2011 drive::MultipartUploadNewFileDelegate* const child_request =
2012 new drive::MultipartUploadNewFileDelegate(
2013 request_sender_->blocking_task_runner(),
2014 base::StringPrintf("new file title %d", i),
2015 "parent_resource_id", kTestContentType, kTestContent.size(),
2016 base::Time(), base::Time(), kTestFilePath, drive::Properties(),
2017 *url_generator_, callback, ProgressCallback());
2018 child_request->SetBoundaryForTesting("INNERBOUNDARY");
2019 request->AddRequest(child_request);
2021 request->Commit();
2022 run_loop[0].Run();
2023 run_loop[1].Run();
2025 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
2026 EXPECT_EQ("batch", http_request_.headers["X-Goog-Upload-Protocol"]);
2027 EXPECT_EQ("multipart/mixed; boundary=OUTERBOUNDARY",
2028 http_request_.headers["Content-Type"]);
2029 EXPECT_EQ(
2030 "--OUTERBOUNDARY\n"
2031 "Content-Type: application/http\n"
2032 "\n"
2033 "POST /upload/drive/v2/files HTTP/1.1\n"
2034 "Host: 127.0.0.1\n"
2035 "X-Goog-Upload-Protocol: multipart\n"
2036 "Content-Type: multipart/related; boundary=INNERBOUNDARY\n"
2037 "\n"
2038 "--INNERBOUNDARY\n"
2039 "Content-Type: application/json\n"
2040 "\n"
2041 "{\"parents\":[{\"id\":\"parent_resource_id\","
2042 "\"kind\":\"drive#fileLink\"}],\"title\":\"new file title 0\"}\n"
2043 "--INNERBOUNDARY\n"
2044 "Content-Type: text/plain\n"
2045 "\n"
2046 "aaaaaaaaaa\n"
2047 "--INNERBOUNDARY--\n"
2048 "--OUTERBOUNDARY\n"
2049 "Content-Type: application/http\n"
2050 "\n"
2051 "POST /upload/drive/v2/files HTTP/1.1\n"
2052 "Host: 127.0.0.1\n"
2053 "X-Goog-Upload-Protocol: multipart\n"
2054 "Content-Type: multipart/related; boundary=INNERBOUNDARY\n"
2055 "\n"
2056 "--INNERBOUNDARY\n"
2057 "Content-Type: application/json\n"
2058 "\n"
2059 "{\"parents\":[{\"id\":\"parent_resource_id\","
2060 "\"kind\":\"drive#fileLink\"}],\"title\":\"new file title 1\"}\n"
2061 "--INNERBOUNDARY\n"
2062 "Content-Type: text/plain\n"
2063 "\n"
2064 "aaaaaaaaaa\n"
2065 "--INNERBOUNDARY--\n"
2066 "--OUTERBOUNDARY--",
2067 http_request_.content);
2068 EXPECT_EQ(HTTP_SUCCESS, errors[0]);
2069 ASSERT_TRUE(file_resources[0]);
2070 EXPECT_EQ("file_id_1", file_resources[0]->file_id());
2071 ASSERT_FALSE(file_resources[1]);
2072 EXPECT_EQ(HTTP_SERVICE_UNAVAILABLE, errors[1]);
2075 TEST_F(DriveApiRequestsTest, EmptyBatchUploadRequest) {
2076 drive::BatchUploadRequest* const request =
2077 new drive::BatchUploadRequest(request_sender_.get(), *url_generator_);
2078 base::WeakPtr<drive::BatchUploadRequest> weak_ptr =
2079 request->GetWeakPtrAsBatchUploadRequest();
2080 request->Commit();
2081 ASSERT_FALSE(weak_ptr.get());
2084 TEST_F(DriveApiRequestsTest, BatchUploadRequestWithBodyIncludingZero) {
2085 // Create batch request.
2086 drive::BatchUploadRequest* const request =
2087 new drive::BatchUploadRequest(request_sender_.get(), *url_generator_);
2088 request->SetBoundaryForTesting("OUTERBOUNDARY");
2089 request_sender_->StartRequestWithAuthRetry(request);
2091 // Create child request.
2093 base::RunLoop loop;
2094 TestBatchableDelegate* const child_request = new TestBatchableDelegate(
2095 GURL("http://example.com/test"), "application/binary",
2096 std::string("Apple\0Orange\0", 13), loop.QuitClosure());
2097 request->AddRequest(child_request);
2098 request->Commit();
2099 loop.Run();
2102 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
2103 EXPECT_EQ("batch", http_request_.headers["X-Goog-Upload-Protocol"]);
2104 EXPECT_EQ("multipart/mixed; boundary=OUTERBOUNDARY",
2105 http_request_.headers["Content-Type"]);
2106 EXPECT_EQ(
2107 "--OUTERBOUNDARY\n"
2108 "Content-Type: application/http\n"
2109 "\n"
2110 "PUT /test HTTP/1.1\n"
2111 "Host: 127.0.0.1\n"
2112 "X-Goog-Upload-Protocol: multipart\n"
2113 "Content-Type: application/binary\n"
2114 "\n" +
2115 std::string("Apple\0Orange\0", 13) +
2116 "\n"
2117 "--OUTERBOUNDARY--",
2118 http_request_.content);
2121 TEST_F(DriveApiRequestsTest, BatchUploadRequestProgress) {
2122 // Create batch request.
2123 drive::BatchUploadRequest* const request =
2124 new drive::BatchUploadRequest(request_sender_.get(), *url_generator_);
2125 TestBatchableDelegate* requests[] = {
2126 new TestBatchableDelegate(GURL("http://example.com/test"),
2127 "application/binary", std::string(100, 'a'),
2128 base::Bind(&EmptyClosure)),
2129 new TestBatchableDelegate(GURL("http://example.com/test"),
2130 "application/binary", std::string(50, 'b'),
2131 base::Bind(&EmptyClosure)),
2132 new TestBatchableDelegate(GURL("http://example.com/test"),
2133 "application/binary", std::string(0, 'c'),
2134 base::Bind(&EmptyClosure))};
2135 const size_t kExpectedUploadDataPosition[] = {208, 517, 776};
2136 const size_t kExpectedUploadDataSize = 851;
2137 request->AddRequest(requests[0]);
2138 request->AddRequest(requests[1]);
2139 request->AddRequest(requests[2]);
2140 request->Commit();
2141 request->Prepare(base::Bind(&EmptyPreapreCallback));
2143 request->OnURLFetchUploadProgress(nullptr, 0, kExpectedUploadDataSize);
2144 request->OnURLFetchUploadProgress(nullptr, 150, kExpectedUploadDataSize);
2145 EXPECT_EQ(0u, requests[0]->progress_values().size());
2146 EXPECT_EQ(0u, requests[1]->progress_values().size());
2147 EXPECT_EQ(0u, requests[2]->progress_values().size());
2148 request->OnURLFetchUploadProgress(nullptr, kExpectedUploadDataPosition[0],
2149 kExpectedUploadDataSize);
2150 EXPECT_EQ(1u, requests[0]->progress_values().size());
2151 EXPECT_EQ(0u, requests[1]->progress_values().size());
2152 EXPECT_EQ(0u, requests[2]->progress_values().size());
2153 request->OnURLFetchUploadProgress(
2154 nullptr, kExpectedUploadDataPosition[0] + 50, kExpectedUploadDataSize);
2155 EXPECT_EQ(2u, requests[0]->progress_values().size());
2156 EXPECT_EQ(0u, requests[1]->progress_values().size());
2157 EXPECT_EQ(0u, requests[2]->progress_values().size());
2158 request->OnURLFetchUploadProgress(
2159 nullptr, kExpectedUploadDataPosition[1] + 20, kExpectedUploadDataSize);
2160 EXPECT_EQ(3u, requests[0]->progress_values().size());
2161 EXPECT_EQ(1u, requests[1]->progress_values().size());
2162 EXPECT_EQ(0u, requests[2]->progress_values().size());
2163 request->OnURLFetchUploadProgress(nullptr, kExpectedUploadDataPosition[2],
2164 kExpectedUploadDataSize);
2165 EXPECT_EQ(3u, requests[0]->progress_values().size());
2166 EXPECT_EQ(2u, requests[1]->progress_values().size());
2167 EXPECT_EQ(1u, requests[2]->progress_values().size());
2168 request->OnURLFetchUploadProgress(nullptr, kExpectedUploadDataSize,
2169 kExpectedUploadDataSize);
2170 ASSERT_EQ(3u, requests[0]->progress_values().size());
2171 EXPECT_EQ(0, requests[0]->progress_values()[0]);
2172 EXPECT_EQ(50, requests[0]->progress_values()[1]);
2173 EXPECT_EQ(100, requests[0]->progress_values()[2]);
2174 ASSERT_EQ(2u, requests[1]->progress_values().size());
2175 EXPECT_EQ(20, requests[1]->progress_values()[0]);
2176 EXPECT_EQ(50, requests[1]->progress_values()[1]);
2177 ASSERT_EQ(1u, requests[2]->progress_values().size());
2178 EXPECT_EQ(0, requests[2]->progress_values()[0]);
2180 request->Cancel();
2183 TEST(ParseMultipartResponseTest, Empty) {
2184 std::vector<drive::MultipartHttpResponse> parts;
2185 EXPECT_FALSE(drive::ParseMultipartResponse(
2186 "multipart/mixed; boundary=BOUNDARY", "", &parts));
2187 EXPECT_FALSE(drive::ParseMultipartResponse("multipart/mixed; boundary=",
2188 "CONTENT", &parts));
2191 TEST(ParseMultipartResponseTest, Basic) {
2192 std::vector<drive::MultipartHttpResponse> parts;
2193 ASSERT_TRUE(
2194 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2195 "--BOUNDARY\r\n"
2196 "Content-Type: application/http\r\n"
2197 "\r\n"
2198 "HTTP/1.1 200 OK\r\n"
2199 "Header: value\r\n"
2200 "\r\n"
2201 "First line\r\n"
2202 "Second line\r\n"
2203 "--BOUNDARY\r\n"
2204 "Content-Type: application/http\r\n"
2205 "\r\n"
2206 "HTTP/1.1 404 Not Found\r\n"
2207 "Header: value\r\n"
2208 "--BOUNDARY--",
2209 &parts));
2210 ASSERT_EQ(2u, parts.size());
2211 EXPECT_EQ(HTTP_SUCCESS, parts[0].code);
2212 EXPECT_EQ("First line\r\nSecond line", parts[0].body);
2213 EXPECT_EQ(HTTP_NOT_FOUND, parts[1].code);
2214 EXPECT_EQ("", parts[1].body);
2217 TEST(ParseMultipartResponseTest, InvalidStatusLine) {
2218 std::vector<drive::MultipartHttpResponse> parts;
2219 ASSERT_TRUE(
2220 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2221 "--BOUNDARY\r\n"
2222 "Content-Type: application/http\r\n"
2223 "\r\n"
2224 "InvalidStatusLine 200 \r\n"
2225 "Header: value\r\n"
2226 "\r\n"
2227 "{}\r\n"
2228 "--BOUNDARY--",
2229 &parts));
2230 ASSERT_EQ(1u, parts.size());
2231 EXPECT_EQ(DRIVE_PARSE_ERROR, parts[0].code);
2232 EXPECT_EQ("{}", parts[0].body);
2235 TEST(ParseMultipartResponseTest, BoundaryInTheBodyAndPreamble) {
2236 std::vector<drive::MultipartHttpResponse> parts;
2237 ASSERT_TRUE(
2238 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2239 "BOUNDARY\r\n"
2240 "PREUMBLE\r\n"
2241 "--BOUNDARY\r\n"
2242 "Content-Type: application/http\r\n"
2243 "\r\n"
2244 "HTTP/1.1 200 OK\r\n"
2245 "Header: value\r\n"
2246 "\r\n"
2247 "{--BOUNDARY}\r\n"
2248 "--BOUNDARY--",
2249 &parts));
2250 ASSERT_EQ(1u, parts.size());
2251 EXPECT_EQ(HTTP_SUCCESS, parts[0].code);
2252 EXPECT_EQ("{--BOUNDARY}", parts[0].body);
2255 TEST(ParseMultipartResponseTest, QuatedBoundary) {
2256 std::vector<drive::MultipartHttpResponse> parts;
2257 ASSERT_TRUE(
2258 drive::ParseMultipartResponse("multipart/mixed; boundary=\"BOUNDARY\"",
2259 "--BOUNDARY\r\n"
2260 "Content-Type: application/http\r\n"
2261 "\r\n"
2262 "HTTP/1.1 200 OK\r\n"
2263 "Header: value\r\n"
2264 "\r\n"
2265 "BODY\r\n"
2266 "--BOUNDARY--",
2267 &parts));
2268 ASSERT_EQ(1u, parts.size());
2269 EXPECT_EQ(HTTP_SUCCESS, parts[0].code);
2270 EXPECT_EQ("BODY", parts[0].body);
2273 TEST(ParseMultipartResponseTest, BoundaryWithTransportPadding) {
2274 std::vector<drive::MultipartHttpResponse> parts;
2275 ASSERT_TRUE(
2276 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2277 "--BOUNDARY \t\r\n"
2278 "Content-Type: application/http\r\n"
2279 "\r\n"
2280 "HTTP/1.1 200 OK\r\n"
2281 "Header: value\r\n"
2282 "\r\n"
2283 "BODY\r\n"
2284 "--BOUNDARY-- \t",
2285 &parts));
2286 ASSERT_EQ(1u, parts.size());
2287 EXPECT_EQ(HTTP_SUCCESS, parts[0].code);
2288 EXPECT_EQ("BODY", parts[0].body);
2290 } // namespace google_apis