1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "base/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
{
31 const char kTestETag
[] = "test_etag";
32 const char kTestUserAgent
[] = "test-user-agent";
34 const char kTestChildrenResponse
[] =
36 "\"kind\": \"drive#childReference\",\n"
37 "\"id\": \"resource_id\",\n"
38 "\"selfLink\": \"self_link\",\n"
39 "\"childLink\": \"child_link\",\n"
42 const char kTestPermissionResponse
[] =
44 "\"kind\": \"drive#permission\",\n"
45 "\"id\": \"resource_id\",\n"
46 "\"selfLink\": \"self_link\",\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
{
63 TestBatchableDelegate(const GURL url
,
64 const std::string
& content_type
,
65 const std::string
& content_data
,
66 const base::Closure
& callback
)
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_
);
87 void NotifyError(DriveApiErrorCode code
) override
{ callback_
.Run(); }
88 void NotifyResult(DriveApiErrorCode code
,
89 const std::string
& body
,
90 const base::Closure
& closure
) override
{
94 void NotifyUploadProgress(const net::URLFetcher
* source
,
96 int64 total
) override
{
97 progress_values_
.push_back(current
);
99 const std::vector
<int64
>& progress_values() const { return progress_values_
; }
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() {
116 class DriveApiRequestsTest
: public testing::Test
{
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(),
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();
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
212 net::test_server::HttpRequest http_request_
;
214 // Testing properties used by multiple test cases.
215 drive::Properties testing_properties_
;
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
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
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
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
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
);
301 if (base::ReadFileToString(expected_precondition_failed_file_path_
,
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
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
>();
339 response
->set_code(net::HTTP_OK
);
340 response
->AddCustomHeader(
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
>();
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
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
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
);
439 if (!test_util::RemovePrefix(absolute_url
.path(),
440 kTestDownloadPathPrefix
,
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
);
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(
469 "Content-Type: application/http\r\n"
471 "HTTP/1.1 200 OK\r\n"
472 "Content-Type: application/json; charset=UTF-8\r\n"
475 " \"kind\": \"drive#file\",\r\n"
476 " \"id\": \"file_id_1\"\r\n"
480 "Content-Type: application/http\r\n"
482 "HTTP/1.1 403 Forbidden\r\n"
483 "Content-Type: application/json; charset=UTF-8\r\n"
485 "{\"error\":{\"errors\": ["
486 " {\"reason\": \"userRateLimitExceeded\"}]}}\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,
501 // Set an expected data file containing valid result.
502 expected_data_file_path_
= test_util::GetTestFilePath(
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(),
513 test_util::CreateQuitCallback(
515 test_util::CreateCopyResultCallback(&error
, &about_resource
)));
516 request
->set_fields("kind,quotaBytesTotal,quotaBytesUsedAggregate,"
517 "largestChangeId,rootFolderId");
518 request_sender_
->StartRequestWithAuthRetry(request
);
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(),
558 test_util::CreateQuitCallback(
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
);
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
);
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\"}],"
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")));
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(),
619 test_util::CreateQuitCallback(
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
);
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
);
646 "{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
647 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
648 "\"parents\":[{\"id\":\"parent_resource_id\"}],"
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(
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(),
670 test_util::CreateQuitCallback(
672 test_util::CreateCopyResultCallback(&error
, &about_resource
)));
673 request_sender_
->StartRequestWithAuthRetry(request
);
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(),
705 test_util::CreateQuitCallback(
707 test_util::CreateCopyResultCallback(&error
, &about_resource
)));
708 request_sender_
->StartRequestWithAuthRetry(request
);
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(),
732 false, // use_internal_endpoint
733 test_util::CreateQuitCallback(
735 test_util::CreateCopyResultCallback(&error
, &app_list
)));
736 request_sender_
->StartRequestWithAuthRetry(request
);
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(
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
);
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
);
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(
790 test_util::CreateCopyResultCallback(&error
, &result
)));
791 request
->set_next_link(test_server_
.GetURL("/continue/get/change/list"));
792 request_sender_
->StartRequestWithAuthRetry(request
);
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
);
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(),
819 test_util::CreateQuitCallback(
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
);
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
);
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(),
858 test_util::CreateQuitCallback(
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
);
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(
891 test_util::CreateCopyResultCallback(&error
, &result
)));
892 request
->set_max_results(50);
893 request
->set_q("\"abcde\" in parents");
894 request_sender_
->StartRequestWithAuthRetry(request
);
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
);
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(
920 test_util::CreateCopyResultCallback(&error
, &result
)));
921 request
->set_next_link(test_server_
.GetURL("/continue/get/file/list"));
922 request_sender_
->StartRequestWithAuthRetry(request
);
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
);
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(),
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
);
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(),
971 test_util::CreateQuitCallback(
973 test_util::CreateCopyResultCallback(&error
, &file_resource
)));
974 request
->set_file_id("resource_id");
975 request_sender_
->StartRequestWithAuthRetry(request
);
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(),
1000 test_util::CreateQuitCallback(
1002 test_util::CreateCopyResultCallback(&error
)));
1003 request
->set_folder_id("parent_resource_id");
1004 request
->set_id("resource_id");
1005 request_sender_
->StartRequestWithAuthRetry(request
);
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(),
1029 test_util::CreateQuitCallback(
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
);
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
;
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(),
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(
1072 test_util::CreateCopyResultCallback(&error
, &upload_url
)));
1073 request
->set_properties(testing_properties_
);
1074 request_sender_
->StartRequestWithAuthRetry(request
);
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
);
1091 "\"id\":\"parent_resource_id\","
1092 "\"kind\":\"drive#fileLink\""
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(),
1110 0, // start_position
1111 kTestContent
.size(), // end_position (exclusive)
1112 kTestContent
.size(), // content_length,
1115 test_util::CreateQuitCallback(
1117 test_util::CreateCopyResultCallback(&response
, &new_entry
)),
1118 ProgressCallback());
1119 request_sender_
->StartRequestWithAuthRetry(resume_request
);
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
;
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(),
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(
1169 test_util::CreateCopyResultCallback(&error
, &upload_url
)));
1170 request_sender_
->StartRequestWithAuthRetry(request
);
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\""
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(),
1201 0, // start_position
1202 0, // end_position (exclusive)
1203 0, // content_length,
1206 test_util::CreateQuitCallback(
1208 test_util::CreateCopyResultCallback(&response
, &new_entry
)),
1209 ProgressCallback());
1210 request_sender_
->StartRequestWithAuthRetry(resume_request
);
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
;
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(),
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(
1258 test_util::CreateCopyResultCallback(&error
, &upload_url
)));
1259 request_sender_
->StartRequestWithAuthRetry(request
);
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\""
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(),
1294 kTestContent
.size(),
1295 test_util::CreateQuitCallback(
1297 test_util::CreateCopyResultCallback(&response
, &new_entry
)));
1298 request_sender_
->StartRequestWithAuthRetry(get_upload_status_request
);
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(
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(),
1337 kTestContent
.size(), // content_length,
1340 test_util::CreateQuitCallback(
1342 test_util::CreateCopyResultCallback(&response
, &new_entry
)),
1343 ProgressCallback());
1344 request_sender_
->StartRequestWithAuthRetry(resume_request
);
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
1367 EXPECT_EQ(-1, response
.start_position_received
);
1368 EXPECT_EQ(-1, response
.end_position_received
);
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(),
1384 kTestContent
.size(),
1385 test_util::CreateQuitCallback(
1387 test_util::CreateCopyResultCallback(&response
, &new_entry
)));
1388 request_sender_
->StartRequestWithAuthRetry(get_upload_status_request
);
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
;
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(),
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(
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
);
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
;
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(),
1485 kTestContent
.size(),
1486 "resource_id", // The resource id of the file to be overwritten.
1487 std::string(), // No etag.
1488 test_util::CreateQuitCallback(
1490 test_util::CreateCopyResultCallback(&error
, &upload_url
)));
1491 request
->set_properties(testing_properties_
);
1492 request_sender_
->StartRequestWithAuthRetry(request
);
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
);
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(),
1523 0, // start_position
1524 kTestContent
.size(), // end_position (exclusive)
1525 kTestContent
.size(), // content_length,
1528 test_util::CreateQuitCallback(
1530 test_util::CreateCopyResultCallback(&response
, &new_entry
)),
1531 ProgressCallback());
1532 request_sender_
->StartRequestWithAuthRetry(resume_request
);
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
;
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(),
1577 kTestContent
.size(),
1578 "resource_id", // The resource id of the file to be overwritten.
1580 test_util::CreateQuitCallback(
1582 test_util::CreateCopyResultCallback(&error
, &upload_url
)));
1583 request_sender_
->StartRequestWithAuthRetry(request
);
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(),
1610 0, // start_position
1611 kTestContent
.size(), // end_position (exclusive)
1612 kTestContent
.size(), // content_length,
1615 test_util::CreateQuitCallback(
1617 test_util::CreateCopyResultCallback(&response
, &new_entry
)),
1618 ProgressCallback());
1619 request_sender_
->StartRequestWithAuthRetry(resume_request
);
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
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
;
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(),
1666 kTestContent
.size(),
1667 "resource_id", // The resource id of the file to be overwritten.
1669 test_util::CreateQuitCallback(
1671 test_util::CreateCopyResultCallback(&error
, &upload_url
)));
1672 request_sender_
->StartRequestWithAuthRetry(request
);
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
;
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(),
1711 kTestContent
.size(),
1712 "resource_id", // The resource id of the file to be overwritten.
1714 test_util::CreateQuitCallback(
1716 test_util::CreateCopyResultCallback(&error
, &upload_url
)));
1717 request_sender_
->StartRequestWithAuthRetry(request
);
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(),
1749 0, // start_position
1750 kTestContent
.size(), // end_position (exclusive)
1751 kTestContent
.size(), // content_length,
1754 test_util::CreateQuitCallback(
1756 test_util::CreateCopyResultCallback(&response
, &new_entry
)),
1757 ProgressCallback());
1758 request_sender_
->StartRequestWithAuthRetry(resume_request
);
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
;
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(),
1807 kTestContent
.size(),
1808 "resource_id", // The resource id of the file to be overwritten.
1810 test_util::CreateQuitCallback(
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
);
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(),
1857 kDownloadedFilePath
,
1858 test_util::CreateQuitCallback(
1860 test_util::CreateCopyResultCallback(&result_code
, &temp_file
)),
1861 GetContentCallback(),
1862 ProgressCallback());
1863 request_sender_
->StartRequestWithAuthRetry(request
);
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(),
1894 kDownloadedFilePath
,
1895 test_util::CreateQuitCallback(
1897 test_util::CreateCopyResultCallback(&result_code
, &temp_file
)),
1898 base::Bind(&AppendContent
, &contents
),
1899 ProgressCallback());
1900 request_sender_
->StartRequestWithAuthRetry(request
);
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(),
1928 test_util::CreateQuitCallback(
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
);
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(),
1963 test_util::CreateQuitCallback(
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
);
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(
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
);
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"]);
2031 "Content-Type: application/http\n"
2033 "POST /upload/drive/v2/files HTTP/1.1\n"
2035 "X-Goog-Upload-Protocol: multipart\n"
2036 "Content-Type: multipart/related; boundary=INNERBOUNDARY\n"
2039 "Content-Type: application/json\n"
2041 "{\"parents\":[{\"id\":\"parent_resource_id\","
2042 "\"kind\":\"drive#fileLink\"}],\"title\":\"new file title 0\"}\n"
2044 "Content-Type: text/plain\n"
2047 "--INNERBOUNDARY--\n"
2049 "Content-Type: application/http\n"
2051 "POST /upload/drive/v2/files HTTP/1.1\n"
2053 "X-Goog-Upload-Protocol: multipart\n"
2054 "Content-Type: multipart/related; boundary=INNERBOUNDARY\n"
2057 "Content-Type: application/json\n"
2059 "{\"parents\":[{\"id\":\"parent_resource_id\","
2060 "\"kind\":\"drive#fileLink\"}],\"title\":\"new file title 1\"}\n"
2062 "Content-Type: text/plain\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();
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.
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
);
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"]);
2108 "Content-Type: application/http\n"
2110 "PUT /test HTTP/1.1\n"
2112 "X-Goog-Upload-Protocol: multipart\n"
2113 "Content-Type: application/binary\n"
2115 std::string("Apple\0Orange\0", 13) +
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]);
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]);
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
;
2194 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2196 "Content-Type: application/http\r\n"
2198 "HTTP/1.1 200 OK\r\n"
2204 "Content-Type: application/http\r\n"
2206 "HTTP/1.1 404 Not Found\r\n"
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
;
2220 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2222 "Content-Type: application/http\r\n"
2224 "InvalidStatusLine 200 \r\n"
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
;
2238 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2242 "Content-Type: application/http\r\n"
2244 "HTTP/1.1 200 OK\r\n"
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
;
2258 drive::ParseMultipartResponse("multipart/mixed; boundary=\"BOUNDARY\"",
2260 "Content-Type: application/http\r\n"
2262 "HTTP/1.1 200 OK\r\n"
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
;
2276 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2278 "Content-Type: application/http\r\n"
2280 "HTTP/1.1 200 OK\r\n"
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