Always open bookmarks in incognito mode in the foreground
[chromium-blink-merge.git] / google_apis / drive / drive_api_requests_unittest.cc
blob5e11fbd9f8de77494f2913514c2f3aeb6490d8ad
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_.message_loop_proxy());
125 request_sender_.reset(new RequestSender(new DummyAuthService,
126 request_context_getter_.get(),
127 message_loop_.message_loop_proxy(),
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 503 Service Unavailable\r\n"
483 "Content-Type: application/json; charset=UTF-8\r\n"
484 "\r\n"
485 "{}\r\n"
486 "\r\n"
487 "--BOUNDARY--\r\n");
488 return response.Pass();
491 // These are for the current upload file status.
492 int64 received_bytes_;
493 int64 content_length_;
496 TEST_F(DriveApiRequestsTest, DriveApiDataRequest_Fields) {
497 // Make sure that "fields" query param is supported by using its subclass,
498 // AboutGetRequest.
500 // Set an expected data file containing valid result.
501 expected_data_file_path_ = test_util::GetTestFilePath(
502 "drive/about.json");
504 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
505 scoped_ptr<AboutResource> about_resource;
508 base::RunLoop run_loop;
509 drive::AboutGetRequest* request = new drive::AboutGetRequest(
510 request_sender_.get(),
511 *url_generator_,
512 test_util::CreateQuitCallback(
513 &run_loop,
514 test_util::CreateCopyResultCallback(&error, &about_resource)));
515 request->set_fields("kind,quotaBytesTotal,quotaBytesUsedAggregate,"
516 "largestChangeId,rootFolderId");
517 request_sender_->StartRequestWithRetry(request);
518 run_loop.Run();
521 EXPECT_EQ(HTTP_SUCCESS, error);
522 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
523 EXPECT_EQ("/drive/v2/about?"
524 "fields=kind%2CquotaBytesTotal%2CquotaBytesUsedAggregate%2C"
525 "largestChangeId%2CrootFolderId",
526 http_request_.relative_url);
528 scoped_ptr<AboutResource> expected(
529 AboutResource::CreateFrom(
530 *test_util::LoadJSONFile("drive/about.json")));
531 ASSERT_TRUE(about_resource.get());
532 EXPECT_EQ(expected->largest_change_id(), about_resource->largest_change_id());
533 EXPECT_EQ(expected->quota_bytes_total(), about_resource->quota_bytes_total());
534 EXPECT_EQ(expected->quota_bytes_used_aggregate(),
535 about_resource->quota_bytes_used_aggregate());
536 EXPECT_EQ(expected->root_folder_id(), about_resource->root_folder_id());
539 TEST_F(DriveApiRequestsTest, FilesInsertRequest) {
540 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
541 const base::Time::Exploded kLastViewedByMeDate =
542 {2013, 7, 0, 19, 15, 59, 13, 123};
544 // Set an expected data file containing the directory's entry data.
545 expected_data_file_path_ =
546 test_util::GetTestFilePath("drive/directory_entry.json");
548 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
549 scoped_ptr<FileResource> file_resource;
551 // Create "new directory" in the root directory.
553 base::RunLoop run_loop;
554 drive::FilesInsertRequest* request = new drive::FilesInsertRequest(
555 request_sender_.get(),
556 *url_generator_,
557 test_util::CreateQuitCallback(
558 &run_loop,
559 test_util::CreateCopyResultCallback(&error, &file_resource)));
560 request->set_last_viewed_by_me_date(
561 base::Time::FromUTCExploded(kLastViewedByMeDate));
562 request->set_mime_type("application/vnd.google-apps.folder");
563 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
564 request->add_parent("root");
565 request->set_title("new directory");
566 request->set_properties(testing_properties_);
567 request_sender_->StartRequestWithRetry(request);
568 run_loop.Run();
571 EXPECT_EQ(HTTP_SUCCESS, error);
572 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
573 EXPECT_EQ("/drive/v2/files", http_request_.relative_url);
574 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
576 EXPECT_TRUE(http_request_.has_content);
577 EXPECT_EQ(
578 "{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
579 "\"mimeType\":\"application/vnd.google-apps.folder\","
580 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
581 "\"parents\":[{\"id\":\"root\"}],"
582 "\"properties\":["
583 "{\"key\":\"key1\",\"value\":\"value1\",\"visibility\":\"PRIVATE\"},"
584 "{\"key\":\"key2\",\"value\":\"value2\",\"visibility\":\"PUBLIC\"}],"
585 "\"title\":\"new directory\"}",
586 http_request_.content);
588 scoped_ptr<FileResource> expected(
589 FileResource::CreateFrom(
590 *test_util::LoadJSONFile("drive/directory_entry.json")));
592 // Sanity check.
593 ASSERT_TRUE(file_resource.get());
595 EXPECT_EQ(expected->file_id(), file_resource->file_id());
596 EXPECT_EQ(expected->title(), file_resource->title());
597 EXPECT_EQ(expected->mime_type(), file_resource->mime_type());
598 EXPECT_EQ(expected->parents().size(), file_resource->parents().size());
601 TEST_F(DriveApiRequestsTest, FilesPatchRequest) {
602 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
603 const base::Time::Exploded kLastViewedByMeDate =
604 {2013, 7, 0, 19, 15, 59, 13, 123};
606 // Set an expected data file containing valid result.
607 expected_data_file_path_ =
608 test_util::GetTestFilePath("drive/file_entry.json");
610 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
611 scoped_ptr<FileResource> file_resource;
614 base::RunLoop run_loop;
615 drive::FilesPatchRequest* request = new drive::FilesPatchRequest(
616 request_sender_.get(),
617 *url_generator_,
618 test_util::CreateQuitCallback(
619 &run_loop,
620 test_util::CreateCopyResultCallback(&error, &file_resource)));
621 request->set_file_id("resource_id");
622 request->set_set_modified_date(true);
623 request->set_update_viewed_date(false);
625 request->set_title("new title");
626 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
627 request->set_last_viewed_by_me_date(
628 base::Time::FromUTCExploded(kLastViewedByMeDate));
629 request->add_parent("parent_resource_id");
631 request->set_properties(testing_properties_);
632 request_sender_->StartRequestWithRetry(request);
633 run_loop.Run();
636 EXPECT_EQ(HTTP_SUCCESS, error);
637 EXPECT_EQ(net::test_server::METHOD_PATCH, http_request_.method);
638 EXPECT_EQ("/drive/v2/files/resource_id"
639 "?setModifiedDate=true&updateViewedDate=false",
640 http_request_.relative_url);
642 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
643 EXPECT_TRUE(http_request_.has_content);
644 EXPECT_EQ(
645 "{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
646 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
647 "\"parents\":[{\"id\":\"parent_resource_id\"}],"
648 "\"properties\":["
649 "{\"key\":\"key1\",\"value\":\"value1\",\"visibility\":\"PRIVATE\"},"
650 "{\"key\":\"key2\",\"value\":\"value2\",\"visibility\":\"PUBLIC\"}],"
651 "\"title\":\"new title\"}",
652 http_request_.content);
653 EXPECT_TRUE(file_resource);
656 TEST_F(DriveApiRequestsTest, AboutGetRequest_ValidJson) {
657 // Set an expected data file containing valid result.
658 expected_data_file_path_ = test_util::GetTestFilePath(
659 "drive/about.json");
661 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
662 scoped_ptr<AboutResource> about_resource;
665 base::RunLoop run_loop;
666 drive::AboutGetRequest* request = new drive::AboutGetRequest(
667 request_sender_.get(),
668 *url_generator_,
669 test_util::CreateQuitCallback(
670 &run_loop,
671 test_util::CreateCopyResultCallback(&error, &about_resource)));
672 request_sender_->StartRequestWithRetry(request);
673 run_loop.Run();
676 EXPECT_EQ(HTTP_SUCCESS, error);
677 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
678 EXPECT_EQ("/drive/v2/about", http_request_.relative_url);
680 scoped_ptr<AboutResource> expected(
681 AboutResource::CreateFrom(
682 *test_util::LoadJSONFile("drive/about.json")));
683 ASSERT_TRUE(about_resource.get());
684 EXPECT_EQ(expected->largest_change_id(), about_resource->largest_change_id());
685 EXPECT_EQ(expected->quota_bytes_total(), about_resource->quota_bytes_total());
686 EXPECT_EQ(expected->quota_bytes_used_aggregate(),
687 about_resource->quota_bytes_used_aggregate());
688 EXPECT_EQ(expected->root_folder_id(), about_resource->root_folder_id());
691 TEST_F(DriveApiRequestsTest, AboutGetRequest_InvalidJson) {
692 // Set an expected data file containing invalid result.
693 expected_data_file_path_ = test_util::GetTestFilePath(
694 "drive/testfile.txt");
696 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
697 scoped_ptr<AboutResource> about_resource;
700 base::RunLoop run_loop;
701 drive::AboutGetRequest* request = new drive::AboutGetRequest(
702 request_sender_.get(),
703 *url_generator_,
704 test_util::CreateQuitCallback(
705 &run_loop,
706 test_util::CreateCopyResultCallback(&error, &about_resource)));
707 request_sender_->StartRequestWithRetry(request);
708 run_loop.Run();
711 // "parse error" should be returned, and the about resource should be NULL.
712 EXPECT_EQ(DRIVE_PARSE_ERROR, error);
713 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
714 EXPECT_EQ("/drive/v2/about", http_request_.relative_url);
715 EXPECT_FALSE(about_resource);
718 TEST_F(DriveApiRequestsTest, AppsListRequest) {
719 // Set an expected data file containing valid result.
720 expected_data_file_path_ = test_util::GetTestFilePath(
721 "drive/applist.json");
723 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
724 scoped_ptr<AppList> app_list;
727 base::RunLoop run_loop;
728 drive::AppsListRequest* request = new drive::AppsListRequest(
729 request_sender_.get(),
730 *url_generator_,
731 false, // use_internal_endpoint
732 test_util::CreateQuitCallback(
733 &run_loop,
734 test_util::CreateCopyResultCallback(&error, &app_list)));
735 request_sender_->StartRequestWithRetry(request);
736 run_loop.Run();
739 EXPECT_EQ(HTTP_SUCCESS, error);
740 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
741 EXPECT_EQ("/drive/v2/apps", http_request_.relative_url);
742 EXPECT_TRUE(app_list);
745 TEST_F(DriveApiRequestsTest, ChangesListRequest) {
746 // Set an expected data file containing valid result.
747 expected_data_file_path_ = test_util::GetTestFilePath(
748 "drive/changelist.json");
750 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
751 scoped_ptr<ChangeList> result;
754 base::RunLoop run_loop;
755 drive::ChangesListRequest* request = new drive::ChangesListRequest(
756 request_sender_.get(), *url_generator_,
757 test_util::CreateQuitCallback(
758 &run_loop,
759 test_util::CreateCopyResultCallback(&error, &result)));
760 request->set_include_deleted(true);
761 request->set_start_change_id(100);
762 request->set_max_results(500);
763 request_sender_->StartRequestWithRetry(request);
764 run_loop.Run();
767 EXPECT_EQ(HTTP_SUCCESS, error);
768 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
769 EXPECT_EQ("/drive/v2/changes?maxResults=500&startChangeId=100",
770 http_request_.relative_url);
771 EXPECT_TRUE(result);
774 TEST_F(DriveApiRequestsTest, ChangesListNextPageRequest) {
775 // Set an expected data file containing valid result.
776 expected_data_file_path_ = test_util::GetTestFilePath(
777 "drive/changelist.json");
779 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
780 scoped_ptr<ChangeList> result;
783 base::RunLoop run_loop;
784 drive::ChangesListNextPageRequest* request =
785 new drive::ChangesListNextPageRequest(
786 request_sender_.get(),
787 test_util::CreateQuitCallback(
788 &run_loop,
789 test_util::CreateCopyResultCallback(&error, &result)));
790 request->set_next_link(test_server_.GetURL("/continue/get/change/list"));
791 request_sender_->StartRequestWithRetry(request);
792 run_loop.Run();
795 EXPECT_EQ(HTTP_SUCCESS, error);
796 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
797 EXPECT_EQ("/continue/get/change/list", http_request_.relative_url);
798 EXPECT_TRUE(result);
801 TEST_F(DriveApiRequestsTest, FilesCopyRequest) {
802 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
804 // Set an expected data file containing the dummy file entry data.
805 // It'd be returned if we copy a file.
806 expected_data_file_path_ =
807 test_util::GetTestFilePath("drive/file_entry.json");
809 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
810 scoped_ptr<FileResource> file_resource;
812 // Copy the file to a new file named "new title".
814 base::RunLoop run_loop;
815 drive::FilesCopyRequest* request = new drive::FilesCopyRequest(
816 request_sender_.get(),
817 *url_generator_,
818 test_util::CreateQuitCallback(
819 &run_loop,
820 test_util::CreateCopyResultCallback(&error, &file_resource)));
821 request->set_file_id("resource_id");
822 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
823 request->add_parent("parent_resource_id");
824 request->set_title("new title");
825 request_sender_->StartRequestWithRetry(request);
826 run_loop.Run();
829 EXPECT_EQ(HTTP_SUCCESS, error);
830 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
831 EXPECT_EQ("/drive/v2/files/resource_id/copy", http_request_.relative_url);
832 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
834 EXPECT_TRUE(http_request_.has_content);
835 EXPECT_EQ(
836 "{\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
837 "\"parents\":[{\"id\":\"parent_resource_id\"}],\"title\":\"new title\"}",
838 http_request_.content);
839 EXPECT_TRUE(file_resource);
842 TEST_F(DriveApiRequestsTest, FilesCopyRequest_EmptyParentResourceId) {
843 // Set an expected data file containing the dummy file entry data.
844 // It'd be returned if we copy a file.
845 expected_data_file_path_ =
846 test_util::GetTestFilePath("drive/file_entry.json");
848 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
849 scoped_ptr<FileResource> file_resource;
851 // Copy the file to a new file named "new title".
853 base::RunLoop run_loop;
854 drive::FilesCopyRequest* request = new drive::FilesCopyRequest(
855 request_sender_.get(),
856 *url_generator_,
857 test_util::CreateQuitCallback(
858 &run_loop,
859 test_util::CreateCopyResultCallback(&error, &file_resource)));
860 request->set_file_id("resource_id");
861 request->set_title("new title");
862 request_sender_->StartRequestWithRetry(request);
863 run_loop.Run();
866 EXPECT_EQ(HTTP_SUCCESS, error);
867 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
868 EXPECT_EQ("/drive/v2/files/resource_id/copy", http_request_.relative_url);
869 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
871 EXPECT_TRUE(http_request_.has_content);
872 EXPECT_EQ("{\"title\":\"new title\"}", http_request_.content);
873 EXPECT_TRUE(file_resource);
876 TEST_F(DriveApiRequestsTest, FilesListRequest) {
877 // Set an expected data file containing valid result.
878 expected_data_file_path_ = test_util::GetTestFilePath(
879 "drive/filelist.json");
881 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
882 scoped_ptr<FileList> result;
885 base::RunLoop run_loop;
886 drive::FilesListRequest* request = new drive::FilesListRequest(
887 request_sender_.get(), *url_generator_,
888 test_util::CreateQuitCallback(
889 &run_loop,
890 test_util::CreateCopyResultCallback(&error, &result)));
891 request->set_max_results(50);
892 request->set_q("\"abcde\" in parents");
893 request_sender_->StartRequestWithRetry(request);
894 run_loop.Run();
897 EXPECT_EQ(HTTP_SUCCESS, error);
898 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
899 EXPECT_EQ("/drive/v2/files?maxResults=50&q=%22abcde%22+in+parents",
900 http_request_.relative_url);
901 EXPECT_TRUE(result);
904 TEST_F(DriveApiRequestsTest, FilesListNextPageRequest) {
905 // Set an expected data file containing valid result.
906 expected_data_file_path_ = test_util::GetTestFilePath(
907 "drive/filelist.json");
909 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
910 scoped_ptr<FileList> result;
913 base::RunLoop run_loop;
914 drive::FilesListNextPageRequest* request =
915 new drive::FilesListNextPageRequest(
916 request_sender_.get(),
917 test_util::CreateQuitCallback(
918 &run_loop,
919 test_util::CreateCopyResultCallback(&error, &result)));
920 request->set_next_link(test_server_.GetURL("/continue/get/file/list"));
921 request_sender_->StartRequestWithRetry(request);
922 run_loop.Run();
925 EXPECT_EQ(HTTP_SUCCESS, error);
926 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
927 EXPECT_EQ("/continue/get/file/list", http_request_.relative_url);
928 EXPECT_TRUE(result);
931 TEST_F(DriveApiRequestsTest, FilesDeleteRequest) {
932 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
934 // Delete a resource with the given resource id.
936 base::RunLoop run_loop;
937 drive::FilesDeleteRequest* request = new drive::FilesDeleteRequest(
938 request_sender_.get(),
939 *url_generator_,
940 test_util::CreateQuitCallback(
941 &run_loop, test_util::CreateCopyResultCallback(&error)));
942 request->set_file_id("resource_id");
943 request->set_etag(kTestETag);
944 request_sender_->StartRequestWithRetry(request);
945 run_loop.Run();
948 EXPECT_EQ(HTTP_NO_CONTENT, error);
949 EXPECT_EQ(net::test_server::METHOD_DELETE, http_request_.method);
950 EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
951 EXPECT_EQ("/drive/v2/files/resource_id", http_request_.relative_url);
952 EXPECT_FALSE(http_request_.has_content);
955 TEST_F(DriveApiRequestsTest, FilesTrashRequest) {
956 // Set data for the expected result. Directory entry should be returned
957 // if the trashing entry is a directory, so using it here should be fine.
958 expected_data_file_path_ =
959 test_util::GetTestFilePath("drive/directory_entry.json");
961 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
962 scoped_ptr<FileResource> file_resource;
964 // Trash a resource with the given resource id.
966 base::RunLoop run_loop;
967 drive::FilesTrashRequest* request = new drive::FilesTrashRequest(
968 request_sender_.get(),
969 *url_generator_,
970 test_util::CreateQuitCallback(
971 &run_loop,
972 test_util::CreateCopyResultCallback(&error, &file_resource)));
973 request->set_file_id("resource_id");
974 request_sender_->StartRequestWithRetry(request);
975 run_loop.Run();
978 EXPECT_EQ(HTTP_SUCCESS, error);
979 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
980 EXPECT_EQ("/drive/v2/files/resource_id/trash", http_request_.relative_url);
981 EXPECT_TRUE(http_request_.has_content);
982 EXPECT_TRUE(http_request_.content.empty());
985 TEST_F(DriveApiRequestsTest, ChildrenInsertRequest) {
986 // Set an expected data file containing the children entry.
987 expected_content_type_ = "application/json";
988 expected_content_ = kTestChildrenResponse;
990 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
992 // Add a resource with "resource_id" to a directory with
993 // "parent_resource_id".
995 base::RunLoop run_loop;
996 drive::ChildrenInsertRequest* request = new drive::ChildrenInsertRequest(
997 request_sender_.get(),
998 *url_generator_,
999 test_util::CreateQuitCallback(
1000 &run_loop,
1001 test_util::CreateCopyResultCallback(&error)));
1002 request->set_folder_id("parent_resource_id");
1003 request->set_id("resource_id");
1004 request_sender_->StartRequestWithRetry(request);
1005 run_loop.Run();
1008 EXPECT_EQ(HTTP_SUCCESS, error);
1009 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1010 EXPECT_EQ("/drive/v2/files/parent_resource_id/children",
1011 http_request_.relative_url);
1012 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1014 EXPECT_TRUE(http_request_.has_content);
1015 EXPECT_EQ("{\"id\":\"resource_id\"}", http_request_.content);
1018 TEST_F(DriveApiRequestsTest, ChildrenDeleteRequest) {
1019 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1021 // Remove a resource with "resource_id" from a directory with
1022 // "parent_resource_id".
1024 base::RunLoop run_loop;
1025 drive::ChildrenDeleteRequest* request = new drive::ChildrenDeleteRequest(
1026 request_sender_.get(),
1027 *url_generator_,
1028 test_util::CreateQuitCallback(
1029 &run_loop,
1030 test_util::CreateCopyResultCallback(&error)));
1031 request->set_child_id("resource_id");
1032 request->set_folder_id("parent_resource_id");
1033 request_sender_->StartRequestWithRetry(request);
1034 run_loop.Run();
1037 EXPECT_EQ(HTTP_NO_CONTENT, error);
1038 EXPECT_EQ(net::test_server::METHOD_DELETE, http_request_.method);
1039 EXPECT_EQ("/drive/v2/files/parent_resource_id/children/resource_id",
1040 http_request_.relative_url);
1041 EXPECT_FALSE(http_request_.has_content);
1044 TEST_F(DriveApiRequestsTest, UploadNewFileRequest) {
1045 // Set an expected url for uploading.
1046 expected_upload_path_ = kTestUploadNewFilePath;
1048 const char kTestContentType[] = "text/plain";
1049 const std::string kTestContent(100, 'a');
1050 const base::FilePath kTestFilePath =
1051 temp_dir_.path().AppendASCII("upload_file.txt");
1052 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1054 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1055 GURL upload_url;
1057 // Initiate uploading a new file to the directory with
1058 // "parent_resource_id".
1060 base::RunLoop run_loop;
1061 drive::InitiateUploadNewFileRequest* request =
1062 new drive::InitiateUploadNewFileRequest(
1063 request_sender_.get(),
1064 *url_generator_,
1065 kTestContentType,
1066 kTestContent.size(),
1067 "parent_resource_id", // The resource id of the parent directory.
1068 "new file title", // The title of the file being uploaded.
1069 test_util::CreateQuitCallback(
1070 &run_loop,
1071 test_util::CreateCopyResultCallback(&error, &upload_url)));
1072 request->set_properties(testing_properties_);
1073 request_sender_->StartRequestWithRetry(request);
1074 run_loop.Run();
1077 EXPECT_EQ(HTTP_SUCCESS, error);
1078 EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1079 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1080 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1081 http_request_.headers["X-Upload-Content-Length"]);
1083 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1084 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
1085 http_request_.relative_url);
1086 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1087 EXPECT_TRUE(http_request_.has_content);
1088 EXPECT_EQ(
1089 "{\"parents\":[{"
1090 "\"id\":\"parent_resource_id\","
1091 "\"kind\":\"drive#fileLink\""
1092 "}],"
1093 "\"properties\":["
1094 "{\"key\":\"key1\",\"value\":\"value1\",\"visibility\":\"PRIVATE\"},"
1095 "{\"key\":\"key2\",\"value\":\"value2\",\"visibility\":\"PUBLIC\"}],"
1096 "\"title\":\"new file title\"}",
1097 http_request_.content);
1099 // Upload the content to the upload URL.
1100 UploadRangeResponse response;
1101 scoped_ptr<FileResource> new_entry;
1104 base::RunLoop run_loop;
1105 drive::ResumeUploadRequest* resume_request =
1106 new drive::ResumeUploadRequest(
1107 request_sender_.get(),
1108 upload_url,
1109 0, // start_position
1110 kTestContent.size(), // end_position (exclusive)
1111 kTestContent.size(), // content_length,
1112 kTestContentType,
1113 kTestFilePath,
1114 test_util::CreateQuitCallback(
1115 &run_loop,
1116 test_util::CreateCopyResultCallback(&response, &new_entry)),
1117 ProgressCallback());
1118 request_sender_->StartRequestWithRetry(resume_request);
1119 run_loop.Run();
1122 // METHOD_PUT should be used to upload data.
1123 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1124 // Request should go to the upload URL.
1125 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1126 // Content-Range header should be added.
1127 EXPECT_EQ("bytes 0-" +
1128 base::Int64ToString(kTestContent.size() - 1) + "/" +
1129 base::Int64ToString(kTestContent.size()),
1130 http_request_.headers["Content-Range"]);
1131 // The upload content should be set in the HTTP request.
1132 EXPECT_TRUE(http_request_.has_content);
1133 EXPECT_EQ(kTestContent, http_request_.content);
1135 // Check the response.
1136 EXPECT_EQ(HTTP_CREATED, response.code); // Because it's a new file
1137 // The start and end positions should be set to -1, if an upload is complete.
1138 EXPECT_EQ(-1, response.start_position_received);
1139 EXPECT_EQ(-1, response.end_position_received);
1142 TEST_F(DriveApiRequestsTest, UploadNewEmptyFileRequest) {
1143 // Set an expected url for uploading.
1144 expected_upload_path_ = kTestUploadNewFilePath;
1146 const char kTestContentType[] = "text/plain";
1147 const char kTestContent[] = "";
1148 const base::FilePath kTestFilePath =
1149 temp_dir_.path().AppendASCII("empty_file.txt");
1150 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1152 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1153 GURL upload_url;
1155 // Initiate uploading a new file to the directory with "parent_resource_id".
1157 base::RunLoop run_loop;
1158 drive::InitiateUploadNewFileRequest* request =
1159 new drive::InitiateUploadNewFileRequest(
1160 request_sender_.get(),
1161 *url_generator_,
1162 kTestContentType,
1164 "parent_resource_id", // The resource id of the parent directory.
1165 "new file title", // The title of the file being uploaded.
1166 test_util::CreateQuitCallback(
1167 &run_loop,
1168 test_util::CreateCopyResultCallback(&error, &upload_url)));
1169 request_sender_->StartRequestWithRetry(request);
1170 run_loop.Run();
1173 EXPECT_EQ(HTTP_SUCCESS, error);
1174 EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1175 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1176 EXPECT_EQ("0", http_request_.headers["X-Upload-Content-Length"]);
1178 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1179 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
1180 http_request_.relative_url);
1181 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1182 EXPECT_TRUE(http_request_.has_content);
1183 EXPECT_EQ("{\"parents\":[{"
1184 "\"id\":\"parent_resource_id\","
1185 "\"kind\":\"drive#fileLink\""
1186 "}],"
1187 "\"title\":\"new file title\"}",
1188 http_request_.content);
1190 // Upload the content to the upload URL.
1191 UploadRangeResponse response;
1192 scoped_ptr<FileResource> new_entry;
1195 base::RunLoop run_loop;
1196 drive::ResumeUploadRequest* resume_request =
1197 new drive::ResumeUploadRequest(
1198 request_sender_.get(),
1199 upload_url,
1200 0, // start_position
1201 0, // end_position (exclusive)
1202 0, // content_length,
1203 kTestContentType,
1204 kTestFilePath,
1205 test_util::CreateQuitCallback(
1206 &run_loop,
1207 test_util::CreateCopyResultCallback(&response, &new_entry)),
1208 ProgressCallback());
1209 request_sender_->StartRequestWithRetry(resume_request);
1210 run_loop.Run();
1213 // METHOD_PUT should be used to upload data.
1214 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1215 // Request should go to the upload URL.
1216 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1217 // Content-Range header should NOT be added.
1218 EXPECT_EQ(0U, http_request_.headers.count("Content-Range"));
1219 // The upload content should be set in the HTTP request.
1220 EXPECT_TRUE(http_request_.has_content);
1221 EXPECT_EQ(kTestContent, http_request_.content);
1223 // Check the response.
1224 EXPECT_EQ(HTTP_CREATED, response.code); // Because it's a new file
1225 // The start and end positions should be set to -1, if an upload is complete.
1226 EXPECT_EQ(-1, response.start_position_received);
1227 EXPECT_EQ(-1, response.end_position_received);
1230 TEST_F(DriveApiRequestsTest, UploadNewLargeFileRequest) {
1231 // Set an expected url for uploading.
1232 expected_upload_path_ = kTestUploadNewFilePath;
1234 const char kTestContentType[] = "text/plain";
1235 const size_t kNumChunkBytes = 10; // Num bytes in a chunk.
1236 const std::string kTestContent(100, 'a');
1237 const base::FilePath kTestFilePath =
1238 temp_dir_.path().AppendASCII("upload_file.txt");
1239 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1241 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1242 GURL upload_url;
1244 // Initiate uploading a new file to the directory with "parent_resource_id".
1246 base::RunLoop run_loop;
1247 drive::InitiateUploadNewFileRequest* request =
1248 new drive::InitiateUploadNewFileRequest(
1249 request_sender_.get(),
1250 *url_generator_,
1251 kTestContentType,
1252 kTestContent.size(),
1253 "parent_resource_id", // The resource id of the parent directory.
1254 "new file title", // The title of the file being uploaded.
1255 test_util::CreateQuitCallback(
1256 &run_loop,
1257 test_util::CreateCopyResultCallback(&error, &upload_url)));
1258 request_sender_->StartRequestWithRetry(request);
1259 run_loop.Run();
1262 EXPECT_EQ(HTTP_SUCCESS, error);
1263 EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1264 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1265 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1266 http_request_.headers["X-Upload-Content-Length"]);
1268 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1269 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
1270 http_request_.relative_url);
1271 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1272 EXPECT_TRUE(http_request_.has_content);
1273 EXPECT_EQ("{\"parents\":[{"
1274 "\"id\":\"parent_resource_id\","
1275 "\"kind\":\"drive#fileLink\""
1276 "}],"
1277 "\"title\":\"new file title\"}",
1278 http_request_.content);
1280 // Before sending any data, check the current status.
1281 // This is an edge case test for GetUploadStatusRequest.
1283 UploadRangeResponse response;
1284 scoped_ptr<FileResource> new_entry;
1286 // Check the response by GetUploadStatusRequest.
1288 base::RunLoop run_loop;
1289 drive::GetUploadStatusRequest* get_upload_status_request =
1290 new drive::GetUploadStatusRequest(
1291 request_sender_.get(),
1292 upload_url,
1293 kTestContent.size(),
1294 test_util::CreateQuitCallback(
1295 &run_loop,
1296 test_util::CreateCopyResultCallback(&response, &new_entry)));
1297 request_sender_->StartRequestWithRetry(get_upload_status_request);
1298 run_loop.Run();
1301 // METHOD_PUT should be used to upload data.
1302 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1303 // Request should go to the upload URL.
1304 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1305 // Content-Range header should be added.
1306 EXPECT_EQ("bytes */" + base::Int64ToString(kTestContent.size()),
1307 http_request_.headers["Content-Range"]);
1308 EXPECT_TRUE(http_request_.has_content);
1309 EXPECT_TRUE(http_request_.content.empty());
1311 // Check the response.
1312 EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code);
1313 EXPECT_EQ(0, response.start_position_received);
1314 EXPECT_EQ(0, response.end_position_received);
1317 // Upload the content to the upload URL.
1318 for (size_t start_position = 0; start_position < kTestContent.size();
1319 start_position += kNumChunkBytes) {
1320 const std::string payload = kTestContent.substr(
1321 start_position,
1322 std::min(kNumChunkBytes, kTestContent.size() - start_position));
1323 const size_t end_position = start_position + payload.size();
1325 UploadRangeResponse response;
1326 scoped_ptr<FileResource> new_entry;
1329 base::RunLoop run_loop;
1330 drive::ResumeUploadRequest* resume_request =
1331 new drive::ResumeUploadRequest(
1332 request_sender_.get(),
1333 upload_url,
1334 start_position,
1335 end_position,
1336 kTestContent.size(), // content_length,
1337 kTestContentType,
1338 kTestFilePath,
1339 test_util::CreateQuitCallback(
1340 &run_loop,
1341 test_util::CreateCopyResultCallback(&response, &new_entry)),
1342 ProgressCallback());
1343 request_sender_->StartRequestWithRetry(resume_request);
1344 run_loop.Run();
1347 // METHOD_PUT should be used to upload data.
1348 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1349 // Request should go to the upload URL.
1350 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1351 // Content-Range header should be added.
1352 EXPECT_EQ("bytes " +
1353 base::Int64ToString(start_position) + "-" +
1354 base::Int64ToString(end_position - 1) + "/" +
1355 base::Int64ToString(kTestContent.size()),
1356 http_request_.headers["Content-Range"]);
1357 // The upload content should be set in the HTTP request.
1358 EXPECT_TRUE(http_request_.has_content);
1359 EXPECT_EQ(payload, http_request_.content);
1361 if (end_position == kTestContent.size()) {
1362 // Check the response.
1363 EXPECT_EQ(HTTP_CREATED, response.code); // Because it's a new file
1364 // The start and end positions should be set to -1, if an upload is
1365 // complete.
1366 EXPECT_EQ(-1, response.start_position_received);
1367 EXPECT_EQ(-1, response.end_position_received);
1368 break;
1371 // Check the response.
1372 EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code);
1373 EXPECT_EQ(0, response.start_position_received);
1374 EXPECT_EQ(static_cast<int64>(end_position), response.end_position_received);
1376 // Check the response by GetUploadStatusRequest.
1378 base::RunLoop run_loop;
1379 drive::GetUploadStatusRequest* get_upload_status_request =
1380 new drive::GetUploadStatusRequest(
1381 request_sender_.get(),
1382 upload_url,
1383 kTestContent.size(),
1384 test_util::CreateQuitCallback(
1385 &run_loop,
1386 test_util::CreateCopyResultCallback(&response, &new_entry)));
1387 request_sender_->StartRequestWithRetry(get_upload_status_request);
1388 run_loop.Run();
1391 // METHOD_PUT should be used to upload data.
1392 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1393 // Request should go to the upload URL.
1394 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1395 // Content-Range header should be added.
1396 EXPECT_EQ("bytes */" + base::Int64ToString(kTestContent.size()),
1397 http_request_.headers["Content-Range"]);
1398 EXPECT_TRUE(http_request_.has_content);
1399 EXPECT_TRUE(http_request_.content.empty());
1401 // Check the response.
1402 EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code);
1403 EXPECT_EQ(0, response.start_position_received);
1404 EXPECT_EQ(static_cast<int64>(end_position),
1405 response.end_position_received);
1409 TEST_F(DriveApiRequestsTest, UploadNewFileWithMetadataRequest) {
1410 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
1411 const base::Time::Exploded kLastViewedByMeDate =
1412 {2013, 7, 0, 19, 15, 59, 13, 123};
1414 // Set an expected url for uploading.
1415 expected_upload_path_ = kTestUploadNewFilePath;
1417 const char kTestContentType[] = "text/plain";
1418 const std::string kTestContent(100, 'a');
1420 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1421 GURL upload_url;
1423 // Initiate uploading a new file to the directory with "parent_resource_id".
1425 base::RunLoop run_loop;
1426 drive::InitiateUploadNewFileRequest* request =
1427 new drive::InitiateUploadNewFileRequest(
1428 request_sender_.get(),
1429 *url_generator_,
1430 kTestContentType,
1431 kTestContent.size(),
1432 "parent_resource_id", // The resource id of the parent directory.
1433 "new file title", // The title of the file being uploaded.
1434 test_util::CreateQuitCallback(
1435 &run_loop,
1436 test_util::CreateCopyResultCallback(&error, &upload_url)));
1437 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
1438 request->set_last_viewed_by_me_date(
1439 base::Time::FromUTCExploded(kLastViewedByMeDate));
1440 request_sender_->StartRequestWithRetry(request);
1441 run_loop.Run();
1444 EXPECT_EQ(HTTP_SUCCESS, error);
1445 EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1446 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1447 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1448 http_request_.headers["X-Upload-Content-Length"]);
1450 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1451 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable&setModifiedDate=true",
1452 http_request_.relative_url);
1453 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1454 EXPECT_TRUE(http_request_.has_content);
1455 EXPECT_EQ("{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
1456 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
1457 "\"parents\":[{\"id\":\"parent_resource_id\","
1458 "\"kind\":\"drive#fileLink\"}],"
1459 "\"title\":\"new file title\"}",
1460 http_request_.content);
1463 TEST_F(DriveApiRequestsTest, UploadExistingFileRequest) {
1464 // Set an expected url for uploading.
1465 expected_upload_path_ = kTestUploadExistingFilePath;
1467 const char kTestContentType[] = "text/plain";
1468 const std::string kTestContent(100, 'a');
1469 const base::FilePath kTestFilePath =
1470 temp_dir_.path().AppendASCII("upload_file.txt");
1471 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1473 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1474 GURL upload_url;
1476 // Initiate uploading a new file to the directory with "parent_resource_id".
1478 base::RunLoop run_loop;
1479 drive::InitiateUploadExistingFileRequest* request =
1480 new drive::InitiateUploadExistingFileRequest(
1481 request_sender_.get(),
1482 *url_generator_,
1483 kTestContentType,
1484 kTestContent.size(),
1485 "resource_id", // The resource id of the file to be overwritten.
1486 std::string(), // No etag.
1487 test_util::CreateQuitCallback(
1488 &run_loop,
1489 test_util::CreateCopyResultCallback(&error, &upload_url)));
1490 request->set_properties(testing_properties_);
1491 request_sender_->StartRequestWithRetry(request);
1492 run_loop.Run();
1495 EXPECT_EQ(HTTP_SUCCESS, error);
1496 EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1497 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1498 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1499 http_request_.headers["X-Upload-Content-Length"]);
1500 EXPECT_EQ("*", http_request_.headers["If-Match"]);
1502 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1503 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1504 http_request_.relative_url);
1505 EXPECT_TRUE(http_request_.has_content);
1506 EXPECT_EQ(
1507 "{\"properties\":["
1508 "{\"key\":\"key1\",\"value\":\"value1\",\"visibility\":\"PRIVATE\"},"
1509 "{\"key\":\"key2\",\"value\":\"value2\",\"visibility\":\"PUBLIC\"}]}",
1510 http_request_.content);
1512 // Upload the content to the upload URL.
1513 UploadRangeResponse response;
1514 scoped_ptr<FileResource> new_entry;
1517 base::RunLoop run_loop;
1518 drive::ResumeUploadRequest* resume_request =
1519 new drive::ResumeUploadRequest(
1520 request_sender_.get(),
1521 upload_url,
1522 0, // start_position
1523 kTestContent.size(), // end_position (exclusive)
1524 kTestContent.size(), // content_length,
1525 kTestContentType,
1526 kTestFilePath,
1527 test_util::CreateQuitCallback(
1528 &run_loop,
1529 test_util::CreateCopyResultCallback(&response, &new_entry)),
1530 ProgressCallback());
1531 request_sender_->StartRequestWithRetry(resume_request);
1532 run_loop.Run();
1535 // METHOD_PUT should be used to upload data.
1536 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1537 // Request should go to the upload URL.
1538 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1539 // Content-Range header should be added.
1540 EXPECT_EQ("bytes 0-" +
1541 base::Int64ToString(kTestContent.size() - 1) + "/" +
1542 base::Int64ToString(kTestContent.size()),
1543 http_request_.headers["Content-Range"]);
1544 // The upload content should be set in the HTTP request.
1545 EXPECT_TRUE(http_request_.has_content);
1546 EXPECT_EQ(kTestContent, http_request_.content);
1548 // Check the response.
1549 EXPECT_EQ(HTTP_SUCCESS, response.code); // Because it's an existing file
1550 // The start and end positions should be set to -1, if an upload is complete.
1551 EXPECT_EQ(-1, response.start_position_received);
1552 EXPECT_EQ(-1, response.end_position_received);
1555 TEST_F(DriveApiRequestsTest, UploadExistingFileRequestWithETag) {
1556 // Set an expected url for uploading.
1557 expected_upload_path_ = kTestUploadExistingFilePath;
1559 const char kTestContentType[] = "text/plain";
1560 const std::string kTestContent(100, 'a');
1561 const base::FilePath kTestFilePath =
1562 temp_dir_.path().AppendASCII("upload_file.txt");
1563 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1565 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1566 GURL upload_url;
1568 // Initiate uploading a new file to the directory with "parent_resource_id".
1570 base::RunLoop run_loop;
1571 drive::InitiateUploadExistingFileRequest* request =
1572 new drive::InitiateUploadExistingFileRequest(
1573 request_sender_.get(),
1574 *url_generator_,
1575 kTestContentType,
1576 kTestContent.size(),
1577 "resource_id", // The resource id of the file to be overwritten.
1578 kTestETag,
1579 test_util::CreateQuitCallback(
1580 &run_loop,
1581 test_util::CreateCopyResultCallback(&error, &upload_url)));
1582 request_sender_->StartRequestWithRetry(request);
1583 run_loop.Run();
1586 EXPECT_EQ(HTTP_SUCCESS, error);
1587 EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1588 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1589 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1590 http_request_.headers["X-Upload-Content-Length"]);
1591 EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
1593 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1594 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1595 http_request_.relative_url);
1596 EXPECT_TRUE(http_request_.has_content);
1597 EXPECT_TRUE(http_request_.content.empty());
1599 // Upload the content to the upload URL.
1600 UploadRangeResponse response;
1601 scoped_ptr<FileResource> new_entry;
1604 base::RunLoop run_loop;
1605 drive::ResumeUploadRequest* resume_request =
1606 new drive::ResumeUploadRequest(
1607 request_sender_.get(),
1608 upload_url,
1609 0, // start_position
1610 kTestContent.size(), // end_position (exclusive)
1611 kTestContent.size(), // content_length,
1612 kTestContentType,
1613 kTestFilePath,
1614 test_util::CreateQuitCallback(
1615 &run_loop,
1616 test_util::CreateCopyResultCallback(&response, &new_entry)),
1617 ProgressCallback());
1618 request_sender_->StartRequestWithRetry(resume_request);
1619 run_loop.Run();
1622 // METHOD_PUT should be used to upload data.
1623 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1624 // Request should go to the upload URL.
1625 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1626 // Content-Range header should be added.
1627 EXPECT_EQ("bytes 0-" +
1628 base::Int64ToString(kTestContent.size() - 1) + "/" +
1629 base::Int64ToString(kTestContent.size()),
1630 http_request_.headers["Content-Range"]);
1631 // The upload content should be set in the HTTP request.
1632 EXPECT_TRUE(http_request_.has_content);
1633 EXPECT_EQ(kTestContent, http_request_.content);
1635 // Check the response.
1636 EXPECT_EQ(HTTP_SUCCESS, response.code); // Because it's an existing file
1637 // The start and end positions should be set to -1, if an upload is complete.
1638 EXPECT_EQ(-1, response.start_position_received);
1639 EXPECT_EQ(-1, response.end_position_received);
1642 TEST_F(DriveApiRequestsTest, UploadExistingFileRequestWithETagConflicting) {
1643 // Set an expected url for uploading.
1644 expected_upload_path_ = kTestUploadExistingFilePath;
1646 // If it turned out that the etag is conflicting, PRECONDITION_FAILED should
1647 // be returned.
1648 expected_precondition_failed_file_path_ =
1649 test_util::GetTestFilePath("drive/error.json");
1651 const char kTestContentType[] = "text/plain";
1652 const std::string kTestContent(100, 'a');
1654 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1655 GURL upload_url;
1657 // Initiate uploading a new file to the directory with "parent_resource_id".
1659 base::RunLoop run_loop;
1660 drive::InitiateUploadExistingFileRequest* request =
1661 new drive::InitiateUploadExistingFileRequest(
1662 request_sender_.get(),
1663 *url_generator_,
1664 kTestContentType,
1665 kTestContent.size(),
1666 "resource_id", // The resource id of the file to be overwritten.
1667 "Conflicting-etag",
1668 test_util::CreateQuitCallback(
1669 &run_loop,
1670 test_util::CreateCopyResultCallback(&error, &upload_url)));
1671 request_sender_->StartRequestWithRetry(request);
1672 run_loop.Run();
1675 EXPECT_EQ(HTTP_PRECONDITION, error);
1676 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1677 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1678 http_request_.headers["X-Upload-Content-Length"]);
1679 EXPECT_EQ("Conflicting-etag", http_request_.headers["If-Match"]);
1681 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1682 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1683 http_request_.relative_url);
1684 EXPECT_TRUE(http_request_.has_content);
1685 EXPECT_TRUE(http_request_.content.empty());
1688 TEST_F(DriveApiRequestsTest,
1689 UploadExistingFileRequestWithETagConflictOnResumeUpload) {
1690 // Set an expected url for uploading.
1691 expected_upload_path_ = kTestUploadExistingFilePath;
1693 const char kTestContentType[] = "text/plain";
1694 const std::string kTestContent(100, 'a');
1695 const base::FilePath kTestFilePath =
1696 temp_dir_.path().AppendASCII("upload_file.txt");
1697 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1699 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1700 GURL upload_url;
1702 // Initiate uploading a new file to the directory with "parent_resource_id".
1704 base::RunLoop run_loop;
1705 drive::InitiateUploadExistingFileRequest* request =
1706 new drive::InitiateUploadExistingFileRequest(
1707 request_sender_.get(),
1708 *url_generator_,
1709 kTestContentType,
1710 kTestContent.size(),
1711 "resource_id", // The resource id of the file to be overwritten.
1712 kTestETag,
1713 test_util::CreateQuitCallback(
1714 &run_loop,
1715 test_util::CreateCopyResultCallback(&error, &upload_url)));
1716 request_sender_->StartRequestWithRetry(request);
1717 run_loop.Run();
1720 EXPECT_EQ(HTTP_SUCCESS, error);
1721 EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1722 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1723 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1724 http_request_.headers["X-Upload-Content-Length"]);
1725 EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
1727 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1728 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1729 http_request_.relative_url);
1730 EXPECT_TRUE(http_request_.has_content);
1731 EXPECT_TRUE(http_request_.content.empty());
1733 // Set PRECONDITION_FAILED to the server. This is the emulation of the
1734 // confliction during uploading.
1735 expected_precondition_failed_file_path_ =
1736 test_util::GetTestFilePath("drive/error.json");
1738 // Upload the content to the upload URL.
1739 UploadRangeResponse response;
1740 scoped_ptr<FileResource> new_entry;
1743 base::RunLoop run_loop;
1744 drive::ResumeUploadRequest* resume_request =
1745 new drive::ResumeUploadRequest(
1746 request_sender_.get(),
1747 upload_url,
1748 0, // start_position
1749 kTestContent.size(), // end_position (exclusive)
1750 kTestContent.size(), // content_length,
1751 kTestContentType,
1752 kTestFilePath,
1753 test_util::CreateQuitCallback(
1754 &run_loop,
1755 test_util::CreateCopyResultCallback(&response, &new_entry)),
1756 ProgressCallback());
1757 request_sender_->StartRequestWithRetry(resume_request);
1758 run_loop.Run();
1761 // METHOD_PUT should be used to upload data.
1762 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1763 // Request should go to the upload URL.
1764 EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1765 // Content-Range header should be added.
1766 EXPECT_EQ("bytes 0-" +
1767 base::Int64ToString(kTestContent.size() - 1) + "/" +
1768 base::Int64ToString(kTestContent.size()),
1769 http_request_.headers["Content-Range"]);
1770 // The upload content should be set in the HTTP request.
1771 EXPECT_TRUE(http_request_.has_content);
1772 EXPECT_EQ(kTestContent, http_request_.content);
1774 // Check the response.
1775 EXPECT_EQ(HTTP_PRECONDITION, response.code);
1776 // The start and end positions should be set to -1 for error.
1777 EXPECT_EQ(-1, response.start_position_received);
1778 EXPECT_EQ(-1, response.end_position_received);
1780 // New entry should be NULL.
1781 EXPECT_FALSE(new_entry.get());
1784 TEST_F(DriveApiRequestsTest, UploadExistingFileWithMetadataRequest) {
1785 const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
1786 const base::Time::Exploded kLastViewedByMeDate =
1787 {2013, 7, 0, 19, 15, 59, 13, 123};
1789 // Set an expected url for uploading.
1790 expected_upload_path_ = kTestUploadExistingFilePath;
1792 const char kTestContentType[] = "text/plain";
1793 const std::string kTestContent(100, 'a');
1795 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1796 GURL upload_url;
1798 // Initiate uploading a new file to the directory with "parent_resource_id".
1800 base::RunLoop run_loop;
1801 drive::InitiateUploadExistingFileRequest* request =
1802 new drive::InitiateUploadExistingFileRequest(
1803 request_sender_.get(),
1804 *url_generator_,
1805 kTestContentType,
1806 kTestContent.size(),
1807 "resource_id", // The resource id of the file to be overwritten.
1808 kTestETag,
1809 test_util::CreateQuitCallback(
1810 &run_loop,
1811 test_util::CreateCopyResultCallback(&error, &upload_url)));
1812 request->set_parent_resource_id("new_parent_resource_id");
1813 request->set_title("new file title");
1814 request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
1815 request->set_last_viewed_by_me_date(
1816 base::Time::FromUTCExploded(kLastViewedByMeDate));
1818 request_sender_->StartRequestWithRetry(request);
1819 run_loop.Run();
1822 EXPECT_EQ(HTTP_SUCCESS, error);
1823 EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1824 EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1825 EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1826 http_request_.headers["X-Upload-Content-Length"]);
1827 EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
1829 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1830 EXPECT_EQ("/upload/drive/v2/files/resource_id?"
1831 "uploadType=resumable&setModifiedDate=true",
1832 http_request_.relative_url);
1833 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1834 EXPECT_TRUE(http_request_.has_content);
1835 EXPECT_EQ("{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
1836 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
1837 "\"parents\":[{\"id\":\"new_parent_resource_id\","
1838 "\"kind\":\"drive#fileLink\"}],"
1839 "\"title\":\"new file title\"}",
1840 http_request_.content);
1843 TEST_F(DriveApiRequestsTest, DownloadFileRequest) {
1844 const base::FilePath kDownloadedFilePath =
1845 temp_dir_.path().AppendASCII("cache_file");
1846 const std::string kTestId("dummyId");
1848 DriveApiErrorCode result_code = DRIVE_OTHER_ERROR;
1849 base::FilePath temp_file;
1851 base::RunLoop run_loop;
1852 drive::DownloadFileRequest* request = new drive::DownloadFileRequest(
1853 request_sender_.get(),
1854 *url_generator_,
1855 kTestId,
1856 kDownloadedFilePath,
1857 test_util::CreateQuitCallback(
1858 &run_loop,
1859 test_util::CreateCopyResultCallback(&result_code, &temp_file)),
1860 GetContentCallback(),
1861 ProgressCallback());
1862 request_sender_->StartRequestWithRetry(request);
1863 run_loop.Run();
1866 std::string contents;
1867 base::ReadFileToString(temp_file, &contents);
1868 base::DeleteFile(temp_file, false);
1870 EXPECT_EQ(HTTP_SUCCESS, result_code);
1871 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
1872 EXPECT_EQ(kTestDownloadPathPrefix + kTestId, http_request_.relative_url);
1873 EXPECT_EQ(kDownloadedFilePath, temp_file);
1875 const std::string expected_contents = kTestId + kTestId + kTestId;
1876 EXPECT_EQ(expected_contents, contents);
1879 TEST_F(DriveApiRequestsTest, DownloadFileRequest_GetContentCallback) {
1880 const base::FilePath kDownloadedFilePath =
1881 temp_dir_.path().AppendASCII("cache_file");
1882 const std::string kTestId("dummyId");
1884 DriveApiErrorCode result_code = DRIVE_OTHER_ERROR;
1885 base::FilePath temp_file;
1886 std::string contents;
1888 base::RunLoop run_loop;
1889 drive::DownloadFileRequest* request = new drive::DownloadFileRequest(
1890 request_sender_.get(),
1891 *url_generator_,
1892 kTestId,
1893 kDownloadedFilePath,
1894 test_util::CreateQuitCallback(
1895 &run_loop,
1896 test_util::CreateCopyResultCallback(&result_code, &temp_file)),
1897 base::Bind(&AppendContent, &contents),
1898 ProgressCallback());
1899 request_sender_->StartRequestWithRetry(request);
1900 run_loop.Run();
1903 base::DeleteFile(temp_file, false);
1905 EXPECT_EQ(HTTP_SUCCESS, result_code);
1906 EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
1907 EXPECT_EQ(kTestDownloadPathPrefix + kTestId, http_request_.relative_url);
1908 EXPECT_EQ(kDownloadedFilePath, temp_file);
1910 const std::string expected_contents = kTestId + kTestId + kTestId;
1911 EXPECT_EQ(expected_contents, contents);
1914 TEST_F(DriveApiRequestsTest, PermissionsInsertRequest) {
1915 expected_content_type_ = "application/json";
1916 expected_content_ = kTestPermissionResponse;
1918 DriveApiErrorCode error = DRIVE_OTHER_ERROR;
1920 // Add comment permission to the user "user@example.com".
1922 base::RunLoop run_loop;
1923 drive::PermissionsInsertRequest* request =
1924 new drive::PermissionsInsertRequest(
1925 request_sender_.get(),
1926 *url_generator_,
1927 test_util::CreateQuitCallback(
1928 &run_loop,
1929 test_util::CreateCopyResultCallback(&error)));
1930 request->set_id("resource_id");
1931 request->set_role(drive::PERMISSION_ROLE_COMMENTER);
1932 request->set_type(drive::PERMISSION_TYPE_USER);
1933 request->set_value("user@example.com");
1934 request_sender_->StartRequestWithRetry(request);
1935 run_loop.Run();
1938 EXPECT_EQ(HTTP_SUCCESS, error);
1939 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1940 EXPECT_EQ("/drive/v2/files/resource_id/permissions",
1941 http_request_.relative_url);
1942 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1944 scoped_ptr<base::Value> expected(base::JSONReader::DeprecatedRead(
1945 "{\"additionalRoles\":[\"commenter\"], \"role\":\"reader\", "
1946 "\"type\":\"user\",\"value\":\"user@example.com\"}"));
1947 ASSERT_TRUE(expected);
1949 scoped_ptr<base::Value> result =
1950 base::JSONReader::Read(http_request_.content);
1951 EXPECT_TRUE(http_request_.has_content);
1952 EXPECT_TRUE(base::Value::Equals(expected.get(), result.get()));
1954 // Add "can edit" permission to users in "example.com".
1955 error = DRIVE_OTHER_ERROR;
1957 base::RunLoop run_loop;
1958 drive::PermissionsInsertRequest* request =
1959 new drive::PermissionsInsertRequest(
1960 request_sender_.get(),
1961 *url_generator_,
1962 test_util::CreateQuitCallback(
1963 &run_loop,
1964 test_util::CreateCopyResultCallback(&error)));
1965 request->set_id("resource_id2");
1966 request->set_role(drive::PERMISSION_ROLE_WRITER);
1967 request->set_type(drive::PERMISSION_TYPE_DOMAIN);
1968 request->set_value("example.com");
1969 request_sender_->StartRequestWithRetry(request);
1970 run_loop.Run();
1973 EXPECT_EQ(HTTP_SUCCESS, error);
1974 EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1975 EXPECT_EQ("/drive/v2/files/resource_id2/permissions",
1976 http_request_.relative_url);
1977 EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1979 expected.reset(base::JSONReader::DeprecatedRead(
1980 "{\"role\":\"writer\", \"type\":\"domain\",\"value\":\"example.com\"}"));
1981 ASSERT_TRUE(expected);
1983 result.reset(base::JSONReader::DeprecatedRead(http_request_.content));
1984 EXPECT_TRUE(http_request_.has_content);
1985 EXPECT_TRUE(base::Value::Equals(expected.get(), result.get()));
1988 TEST_F(DriveApiRequestsTest, BatchUploadRequest) {
1989 // Preapre constants.
1990 const char kTestContentType[] = "text/plain";
1991 const std::string kTestContent(10, 'a');
1992 const base::FilePath kTestFilePath =
1993 temp_dir_.path().AppendASCII("upload_file.txt");
1994 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1996 // Create batch request.
1997 drive::BatchUploadRequest* const request =
1998 new drive::BatchUploadRequest(request_sender_.get(), *url_generator_);
1999 request->SetBoundaryForTesting("OUTERBOUNDARY");
2000 request_sender_->StartRequestWithRetry(request);
2002 // Create child request.
2003 DriveApiErrorCode errors[] = {DRIVE_OTHER_ERROR, DRIVE_OTHER_ERROR};
2004 scoped_ptr<FileResource> file_resources[2];
2005 base::RunLoop run_loop[2];
2006 for (int i = 0; i < 2; ++i) {
2007 const FileResourceCallback callback = test_util::CreateQuitCallback(
2008 &run_loop[i],
2009 test_util::CreateCopyResultCallback(&errors[i], &file_resources[i]));
2010 drive::MultipartUploadNewFileDelegate* const child_request =
2011 new drive::MultipartUploadNewFileDelegate(
2012 request_sender_.get(), base::StringPrintf("new file title %d", i),
2013 "parent_resource_id", kTestContentType, kTestContent.size(),
2014 base::Time(), base::Time(), kTestFilePath, drive::Properties(),
2015 *url_generator_, callback, ProgressCallback());
2016 child_request->SetBoundaryForTesting("INNERBOUNDARY");
2017 request->AddRequest(child_request);
2019 request->Commit();
2020 run_loop[0].Run();
2021 run_loop[1].Run();
2023 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
2024 EXPECT_EQ("batch", http_request_.headers["X-Goog-Upload-Protocol"]);
2025 EXPECT_EQ("multipart/mixed; boundary=OUTERBOUNDARY",
2026 http_request_.headers["Content-Type"]);
2027 EXPECT_EQ(
2028 "--OUTERBOUNDARY\n"
2029 "Content-Type: application/http\n"
2030 "\n"
2031 "POST /upload/drive/v2/files HTTP/1.1\n"
2032 "Host: 127.0.0.1\n"
2033 "X-Goog-Upload-Protocol: multipart\n"
2034 "Content-Type: multipart/related; boundary=INNERBOUNDARY\n"
2035 "\n"
2036 "--INNERBOUNDARY\n"
2037 "Content-Type: application/json\n"
2038 "\n"
2039 "{\"parents\":[{\"id\":\"parent_resource_id\","
2040 "\"kind\":\"drive#fileLink\"}],\"title\":\"new file title 0\"}\n"
2041 "--INNERBOUNDARY\n"
2042 "Content-Type: text/plain\n"
2043 "\n"
2044 "aaaaaaaaaa\n"
2045 "--INNERBOUNDARY--\n"
2046 "--OUTERBOUNDARY\n"
2047 "Content-Type: application/http\n"
2048 "\n"
2049 "POST /upload/drive/v2/files HTTP/1.1\n"
2050 "Host: 127.0.0.1\n"
2051 "X-Goog-Upload-Protocol: multipart\n"
2052 "Content-Type: multipart/related; boundary=INNERBOUNDARY\n"
2053 "\n"
2054 "--INNERBOUNDARY\n"
2055 "Content-Type: application/json\n"
2056 "\n"
2057 "{\"parents\":[{\"id\":\"parent_resource_id\","
2058 "\"kind\":\"drive#fileLink\"}],\"title\":\"new file title 1\"}\n"
2059 "--INNERBOUNDARY\n"
2060 "Content-Type: text/plain\n"
2061 "\n"
2062 "aaaaaaaaaa\n"
2063 "--INNERBOUNDARY--\n"
2064 "--OUTERBOUNDARY--",
2065 http_request_.content);
2066 EXPECT_EQ(HTTP_SUCCESS, errors[0]);
2067 ASSERT_TRUE(file_resources[0]);
2068 EXPECT_EQ("file_id_1", file_resources[0]->file_id());
2069 ASSERT_FALSE(file_resources[1]);
2070 EXPECT_EQ(HTTP_SERVICE_UNAVAILABLE, errors[1]);
2073 TEST_F(DriveApiRequestsTest, EmptyBatchUploadRequest) {
2074 drive::BatchUploadRequest* const request =
2075 new drive::BatchUploadRequest(request_sender_.get(), *url_generator_);
2076 base::WeakPtr<drive::BatchUploadRequest> weak_ptr =
2077 request->GetWeakPtrAsBatchUploadRequest();
2078 request->Commit();
2079 ASSERT_FALSE(weak_ptr.get());
2082 TEST_F(DriveApiRequestsTest, BatchUploadRequestWithBodyIncludingZero) {
2083 // Create batch request.
2084 drive::BatchUploadRequest* const request =
2085 new drive::BatchUploadRequest(request_sender_.get(), *url_generator_);
2086 request->SetBoundaryForTesting("OUTERBOUNDARY");
2087 request_sender_->StartRequestWithRetry(request);
2089 // Create child request.
2091 base::RunLoop loop;
2092 TestBatchableDelegate* const child_request = new TestBatchableDelegate(
2093 GURL("http://example.com/test"), "application/binary",
2094 std::string("Apple\0Orange\0", 13), loop.QuitClosure());
2095 request->AddRequest(child_request);
2096 request->Commit();
2097 loop.Run();
2100 EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
2101 EXPECT_EQ("batch", http_request_.headers["X-Goog-Upload-Protocol"]);
2102 EXPECT_EQ("multipart/mixed; boundary=OUTERBOUNDARY",
2103 http_request_.headers["Content-Type"]);
2104 EXPECT_EQ(
2105 "--OUTERBOUNDARY\n"
2106 "Content-Type: application/http\n"
2107 "\n"
2108 "PUT /test HTTP/1.1\n"
2109 "Host: 127.0.0.1\n"
2110 "X-Goog-Upload-Protocol: multipart\n"
2111 "Content-Type: application/binary\n"
2112 "\n" +
2113 std::string("Apple\0Orange\0", 13) +
2114 "\n"
2115 "--OUTERBOUNDARY--",
2116 http_request_.content);
2119 TEST_F(DriveApiRequestsTest, BatchUploadRequestProgress) {
2120 // Create batch request.
2121 drive::BatchUploadRequest* const request =
2122 new drive::BatchUploadRequest(request_sender_.get(), *url_generator_);
2123 TestBatchableDelegate* requests[] = {
2124 new TestBatchableDelegate(GURL("http://example.com/test"),
2125 "application/binary", std::string(100, 'a'),
2126 base::Bind(&EmptyClosure)),
2127 new TestBatchableDelegate(GURL("http://example.com/test"),
2128 "application/binary", std::string(50, 'b'),
2129 base::Bind(&EmptyClosure)),
2130 new TestBatchableDelegate(GURL("http://example.com/test"),
2131 "application/binary", std::string(0, 'c'),
2132 base::Bind(&EmptyClosure))};
2133 const size_t kExpectedUploadDataPosition[] = {208, 517, 776};
2134 const size_t kExpectedUploadDataSize = 851;
2135 request->AddRequest(requests[0]);
2136 request->AddRequest(requests[1]);
2137 request->AddRequest(requests[2]);
2138 request->Commit();
2139 request->Prepare(base::Bind(&EmptyPreapreCallback));
2141 request->OnURLFetchUploadProgress(nullptr, 0, kExpectedUploadDataSize);
2142 request->OnURLFetchUploadProgress(nullptr, 150, kExpectedUploadDataSize);
2143 EXPECT_EQ(0u, requests[0]->progress_values().size());
2144 EXPECT_EQ(0u, requests[1]->progress_values().size());
2145 EXPECT_EQ(0u, requests[2]->progress_values().size());
2146 request->OnURLFetchUploadProgress(nullptr, kExpectedUploadDataPosition[0],
2147 kExpectedUploadDataSize);
2148 EXPECT_EQ(1u, 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(
2152 nullptr, kExpectedUploadDataPosition[0] + 50, kExpectedUploadDataSize);
2153 EXPECT_EQ(2u, 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[1] + 20, kExpectedUploadDataSize);
2158 EXPECT_EQ(3u, requests[0]->progress_values().size());
2159 EXPECT_EQ(1u, requests[1]->progress_values().size());
2160 EXPECT_EQ(0u, requests[2]->progress_values().size());
2161 request->OnURLFetchUploadProgress(nullptr, kExpectedUploadDataPosition[2],
2162 kExpectedUploadDataSize);
2163 EXPECT_EQ(3u, requests[0]->progress_values().size());
2164 EXPECT_EQ(2u, requests[1]->progress_values().size());
2165 EXPECT_EQ(1u, requests[2]->progress_values().size());
2166 request->OnURLFetchUploadProgress(nullptr, kExpectedUploadDataSize,
2167 kExpectedUploadDataSize);
2168 ASSERT_EQ(3u, requests[0]->progress_values().size());
2169 EXPECT_EQ(0, requests[0]->progress_values()[0]);
2170 EXPECT_EQ(50, requests[0]->progress_values()[1]);
2171 EXPECT_EQ(100, requests[0]->progress_values()[2]);
2172 ASSERT_EQ(2u, requests[1]->progress_values().size());
2173 EXPECT_EQ(20, requests[1]->progress_values()[0]);
2174 EXPECT_EQ(50, requests[1]->progress_values()[1]);
2175 ASSERT_EQ(1u, requests[2]->progress_values().size());
2176 EXPECT_EQ(0, requests[2]->progress_values()[0]);
2178 request->Cancel();
2181 TEST(ParseMultipartResponseTest, Empty) {
2182 std::vector<drive::MultipartHttpResponse> parts;
2183 EXPECT_FALSE(drive::ParseMultipartResponse(
2184 "multipart/mixed; boundary=BOUNDARY", "", &parts));
2185 EXPECT_FALSE(drive::ParseMultipartResponse("multipart/mixed; boundary=",
2186 "CONTENT", &parts));
2189 TEST(ParseMultipartResponseTest, Basic) {
2190 std::vector<drive::MultipartHttpResponse> parts;
2191 ASSERT_TRUE(
2192 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2193 "--BOUNDARY\r\n"
2194 "Content-Type: application/http\r\n"
2195 "\r\n"
2196 "HTTP/1.1 200 OK\r\n"
2197 "Header: value\r\n"
2198 "\r\n"
2199 "First line\r\n"
2200 "Second line\r\n"
2201 "--BOUNDARY\r\n"
2202 "Content-Type: application/http\r\n"
2203 "\r\n"
2204 "HTTP/1.1 404 Not Found\r\n"
2205 "Header: value\r\n"
2206 "--BOUNDARY--",
2207 &parts));
2208 ASSERT_EQ(2u, parts.size());
2209 EXPECT_EQ(HTTP_SUCCESS, parts[0].code);
2210 EXPECT_EQ("First line\r\nSecond line", parts[0].body);
2211 EXPECT_EQ(HTTP_NOT_FOUND, parts[1].code);
2212 EXPECT_EQ("", parts[1].body);
2215 TEST(ParseMultipartResponseTest, InvalidStatusLine) {
2216 std::vector<drive::MultipartHttpResponse> parts;
2217 ASSERT_TRUE(
2218 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2219 "--BOUNDARY\r\n"
2220 "Content-Type: application/http\r\n"
2221 "\r\n"
2222 "InvalidStatusLine 200 \r\n"
2223 "Header: value\r\n"
2224 "\r\n"
2225 "{}\r\n"
2226 "--BOUNDARY--",
2227 &parts));
2228 ASSERT_EQ(1u, parts.size());
2229 EXPECT_EQ(DRIVE_PARSE_ERROR, parts[0].code);
2230 EXPECT_EQ("{}", parts[0].body);
2233 TEST(ParseMultipartResponseTest, BoundaryInTheBodyAndPreamble) {
2234 std::vector<drive::MultipartHttpResponse> parts;
2235 ASSERT_TRUE(
2236 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2237 "BOUNDARY\r\n"
2238 "PREUMBLE\r\n"
2239 "--BOUNDARY\r\n"
2240 "Content-Type: application/http\r\n"
2241 "\r\n"
2242 "HTTP/1.1 200 OK\r\n"
2243 "Header: value\r\n"
2244 "\r\n"
2245 "{--BOUNDARY}\r\n"
2246 "--BOUNDARY--",
2247 &parts));
2248 ASSERT_EQ(1u, parts.size());
2249 EXPECT_EQ(HTTP_SUCCESS, parts[0].code);
2250 EXPECT_EQ("{--BOUNDARY}", parts[0].body);
2253 TEST(ParseMultipartResponseTest, QuatedBoundary) {
2254 std::vector<drive::MultipartHttpResponse> parts;
2255 ASSERT_TRUE(
2256 drive::ParseMultipartResponse("multipart/mixed; boundary=\"BOUNDARY\"",
2257 "--BOUNDARY\r\n"
2258 "Content-Type: application/http\r\n"
2259 "\r\n"
2260 "HTTP/1.1 200 OK\r\n"
2261 "Header: value\r\n"
2262 "\r\n"
2263 "BODY\r\n"
2264 "--BOUNDARY--",
2265 &parts));
2266 ASSERT_EQ(1u, parts.size());
2267 EXPECT_EQ(HTTP_SUCCESS, parts[0].code);
2268 EXPECT_EQ("BODY", parts[0].body);
2271 TEST(ParseMultipartResponseTest, BoundaryWithTransportPadding) {
2272 std::vector<drive::MultipartHttpResponse> parts;
2273 ASSERT_TRUE(
2274 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2275 "--BOUNDARY \t\r\n"
2276 "Content-Type: application/http\r\n"
2277 "\r\n"
2278 "HTTP/1.1 200 OK\r\n"
2279 "Header: value\r\n"
2280 "\r\n"
2281 "BODY\r\n"
2282 "--BOUNDARY-- \t",
2283 &parts));
2284 ASSERT_EQ(1u, parts.size());
2285 EXPECT_EQ(HTTP_SUCCESS, parts[0].code);
2286 EXPECT_EQ("BODY", parts[0].body);
2288 } // namespace google_apis