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_visibility(drive::FILE_VISIBILITY_PRIVATE
);
562 request
->set_last_viewed_by_me_date(
563 base::Time::FromUTCExploded(kLastViewedByMeDate
));
564 request
->set_mime_type("application/vnd.google-apps.folder");
565 request
->set_modified_date(base::Time::FromUTCExploded(kModifiedDate
));
566 request
->add_parent("root");
567 request
->set_title("new directory");
568 request
->set_properties(testing_properties_
);
569 request_sender_
->StartRequestWithAuthRetry(request
);
573 EXPECT_EQ(HTTP_SUCCESS
, error
);
574 EXPECT_EQ(net::test_server::METHOD_POST
, http_request_
.method
);
575 EXPECT_EQ("/drive/v2/files?visibility=PRIVATE", http_request_
.relative_url
);
576 EXPECT_EQ("application/json", http_request_
.headers
["Content-Type"]);
578 EXPECT_TRUE(http_request_
.has_content
);
580 "{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
581 "\"mimeType\":\"application/vnd.google-apps.folder\","
582 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
583 "\"parents\":[{\"id\":\"root\"}],"
585 "{\"key\":\"key1\",\"value\":\"value1\",\"visibility\":\"PRIVATE\"},"
586 "{\"key\":\"key2\",\"value\":\"value2\",\"visibility\":\"PUBLIC\"}],"
587 "\"title\":\"new directory\"}",
588 http_request_
.content
);
590 scoped_ptr
<FileResource
> expected(
591 FileResource::CreateFrom(
592 *test_util::LoadJSONFile("drive/directory_entry.json")));
595 ASSERT_TRUE(file_resource
.get());
597 EXPECT_EQ(expected
->file_id(), file_resource
->file_id());
598 EXPECT_EQ(expected
->title(), file_resource
->title());
599 EXPECT_EQ(expected
->mime_type(), file_resource
->mime_type());
600 EXPECT_EQ(expected
->parents().size(), file_resource
->parents().size());
603 TEST_F(DriveApiRequestsTest
, FilesPatchRequest
) {
604 const base::Time::Exploded kModifiedDate
= {2012, 7, 0, 19, 15, 59, 13, 123};
605 const base::Time::Exploded kLastViewedByMeDate
=
606 {2013, 7, 0, 19, 15, 59, 13, 123};
608 // Set an expected data file containing valid result.
609 expected_data_file_path_
=
610 test_util::GetTestFilePath("drive/file_entry.json");
612 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
613 scoped_ptr
<FileResource
> file_resource
;
616 base::RunLoop run_loop
;
617 drive::FilesPatchRequest
* request
= new drive::FilesPatchRequest(
618 request_sender_
.get(),
620 test_util::CreateQuitCallback(
622 test_util::CreateCopyResultCallback(&error
, &file_resource
)));
623 request
->set_file_id("resource_id");
624 request
->set_set_modified_date(true);
625 request
->set_update_viewed_date(false);
627 request
->set_title("new title");
628 request
->set_modified_date(base::Time::FromUTCExploded(kModifiedDate
));
629 request
->set_last_viewed_by_me_date(
630 base::Time::FromUTCExploded(kLastViewedByMeDate
));
631 request
->add_parent("parent_resource_id");
633 request
->set_properties(testing_properties_
);
634 request_sender_
->StartRequestWithAuthRetry(request
);
638 EXPECT_EQ(HTTP_SUCCESS
, error
);
639 EXPECT_EQ(net::test_server::METHOD_PATCH
, http_request_
.method
);
640 EXPECT_EQ("/drive/v2/files/resource_id"
641 "?setModifiedDate=true&updateViewedDate=false",
642 http_request_
.relative_url
);
644 EXPECT_EQ("application/json", http_request_
.headers
["Content-Type"]);
645 EXPECT_TRUE(http_request_
.has_content
);
647 "{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
648 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
649 "\"parents\":[{\"id\":\"parent_resource_id\"}],"
651 "{\"key\":\"key1\",\"value\":\"value1\",\"visibility\":\"PRIVATE\"},"
652 "{\"key\":\"key2\",\"value\":\"value2\",\"visibility\":\"PUBLIC\"}],"
653 "\"title\":\"new title\"}",
654 http_request_
.content
);
655 EXPECT_TRUE(file_resource
);
658 TEST_F(DriveApiRequestsTest
, AboutGetRequest_ValidJson
) {
659 // Set an expected data file containing valid result.
660 expected_data_file_path_
= test_util::GetTestFilePath(
663 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
664 scoped_ptr
<AboutResource
> about_resource
;
667 base::RunLoop run_loop
;
668 drive::AboutGetRequest
* request
= new drive::AboutGetRequest(
669 request_sender_
.get(),
671 test_util::CreateQuitCallback(
673 test_util::CreateCopyResultCallback(&error
, &about_resource
)));
674 request_sender_
->StartRequestWithAuthRetry(request
);
678 EXPECT_EQ(HTTP_SUCCESS
, error
);
679 EXPECT_EQ(net::test_server::METHOD_GET
, http_request_
.method
);
680 EXPECT_EQ("/drive/v2/about", http_request_
.relative_url
);
682 scoped_ptr
<AboutResource
> expected(
683 AboutResource::CreateFrom(
684 *test_util::LoadJSONFile("drive/about.json")));
685 ASSERT_TRUE(about_resource
.get());
686 EXPECT_EQ(expected
->largest_change_id(), about_resource
->largest_change_id());
687 EXPECT_EQ(expected
->quota_bytes_total(), about_resource
->quota_bytes_total());
688 EXPECT_EQ(expected
->quota_bytes_used_aggregate(),
689 about_resource
->quota_bytes_used_aggregate());
690 EXPECT_EQ(expected
->root_folder_id(), about_resource
->root_folder_id());
693 TEST_F(DriveApiRequestsTest
, AboutGetRequest_InvalidJson
) {
694 // Set an expected data file containing invalid result.
695 expected_data_file_path_
= test_util::GetTestFilePath(
696 "drive/testfile.txt");
698 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
699 scoped_ptr
<AboutResource
> about_resource
;
702 base::RunLoop run_loop
;
703 drive::AboutGetRequest
* request
= new drive::AboutGetRequest(
704 request_sender_
.get(),
706 test_util::CreateQuitCallback(
708 test_util::CreateCopyResultCallback(&error
, &about_resource
)));
709 request_sender_
->StartRequestWithAuthRetry(request
);
713 // "parse error" should be returned, and the about resource should be NULL.
714 EXPECT_EQ(DRIVE_PARSE_ERROR
, error
);
715 EXPECT_EQ(net::test_server::METHOD_GET
, http_request_
.method
);
716 EXPECT_EQ("/drive/v2/about", http_request_
.relative_url
);
717 EXPECT_FALSE(about_resource
);
720 TEST_F(DriveApiRequestsTest
, AppsListRequest
) {
721 // Set an expected data file containing valid result.
722 expected_data_file_path_
= test_util::GetTestFilePath(
723 "drive/applist.json");
725 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
726 scoped_ptr
<AppList
> app_list
;
729 base::RunLoop run_loop
;
730 drive::AppsListRequest
* request
= new drive::AppsListRequest(
731 request_sender_
.get(),
733 false, // use_internal_endpoint
734 test_util::CreateQuitCallback(
736 test_util::CreateCopyResultCallback(&error
, &app_list
)));
737 request_sender_
->StartRequestWithAuthRetry(request
);
741 EXPECT_EQ(HTTP_SUCCESS
, error
);
742 EXPECT_EQ(net::test_server::METHOD_GET
, http_request_
.method
);
743 EXPECT_EQ("/drive/v2/apps", http_request_
.relative_url
);
744 EXPECT_TRUE(app_list
);
747 TEST_F(DriveApiRequestsTest
, ChangesListRequest
) {
748 // Set an expected data file containing valid result.
749 expected_data_file_path_
= test_util::GetTestFilePath(
750 "drive/changelist.json");
752 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
753 scoped_ptr
<ChangeList
> result
;
756 base::RunLoop run_loop
;
757 drive::ChangesListRequest
* request
= new drive::ChangesListRequest(
758 request_sender_
.get(), *url_generator_
,
759 test_util::CreateQuitCallback(
761 test_util::CreateCopyResultCallback(&error
, &result
)));
762 request
->set_include_deleted(true);
763 request
->set_start_change_id(100);
764 request
->set_max_results(500);
765 request_sender_
->StartRequestWithAuthRetry(request
);
769 EXPECT_EQ(HTTP_SUCCESS
, error
);
770 EXPECT_EQ(net::test_server::METHOD_GET
, http_request_
.method
);
771 EXPECT_EQ("/drive/v2/changes?maxResults=500&startChangeId=100",
772 http_request_
.relative_url
);
776 TEST_F(DriveApiRequestsTest
, ChangesListNextPageRequest
) {
777 // Set an expected data file containing valid result.
778 expected_data_file_path_
= test_util::GetTestFilePath(
779 "drive/changelist.json");
781 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
782 scoped_ptr
<ChangeList
> result
;
785 base::RunLoop run_loop
;
786 drive::ChangesListNextPageRequest
* request
=
787 new drive::ChangesListNextPageRequest(
788 request_sender_
.get(),
789 test_util::CreateQuitCallback(
791 test_util::CreateCopyResultCallback(&error
, &result
)));
792 request
->set_next_link(test_server_
.GetURL("/continue/get/change/list"));
793 request_sender_
->StartRequestWithAuthRetry(request
);
797 EXPECT_EQ(HTTP_SUCCESS
, error
);
798 EXPECT_EQ(net::test_server::METHOD_GET
, http_request_
.method
);
799 EXPECT_EQ("/continue/get/change/list", http_request_
.relative_url
);
803 TEST_F(DriveApiRequestsTest
, FilesCopyRequest
) {
804 const base::Time::Exploded kModifiedDate
= {2012, 7, 0, 19, 15, 59, 13, 123};
806 // Set an expected data file containing the dummy file entry data.
807 // It'd be returned if we copy a file.
808 expected_data_file_path_
=
809 test_util::GetTestFilePath("drive/file_entry.json");
811 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
812 scoped_ptr
<FileResource
> file_resource
;
814 // Copy the file to a new file named "new title".
816 base::RunLoop run_loop
;
817 drive::FilesCopyRequest
* request
= new drive::FilesCopyRequest(
818 request_sender_
.get(),
820 test_util::CreateQuitCallback(
822 test_util::CreateCopyResultCallback(&error
, &file_resource
)));
823 request
->set_visibility(drive::FILE_VISIBILITY_PRIVATE
);
824 request
->set_file_id("resource_id");
825 request
->set_modified_date(base::Time::FromUTCExploded(kModifiedDate
));
826 request
->add_parent("parent_resource_id");
827 request
->set_title("new title");
828 request_sender_
->StartRequestWithAuthRetry(request
);
832 EXPECT_EQ(HTTP_SUCCESS
, error
);
833 EXPECT_EQ(net::test_server::METHOD_POST
, http_request_
.method
);
834 EXPECT_EQ("/drive/v2/files/resource_id/copy?visibility=PRIVATE",
835 http_request_
.relative_url
);
836 EXPECT_EQ("application/json", http_request_
.headers
["Content-Type"]);
838 EXPECT_TRUE(http_request_
.has_content
);
840 "{\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
841 "\"parents\":[{\"id\":\"parent_resource_id\"}],\"title\":\"new title\"}",
842 http_request_
.content
);
843 EXPECT_TRUE(file_resource
);
846 TEST_F(DriveApiRequestsTest
, FilesCopyRequest_EmptyParentResourceId
) {
847 // Set an expected data file containing the dummy file entry data.
848 // It'd be returned if we copy a file.
849 expected_data_file_path_
=
850 test_util::GetTestFilePath("drive/file_entry.json");
852 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
853 scoped_ptr
<FileResource
> file_resource
;
855 // Copy the file to a new file named "new title".
857 base::RunLoop run_loop
;
858 drive::FilesCopyRequest
* request
= new drive::FilesCopyRequest(
859 request_sender_
.get(),
861 test_util::CreateQuitCallback(
863 test_util::CreateCopyResultCallback(&error
, &file_resource
)));
864 request
->set_file_id("resource_id");
865 request
->set_title("new title");
866 request_sender_
->StartRequestWithAuthRetry(request
);
870 EXPECT_EQ(HTTP_SUCCESS
, error
);
871 EXPECT_EQ(net::test_server::METHOD_POST
, http_request_
.method
);
872 EXPECT_EQ("/drive/v2/files/resource_id/copy", http_request_
.relative_url
);
873 EXPECT_EQ("application/json", http_request_
.headers
["Content-Type"]);
875 EXPECT_TRUE(http_request_
.has_content
);
876 EXPECT_EQ("{\"title\":\"new title\"}", http_request_
.content
);
877 EXPECT_TRUE(file_resource
);
880 TEST_F(DriveApiRequestsTest
, FilesListRequest
) {
881 // Set an expected data file containing valid result.
882 expected_data_file_path_
= test_util::GetTestFilePath(
883 "drive/filelist.json");
885 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
886 scoped_ptr
<FileList
> result
;
889 base::RunLoop run_loop
;
890 drive::FilesListRequest
* request
= new drive::FilesListRequest(
891 request_sender_
.get(), *url_generator_
,
892 test_util::CreateQuitCallback(
894 test_util::CreateCopyResultCallback(&error
, &result
)));
895 request
->set_max_results(50);
896 request
->set_q("\"abcde\" in parents");
897 request_sender_
->StartRequestWithAuthRetry(request
);
901 EXPECT_EQ(HTTP_SUCCESS
, error
);
902 EXPECT_EQ(net::test_server::METHOD_GET
, http_request_
.method
);
903 EXPECT_EQ("/drive/v2/files?maxResults=50&q=%22abcde%22+in+parents",
904 http_request_
.relative_url
);
908 TEST_F(DriveApiRequestsTest
, FilesListNextPageRequest
) {
909 // Set an expected data file containing valid result.
910 expected_data_file_path_
= test_util::GetTestFilePath(
911 "drive/filelist.json");
913 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
914 scoped_ptr
<FileList
> result
;
917 base::RunLoop run_loop
;
918 drive::FilesListNextPageRequest
* request
=
919 new drive::FilesListNextPageRequest(
920 request_sender_
.get(),
921 test_util::CreateQuitCallback(
923 test_util::CreateCopyResultCallback(&error
, &result
)));
924 request
->set_next_link(test_server_
.GetURL("/continue/get/file/list"));
925 request_sender_
->StartRequestWithAuthRetry(request
);
929 EXPECT_EQ(HTTP_SUCCESS
, error
);
930 EXPECT_EQ(net::test_server::METHOD_GET
, http_request_
.method
);
931 EXPECT_EQ("/continue/get/file/list", http_request_
.relative_url
);
935 TEST_F(DriveApiRequestsTest
, FilesDeleteRequest
) {
936 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
938 // Delete a resource with the given resource id.
940 base::RunLoop run_loop
;
941 drive::FilesDeleteRequest
* request
= new drive::FilesDeleteRequest(
942 request_sender_
.get(),
944 test_util::CreateQuitCallback(
945 &run_loop
, test_util::CreateCopyResultCallback(&error
)));
946 request
->set_file_id("resource_id");
947 request
->set_etag(kTestETag
);
948 request_sender_
->StartRequestWithAuthRetry(request
);
952 EXPECT_EQ(HTTP_NO_CONTENT
, error
);
953 EXPECT_EQ(net::test_server::METHOD_DELETE
, http_request_
.method
);
954 EXPECT_EQ(kTestETag
, http_request_
.headers
["If-Match"]);
955 EXPECT_EQ("/drive/v2/files/resource_id", http_request_
.relative_url
);
956 EXPECT_FALSE(http_request_
.has_content
);
959 TEST_F(DriveApiRequestsTest
, FilesTrashRequest
) {
960 // Set data for the expected result. Directory entry should be returned
961 // if the trashing entry is a directory, so using it here should be fine.
962 expected_data_file_path_
=
963 test_util::GetTestFilePath("drive/directory_entry.json");
965 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
966 scoped_ptr
<FileResource
> file_resource
;
968 // Trash a resource with the given resource id.
970 base::RunLoop run_loop
;
971 drive::FilesTrashRequest
* request
= new drive::FilesTrashRequest(
972 request_sender_
.get(),
974 test_util::CreateQuitCallback(
976 test_util::CreateCopyResultCallback(&error
, &file_resource
)));
977 request
->set_file_id("resource_id");
978 request_sender_
->StartRequestWithAuthRetry(request
);
982 EXPECT_EQ(HTTP_SUCCESS
, error
);
983 EXPECT_EQ(net::test_server::METHOD_POST
, http_request_
.method
);
984 EXPECT_EQ("/drive/v2/files/resource_id/trash", http_request_
.relative_url
);
985 EXPECT_TRUE(http_request_
.has_content
);
986 EXPECT_TRUE(http_request_
.content
.empty());
989 TEST_F(DriveApiRequestsTest
, ChildrenInsertRequest
) {
990 // Set an expected data file containing the children entry.
991 expected_content_type_
= "application/json";
992 expected_content_
= kTestChildrenResponse
;
994 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
996 // Add a resource with "resource_id" to a directory with
997 // "parent_resource_id".
999 base::RunLoop run_loop
;
1000 drive::ChildrenInsertRequest
* request
= new drive::ChildrenInsertRequest(
1001 request_sender_
.get(),
1003 test_util::CreateQuitCallback(
1005 test_util::CreateCopyResultCallback(&error
)));
1006 request
->set_folder_id("parent_resource_id");
1007 request
->set_id("resource_id");
1008 request_sender_
->StartRequestWithAuthRetry(request
);
1012 EXPECT_EQ(HTTP_SUCCESS
, error
);
1013 EXPECT_EQ(net::test_server::METHOD_POST
, http_request_
.method
);
1014 EXPECT_EQ("/drive/v2/files/parent_resource_id/children",
1015 http_request_
.relative_url
);
1016 EXPECT_EQ("application/json", http_request_
.headers
["Content-Type"]);
1018 EXPECT_TRUE(http_request_
.has_content
);
1019 EXPECT_EQ("{\"id\":\"resource_id\"}", http_request_
.content
);
1022 TEST_F(DriveApiRequestsTest
, ChildrenDeleteRequest
) {
1023 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
1025 // Remove a resource with "resource_id" from a directory with
1026 // "parent_resource_id".
1028 base::RunLoop run_loop
;
1029 drive::ChildrenDeleteRequest
* request
= new drive::ChildrenDeleteRequest(
1030 request_sender_
.get(),
1032 test_util::CreateQuitCallback(
1034 test_util::CreateCopyResultCallback(&error
)));
1035 request
->set_child_id("resource_id");
1036 request
->set_folder_id("parent_resource_id");
1037 request_sender_
->StartRequestWithAuthRetry(request
);
1041 EXPECT_EQ(HTTP_NO_CONTENT
, error
);
1042 EXPECT_EQ(net::test_server::METHOD_DELETE
, http_request_
.method
);
1043 EXPECT_EQ("/drive/v2/files/parent_resource_id/children/resource_id",
1044 http_request_
.relative_url
);
1045 EXPECT_FALSE(http_request_
.has_content
);
1048 TEST_F(DriveApiRequestsTest
, UploadNewFileRequest
) {
1049 // Set an expected url for uploading.
1050 expected_upload_path_
= kTestUploadNewFilePath
;
1052 const char kTestContentType
[] = "text/plain";
1053 const std::string
kTestContent(100, 'a');
1054 const base::FilePath kTestFilePath
=
1055 temp_dir_
.path().AppendASCII("upload_file.txt");
1056 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath
, kTestContent
));
1058 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
1061 // Initiate uploading a new file to the directory with
1062 // "parent_resource_id".
1064 base::RunLoop run_loop
;
1065 drive::InitiateUploadNewFileRequest
* request
=
1066 new drive::InitiateUploadNewFileRequest(
1067 request_sender_
.get(),
1070 kTestContent
.size(),
1071 "parent_resource_id", // The resource id of the parent directory.
1072 "new file title", // The title of the file being uploaded.
1073 test_util::CreateQuitCallback(
1075 test_util::CreateCopyResultCallback(&error
, &upload_url
)));
1076 request
->set_properties(testing_properties_
);
1077 request_sender_
->StartRequestWithAuthRetry(request
);
1081 EXPECT_EQ(HTTP_SUCCESS
, error
);
1082 EXPECT_EQ(kTestUploadNewFilePath
, upload_url
.path());
1083 EXPECT_EQ(kTestContentType
, http_request_
.headers
["X-Upload-Content-Type"]);
1084 EXPECT_EQ(base::Int64ToString(kTestContent
.size()),
1085 http_request_
.headers
["X-Upload-Content-Length"]);
1087 EXPECT_EQ(net::test_server::METHOD_POST
, http_request_
.method
);
1088 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
1089 http_request_
.relative_url
);
1090 EXPECT_EQ("application/json", http_request_
.headers
["Content-Type"]);
1091 EXPECT_TRUE(http_request_
.has_content
);
1094 "\"id\":\"parent_resource_id\","
1095 "\"kind\":\"drive#fileLink\""
1098 "{\"key\":\"key1\",\"value\":\"value1\",\"visibility\":\"PRIVATE\"},"
1099 "{\"key\":\"key2\",\"value\":\"value2\",\"visibility\":\"PUBLIC\"}],"
1100 "\"title\":\"new file title\"}",
1101 http_request_
.content
);
1103 // Upload the content to the upload URL.
1104 UploadRangeResponse response
;
1105 scoped_ptr
<FileResource
> new_entry
;
1108 base::RunLoop run_loop
;
1109 drive::ResumeUploadRequest
* resume_request
=
1110 new drive::ResumeUploadRequest(
1111 request_sender_
.get(),
1113 0, // start_position
1114 kTestContent
.size(), // end_position (exclusive)
1115 kTestContent
.size(), // content_length,
1118 test_util::CreateQuitCallback(
1120 test_util::CreateCopyResultCallback(&response
, &new_entry
)),
1121 ProgressCallback());
1122 request_sender_
->StartRequestWithAuthRetry(resume_request
);
1126 // METHOD_PUT should be used to upload data.
1127 EXPECT_EQ(net::test_server::METHOD_PUT
, http_request_
.method
);
1128 // Request should go to the upload URL.
1129 EXPECT_EQ(upload_url
.path(), http_request_
.relative_url
);
1130 // Content-Range header should be added.
1131 EXPECT_EQ("bytes 0-" +
1132 base::Int64ToString(kTestContent
.size() - 1) + "/" +
1133 base::Int64ToString(kTestContent
.size()),
1134 http_request_
.headers
["Content-Range"]);
1135 // The upload content should be set in the HTTP request.
1136 EXPECT_TRUE(http_request_
.has_content
);
1137 EXPECT_EQ(kTestContent
, http_request_
.content
);
1139 // Check the response.
1140 EXPECT_EQ(HTTP_CREATED
, response
.code
); // Because it's a new file
1141 // The start and end positions should be set to -1, if an upload is complete.
1142 EXPECT_EQ(-1, response
.start_position_received
);
1143 EXPECT_EQ(-1, response
.end_position_received
);
1146 TEST_F(DriveApiRequestsTest
, UploadNewEmptyFileRequest
) {
1147 // Set an expected url for uploading.
1148 expected_upload_path_
= kTestUploadNewFilePath
;
1150 const char kTestContentType
[] = "text/plain";
1151 const char kTestContent
[] = "";
1152 const base::FilePath kTestFilePath
=
1153 temp_dir_
.path().AppendASCII("empty_file.txt");
1154 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath
, kTestContent
));
1156 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
1159 // Initiate uploading a new file to the directory with "parent_resource_id".
1161 base::RunLoop run_loop
;
1162 drive::InitiateUploadNewFileRequest
* request
=
1163 new drive::InitiateUploadNewFileRequest(
1164 request_sender_
.get(),
1168 "parent_resource_id", // The resource id of the parent directory.
1169 "new file title", // The title of the file being uploaded.
1170 test_util::CreateQuitCallback(
1172 test_util::CreateCopyResultCallback(&error
, &upload_url
)));
1173 request_sender_
->StartRequestWithAuthRetry(request
);
1177 EXPECT_EQ(HTTP_SUCCESS
, error
);
1178 EXPECT_EQ(kTestUploadNewFilePath
, upload_url
.path());
1179 EXPECT_EQ(kTestContentType
, http_request_
.headers
["X-Upload-Content-Type"]);
1180 EXPECT_EQ("0", http_request_
.headers
["X-Upload-Content-Length"]);
1182 EXPECT_EQ(net::test_server::METHOD_POST
, http_request_
.method
);
1183 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
1184 http_request_
.relative_url
);
1185 EXPECT_EQ("application/json", http_request_
.headers
["Content-Type"]);
1186 EXPECT_TRUE(http_request_
.has_content
);
1187 EXPECT_EQ("{\"parents\":[{"
1188 "\"id\":\"parent_resource_id\","
1189 "\"kind\":\"drive#fileLink\""
1191 "\"title\":\"new file title\"}",
1192 http_request_
.content
);
1194 // Upload the content to the upload URL.
1195 UploadRangeResponse response
;
1196 scoped_ptr
<FileResource
> new_entry
;
1199 base::RunLoop run_loop
;
1200 drive::ResumeUploadRequest
* resume_request
=
1201 new drive::ResumeUploadRequest(
1202 request_sender_
.get(),
1204 0, // start_position
1205 0, // end_position (exclusive)
1206 0, // content_length,
1209 test_util::CreateQuitCallback(
1211 test_util::CreateCopyResultCallback(&response
, &new_entry
)),
1212 ProgressCallback());
1213 request_sender_
->StartRequestWithAuthRetry(resume_request
);
1217 // METHOD_PUT should be used to upload data.
1218 EXPECT_EQ(net::test_server::METHOD_PUT
, http_request_
.method
);
1219 // Request should go to the upload URL.
1220 EXPECT_EQ(upload_url
.path(), http_request_
.relative_url
);
1221 // Content-Range header should NOT be added.
1222 EXPECT_EQ(0U, http_request_
.headers
.count("Content-Range"));
1223 // The upload content should be set in the HTTP request.
1224 EXPECT_TRUE(http_request_
.has_content
);
1225 EXPECT_EQ(kTestContent
, http_request_
.content
);
1227 // Check the response.
1228 EXPECT_EQ(HTTP_CREATED
, response
.code
); // Because it's a new file
1229 // The start and end positions should be set to -1, if an upload is complete.
1230 EXPECT_EQ(-1, response
.start_position_received
);
1231 EXPECT_EQ(-1, response
.end_position_received
);
1234 TEST_F(DriveApiRequestsTest
, UploadNewLargeFileRequest
) {
1235 // Set an expected url for uploading.
1236 expected_upload_path_
= kTestUploadNewFilePath
;
1238 const char kTestContentType
[] = "text/plain";
1239 const size_t kNumChunkBytes
= 10; // Num bytes in a chunk.
1240 const std::string
kTestContent(100, 'a');
1241 const base::FilePath kTestFilePath
=
1242 temp_dir_
.path().AppendASCII("upload_file.txt");
1243 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath
, kTestContent
));
1245 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
1248 // Initiate uploading a new file to the directory with "parent_resource_id".
1250 base::RunLoop run_loop
;
1251 drive::InitiateUploadNewFileRequest
* request
=
1252 new drive::InitiateUploadNewFileRequest(
1253 request_sender_
.get(),
1256 kTestContent
.size(),
1257 "parent_resource_id", // The resource id of the parent directory.
1258 "new file title", // The title of the file being uploaded.
1259 test_util::CreateQuitCallback(
1261 test_util::CreateCopyResultCallback(&error
, &upload_url
)));
1262 request_sender_
->StartRequestWithAuthRetry(request
);
1266 EXPECT_EQ(HTTP_SUCCESS
, error
);
1267 EXPECT_EQ(kTestUploadNewFilePath
, upload_url
.path());
1268 EXPECT_EQ(kTestContentType
, http_request_
.headers
["X-Upload-Content-Type"]);
1269 EXPECT_EQ(base::Int64ToString(kTestContent
.size()),
1270 http_request_
.headers
["X-Upload-Content-Length"]);
1272 EXPECT_EQ(net::test_server::METHOD_POST
, http_request_
.method
);
1273 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
1274 http_request_
.relative_url
);
1275 EXPECT_EQ("application/json", http_request_
.headers
["Content-Type"]);
1276 EXPECT_TRUE(http_request_
.has_content
);
1277 EXPECT_EQ("{\"parents\":[{"
1278 "\"id\":\"parent_resource_id\","
1279 "\"kind\":\"drive#fileLink\""
1281 "\"title\":\"new file title\"}",
1282 http_request_
.content
);
1284 // Before sending any data, check the current status.
1285 // This is an edge case test for GetUploadStatusRequest.
1287 UploadRangeResponse response
;
1288 scoped_ptr
<FileResource
> new_entry
;
1290 // Check the response by GetUploadStatusRequest.
1292 base::RunLoop run_loop
;
1293 drive::GetUploadStatusRequest
* get_upload_status_request
=
1294 new drive::GetUploadStatusRequest(
1295 request_sender_
.get(),
1297 kTestContent
.size(),
1298 test_util::CreateQuitCallback(
1300 test_util::CreateCopyResultCallback(&response
, &new_entry
)));
1301 request_sender_
->StartRequestWithAuthRetry(get_upload_status_request
);
1305 // METHOD_PUT should be used to upload data.
1306 EXPECT_EQ(net::test_server::METHOD_PUT
, http_request_
.method
);
1307 // Request should go to the upload URL.
1308 EXPECT_EQ(upload_url
.path(), http_request_
.relative_url
);
1309 // Content-Range header should be added.
1310 EXPECT_EQ("bytes */" + base::Int64ToString(kTestContent
.size()),
1311 http_request_
.headers
["Content-Range"]);
1312 EXPECT_TRUE(http_request_
.has_content
);
1313 EXPECT_TRUE(http_request_
.content
.empty());
1315 // Check the response.
1316 EXPECT_EQ(HTTP_RESUME_INCOMPLETE
, response
.code
);
1317 EXPECT_EQ(0, response
.start_position_received
);
1318 EXPECT_EQ(0, response
.end_position_received
);
1321 // Upload the content to the upload URL.
1322 for (size_t start_position
= 0; start_position
< kTestContent
.size();
1323 start_position
+= kNumChunkBytes
) {
1324 const std::string payload
= kTestContent
.substr(
1326 std::min(kNumChunkBytes
, kTestContent
.size() - start_position
));
1327 const size_t end_position
= start_position
+ payload
.size();
1329 UploadRangeResponse response
;
1330 scoped_ptr
<FileResource
> new_entry
;
1333 base::RunLoop run_loop
;
1334 drive::ResumeUploadRequest
* resume_request
=
1335 new drive::ResumeUploadRequest(
1336 request_sender_
.get(),
1340 kTestContent
.size(), // content_length,
1343 test_util::CreateQuitCallback(
1345 test_util::CreateCopyResultCallback(&response
, &new_entry
)),
1346 ProgressCallback());
1347 request_sender_
->StartRequestWithAuthRetry(resume_request
);
1351 // METHOD_PUT should be used to upload data.
1352 EXPECT_EQ(net::test_server::METHOD_PUT
, http_request_
.method
);
1353 // Request should go to the upload URL.
1354 EXPECT_EQ(upload_url
.path(), http_request_
.relative_url
);
1355 // Content-Range header should be added.
1356 EXPECT_EQ("bytes " +
1357 base::Int64ToString(start_position
) + "-" +
1358 base::Int64ToString(end_position
- 1) + "/" +
1359 base::Int64ToString(kTestContent
.size()),
1360 http_request_
.headers
["Content-Range"]);
1361 // The upload content should be set in the HTTP request.
1362 EXPECT_TRUE(http_request_
.has_content
);
1363 EXPECT_EQ(payload
, http_request_
.content
);
1365 if (end_position
== kTestContent
.size()) {
1366 // Check the response.
1367 EXPECT_EQ(HTTP_CREATED
, response
.code
); // Because it's a new file
1368 // The start and end positions should be set to -1, if an upload is
1370 EXPECT_EQ(-1, response
.start_position_received
);
1371 EXPECT_EQ(-1, response
.end_position_received
);
1375 // Check the response.
1376 EXPECT_EQ(HTTP_RESUME_INCOMPLETE
, response
.code
);
1377 EXPECT_EQ(0, response
.start_position_received
);
1378 EXPECT_EQ(static_cast<int64
>(end_position
), response
.end_position_received
);
1380 // Check the response by GetUploadStatusRequest.
1382 base::RunLoop run_loop
;
1383 drive::GetUploadStatusRequest
* get_upload_status_request
=
1384 new drive::GetUploadStatusRequest(
1385 request_sender_
.get(),
1387 kTestContent
.size(),
1388 test_util::CreateQuitCallback(
1390 test_util::CreateCopyResultCallback(&response
, &new_entry
)));
1391 request_sender_
->StartRequestWithAuthRetry(get_upload_status_request
);
1395 // METHOD_PUT should be used to upload data.
1396 EXPECT_EQ(net::test_server::METHOD_PUT
, http_request_
.method
);
1397 // Request should go to the upload URL.
1398 EXPECT_EQ(upload_url
.path(), http_request_
.relative_url
);
1399 // Content-Range header should be added.
1400 EXPECT_EQ("bytes */" + base::Int64ToString(kTestContent
.size()),
1401 http_request_
.headers
["Content-Range"]);
1402 EXPECT_TRUE(http_request_
.has_content
);
1403 EXPECT_TRUE(http_request_
.content
.empty());
1405 // Check the response.
1406 EXPECT_EQ(HTTP_RESUME_INCOMPLETE
, response
.code
);
1407 EXPECT_EQ(0, response
.start_position_received
);
1408 EXPECT_EQ(static_cast<int64
>(end_position
),
1409 response
.end_position_received
);
1413 TEST_F(DriveApiRequestsTest
, UploadNewFileWithMetadataRequest
) {
1414 const base::Time::Exploded kModifiedDate
= {2012, 7, 0, 19, 15, 59, 13, 123};
1415 const base::Time::Exploded kLastViewedByMeDate
=
1416 {2013, 7, 0, 19, 15, 59, 13, 123};
1418 // Set an expected url for uploading.
1419 expected_upload_path_
= kTestUploadNewFilePath
;
1421 const char kTestContentType
[] = "text/plain";
1422 const std::string
kTestContent(100, 'a');
1424 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
1427 // Initiate uploading a new file to the directory with "parent_resource_id".
1429 base::RunLoop run_loop
;
1430 drive::InitiateUploadNewFileRequest
* request
=
1431 new drive::InitiateUploadNewFileRequest(
1432 request_sender_
.get(),
1435 kTestContent
.size(),
1436 "parent_resource_id", // The resource id of the parent directory.
1437 "new file title", // The title of the file being uploaded.
1438 test_util::CreateQuitCallback(
1440 test_util::CreateCopyResultCallback(&error
, &upload_url
)));
1441 request
->set_modified_date(base::Time::FromUTCExploded(kModifiedDate
));
1442 request
->set_last_viewed_by_me_date(
1443 base::Time::FromUTCExploded(kLastViewedByMeDate
));
1444 request_sender_
->StartRequestWithAuthRetry(request
);
1448 EXPECT_EQ(HTTP_SUCCESS
, error
);
1449 EXPECT_EQ(kTestUploadNewFilePath
, upload_url
.path());
1450 EXPECT_EQ(kTestContentType
, http_request_
.headers
["X-Upload-Content-Type"]);
1451 EXPECT_EQ(base::Int64ToString(kTestContent
.size()),
1452 http_request_
.headers
["X-Upload-Content-Length"]);
1454 EXPECT_EQ(net::test_server::METHOD_POST
, http_request_
.method
);
1455 EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable&setModifiedDate=true",
1456 http_request_
.relative_url
);
1457 EXPECT_EQ("application/json", http_request_
.headers
["Content-Type"]);
1458 EXPECT_TRUE(http_request_
.has_content
);
1459 EXPECT_EQ("{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
1460 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
1461 "\"parents\":[{\"id\":\"parent_resource_id\","
1462 "\"kind\":\"drive#fileLink\"}],"
1463 "\"title\":\"new file title\"}",
1464 http_request_
.content
);
1467 TEST_F(DriveApiRequestsTest
, UploadExistingFileRequest
) {
1468 // Set an expected url for uploading.
1469 expected_upload_path_
= kTestUploadExistingFilePath
;
1471 const char kTestContentType
[] = "text/plain";
1472 const std::string
kTestContent(100, 'a');
1473 const base::FilePath kTestFilePath
=
1474 temp_dir_
.path().AppendASCII("upload_file.txt");
1475 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath
, kTestContent
));
1477 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
1480 // Initiate uploading a new file to the directory with "parent_resource_id".
1482 base::RunLoop run_loop
;
1483 drive::InitiateUploadExistingFileRequest
* request
=
1484 new drive::InitiateUploadExistingFileRequest(
1485 request_sender_
.get(),
1488 kTestContent
.size(),
1489 "resource_id", // The resource id of the file to be overwritten.
1490 std::string(), // No etag.
1491 test_util::CreateQuitCallback(
1493 test_util::CreateCopyResultCallback(&error
, &upload_url
)));
1494 request
->set_properties(testing_properties_
);
1495 request_sender_
->StartRequestWithAuthRetry(request
);
1499 EXPECT_EQ(HTTP_SUCCESS
, error
);
1500 EXPECT_EQ(kTestUploadExistingFilePath
, upload_url
.path());
1501 EXPECT_EQ(kTestContentType
, http_request_
.headers
["X-Upload-Content-Type"]);
1502 EXPECT_EQ(base::Int64ToString(kTestContent
.size()),
1503 http_request_
.headers
["X-Upload-Content-Length"]);
1504 EXPECT_EQ("*", http_request_
.headers
["If-Match"]);
1506 EXPECT_EQ(net::test_server::METHOD_PUT
, http_request_
.method
);
1507 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1508 http_request_
.relative_url
);
1509 EXPECT_TRUE(http_request_
.has_content
);
1512 "{\"key\":\"key1\",\"value\":\"value1\",\"visibility\":\"PRIVATE\"},"
1513 "{\"key\":\"key2\",\"value\":\"value2\",\"visibility\":\"PUBLIC\"}]}",
1514 http_request_
.content
);
1516 // Upload the content to the upload URL.
1517 UploadRangeResponse response
;
1518 scoped_ptr
<FileResource
> new_entry
;
1521 base::RunLoop run_loop
;
1522 drive::ResumeUploadRequest
* resume_request
=
1523 new drive::ResumeUploadRequest(
1524 request_sender_
.get(),
1526 0, // start_position
1527 kTestContent
.size(), // end_position (exclusive)
1528 kTestContent
.size(), // content_length,
1531 test_util::CreateQuitCallback(
1533 test_util::CreateCopyResultCallback(&response
, &new_entry
)),
1534 ProgressCallback());
1535 request_sender_
->StartRequestWithAuthRetry(resume_request
);
1539 // METHOD_PUT should be used to upload data.
1540 EXPECT_EQ(net::test_server::METHOD_PUT
, http_request_
.method
);
1541 // Request should go to the upload URL.
1542 EXPECT_EQ(upload_url
.path(), http_request_
.relative_url
);
1543 // Content-Range header should be added.
1544 EXPECT_EQ("bytes 0-" +
1545 base::Int64ToString(kTestContent
.size() - 1) + "/" +
1546 base::Int64ToString(kTestContent
.size()),
1547 http_request_
.headers
["Content-Range"]);
1548 // The upload content should be set in the HTTP request.
1549 EXPECT_TRUE(http_request_
.has_content
);
1550 EXPECT_EQ(kTestContent
, http_request_
.content
);
1552 // Check the response.
1553 EXPECT_EQ(HTTP_SUCCESS
, response
.code
); // Because it's an existing file
1554 // The start and end positions should be set to -1, if an upload is complete.
1555 EXPECT_EQ(-1, response
.start_position_received
);
1556 EXPECT_EQ(-1, response
.end_position_received
);
1559 TEST_F(DriveApiRequestsTest
, UploadExistingFileRequestWithETag
) {
1560 // Set an expected url for uploading.
1561 expected_upload_path_
= kTestUploadExistingFilePath
;
1563 const char kTestContentType
[] = "text/plain";
1564 const std::string
kTestContent(100, 'a');
1565 const base::FilePath kTestFilePath
=
1566 temp_dir_
.path().AppendASCII("upload_file.txt");
1567 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath
, kTestContent
));
1569 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
1572 // Initiate uploading a new file to the directory with "parent_resource_id".
1574 base::RunLoop run_loop
;
1575 drive::InitiateUploadExistingFileRequest
* request
=
1576 new drive::InitiateUploadExistingFileRequest(
1577 request_sender_
.get(),
1580 kTestContent
.size(),
1581 "resource_id", // The resource id of the file to be overwritten.
1583 test_util::CreateQuitCallback(
1585 test_util::CreateCopyResultCallback(&error
, &upload_url
)));
1586 request_sender_
->StartRequestWithAuthRetry(request
);
1590 EXPECT_EQ(HTTP_SUCCESS
, error
);
1591 EXPECT_EQ(kTestUploadExistingFilePath
, upload_url
.path());
1592 EXPECT_EQ(kTestContentType
, http_request_
.headers
["X-Upload-Content-Type"]);
1593 EXPECT_EQ(base::Int64ToString(kTestContent
.size()),
1594 http_request_
.headers
["X-Upload-Content-Length"]);
1595 EXPECT_EQ(kTestETag
, http_request_
.headers
["If-Match"]);
1597 EXPECT_EQ(net::test_server::METHOD_PUT
, http_request_
.method
);
1598 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1599 http_request_
.relative_url
);
1600 EXPECT_TRUE(http_request_
.has_content
);
1601 EXPECT_TRUE(http_request_
.content
.empty());
1603 // Upload the content to the upload URL.
1604 UploadRangeResponse response
;
1605 scoped_ptr
<FileResource
> new_entry
;
1608 base::RunLoop run_loop
;
1609 drive::ResumeUploadRequest
* resume_request
=
1610 new drive::ResumeUploadRequest(
1611 request_sender_
.get(),
1613 0, // start_position
1614 kTestContent
.size(), // end_position (exclusive)
1615 kTestContent
.size(), // content_length,
1618 test_util::CreateQuitCallback(
1620 test_util::CreateCopyResultCallback(&response
, &new_entry
)),
1621 ProgressCallback());
1622 request_sender_
->StartRequestWithAuthRetry(resume_request
);
1626 // METHOD_PUT should be used to upload data.
1627 EXPECT_EQ(net::test_server::METHOD_PUT
, http_request_
.method
);
1628 // Request should go to the upload URL.
1629 EXPECT_EQ(upload_url
.path(), http_request_
.relative_url
);
1630 // Content-Range header should be added.
1631 EXPECT_EQ("bytes 0-" +
1632 base::Int64ToString(kTestContent
.size() - 1) + "/" +
1633 base::Int64ToString(kTestContent
.size()),
1634 http_request_
.headers
["Content-Range"]);
1635 // The upload content should be set in the HTTP request.
1636 EXPECT_TRUE(http_request_
.has_content
);
1637 EXPECT_EQ(kTestContent
, http_request_
.content
);
1639 // Check the response.
1640 EXPECT_EQ(HTTP_SUCCESS
, response
.code
); // Because it's an existing file
1641 // The start and end positions should be set to -1, if an upload is complete.
1642 EXPECT_EQ(-1, response
.start_position_received
);
1643 EXPECT_EQ(-1, response
.end_position_received
);
1646 TEST_F(DriveApiRequestsTest
, UploadExistingFileRequestWithETagConflicting
) {
1647 // Set an expected url for uploading.
1648 expected_upload_path_
= kTestUploadExistingFilePath
;
1650 // If it turned out that the etag is conflicting, PRECONDITION_FAILED should
1652 expected_precondition_failed_file_path_
=
1653 test_util::GetTestFilePath("drive/error.json");
1655 const char kTestContentType
[] = "text/plain";
1656 const std::string
kTestContent(100, 'a');
1658 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
1661 // Initiate uploading a new file to the directory with "parent_resource_id".
1663 base::RunLoop run_loop
;
1664 drive::InitiateUploadExistingFileRequest
* request
=
1665 new drive::InitiateUploadExistingFileRequest(
1666 request_sender_
.get(),
1669 kTestContent
.size(),
1670 "resource_id", // The resource id of the file to be overwritten.
1672 test_util::CreateQuitCallback(
1674 test_util::CreateCopyResultCallback(&error
, &upload_url
)));
1675 request_sender_
->StartRequestWithAuthRetry(request
);
1679 EXPECT_EQ(HTTP_PRECONDITION
, error
);
1680 EXPECT_EQ(kTestContentType
, http_request_
.headers
["X-Upload-Content-Type"]);
1681 EXPECT_EQ(base::Int64ToString(kTestContent
.size()),
1682 http_request_
.headers
["X-Upload-Content-Length"]);
1683 EXPECT_EQ("Conflicting-etag", http_request_
.headers
["If-Match"]);
1685 EXPECT_EQ(net::test_server::METHOD_PUT
, http_request_
.method
);
1686 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1687 http_request_
.relative_url
);
1688 EXPECT_TRUE(http_request_
.has_content
);
1689 EXPECT_TRUE(http_request_
.content
.empty());
1692 TEST_F(DriveApiRequestsTest
,
1693 UploadExistingFileRequestWithETagConflictOnResumeUpload
) {
1694 // Set an expected url for uploading.
1695 expected_upload_path_
= kTestUploadExistingFilePath
;
1697 const char kTestContentType
[] = "text/plain";
1698 const std::string
kTestContent(100, 'a');
1699 const base::FilePath kTestFilePath
=
1700 temp_dir_
.path().AppendASCII("upload_file.txt");
1701 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath
, kTestContent
));
1703 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
1706 // Initiate uploading a new file to the directory with "parent_resource_id".
1708 base::RunLoop run_loop
;
1709 drive::InitiateUploadExistingFileRequest
* request
=
1710 new drive::InitiateUploadExistingFileRequest(
1711 request_sender_
.get(),
1714 kTestContent
.size(),
1715 "resource_id", // The resource id of the file to be overwritten.
1717 test_util::CreateQuitCallback(
1719 test_util::CreateCopyResultCallback(&error
, &upload_url
)));
1720 request_sender_
->StartRequestWithAuthRetry(request
);
1724 EXPECT_EQ(HTTP_SUCCESS
, error
);
1725 EXPECT_EQ(kTestUploadExistingFilePath
, upload_url
.path());
1726 EXPECT_EQ(kTestContentType
, http_request_
.headers
["X-Upload-Content-Type"]);
1727 EXPECT_EQ(base::Int64ToString(kTestContent
.size()),
1728 http_request_
.headers
["X-Upload-Content-Length"]);
1729 EXPECT_EQ(kTestETag
, http_request_
.headers
["If-Match"]);
1731 EXPECT_EQ(net::test_server::METHOD_PUT
, http_request_
.method
);
1732 EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1733 http_request_
.relative_url
);
1734 EXPECT_TRUE(http_request_
.has_content
);
1735 EXPECT_TRUE(http_request_
.content
.empty());
1737 // Set PRECONDITION_FAILED to the server. This is the emulation of the
1738 // confliction during uploading.
1739 expected_precondition_failed_file_path_
=
1740 test_util::GetTestFilePath("drive/error.json");
1742 // Upload the content to the upload URL.
1743 UploadRangeResponse response
;
1744 scoped_ptr
<FileResource
> new_entry
;
1747 base::RunLoop run_loop
;
1748 drive::ResumeUploadRequest
* resume_request
=
1749 new drive::ResumeUploadRequest(
1750 request_sender_
.get(),
1752 0, // start_position
1753 kTestContent
.size(), // end_position (exclusive)
1754 kTestContent
.size(), // content_length,
1757 test_util::CreateQuitCallback(
1759 test_util::CreateCopyResultCallback(&response
, &new_entry
)),
1760 ProgressCallback());
1761 request_sender_
->StartRequestWithAuthRetry(resume_request
);
1765 // METHOD_PUT should be used to upload data.
1766 EXPECT_EQ(net::test_server::METHOD_PUT
, http_request_
.method
);
1767 // Request should go to the upload URL.
1768 EXPECT_EQ(upload_url
.path(), http_request_
.relative_url
);
1769 // Content-Range header should be added.
1770 EXPECT_EQ("bytes 0-" +
1771 base::Int64ToString(kTestContent
.size() - 1) + "/" +
1772 base::Int64ToString(kTestContent
.size()),
1773 http_request_
.headers
["Content-Range"]);
1774 // The upload content should be set in the HTTP request.
1775 EXPECT_TRUE(http_request_
.has_content
);
1776 EXPECT_EQ(kTestContent
, http_request_
.content
);
1778 // Check the response.
1779 EXPECT_EQ(HTTP_PRECONDITION
, response
.code
);
1780 // The start and end positions should be set to -1 for error.
1781 EXPECT_EQ(-1, response
.start_position_received
);
1782 EXPECT_EQ(-1, response
.end_position_received
);
1784 // New entry should be NULL.
1785 EXPECT_FALSE(new_entry
.get());
1788 TEST_F(DriveApiRequestsTest
, UploadExistingFileWithMetadataRequest
) {
1789 const base::Time::Exploded kModifiedDate
= {2012, 7, 0, 19, 15, 59, 13, 123};
1790 const base::Time::Exploded kLastViewedByMeDate
=
1791 {2013, 7, 0, 19, 15, 59, 13, 123};
1793 // Set an expected url for uploading.
1794 expected_upload_path_
= kTestUploadExistingFilePath
;
1796 const char kTestContentType
[] = "text/plain";
1797 const std::string
kTestContent(100, 'a');
1799 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
1802 // Initiate uploading a new file to the directory with "parent_resource_id".
1804 base::RunLoop run_loop
;
1805 drive::InitiateUploadExistingFileRequest
* request
=
1806 new drive::InitiateUploadExistingFileRequest(
1807 request_sender_
.get(),
1810 kTestContent
.size(),
1811 "resource_id", // The resource id of the file to be overwritten.
1813 test_util::CreateQuitCallback(
1815 test_util::CreateCopyResultCallback(&error
, &upload_url
)));
1816 request
->set_parent_resource_id("new_parent_resource_id");
1817 request
->set_title("new file title");
1818 request
->set_modified_date(base::Time::FromUTCExploded(kModifiedDate
));
1819 request
->set_last_viewed_by_me_date(
1820 base::Time::FromUTCExploded(kLastViewedByMeDate
));
1822 request_sender_
->StartRequestWithAuthRetry(request
);
1826 EXPECT_EQ(HTTP_SUCCESS
, error
);
1827 EXPECT_EQ(kTestUploadExistingFilePath
, upload_url
.path());
1828 EXPECT_EQ(kTestContentType
, http_request_
.headers
["X-Upload-Content-Type"]);
1829 EXPECT_EQ(base::Int64ToString(kTestContent
.size()),
1830 http_request_
.headers
["X-Upload-Content-Length"]);
1831 EXPECT_EQ(kTestETag
, http_request_
.headers
["If-Match"]);
1833 EXPECT_EQ(net::test_server::METHOD_PUT
, http_request_
.method
);
1834 EXPECT_EQ("/upload/drive/v2/files/resource_id?"
1835 "uploadType=resumable&setModifiedDate=true",
1836 http_request_
.relative_url
);
1837 EXPECT_EQ("application/json", http_request_
.headers
["Content-Type"]);
1838 EXPECT_TRUE(http_request_
.has_content
);
1839 EXPECT_EQ("{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
1840 "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
1841 "\"parents\":[{\"id\":\"new_parent_resource_id\","
1842 "\"kind\":\"drive#fileLink\"}],"
1843 "\"title\":\"new file title\"}",
1844 http_request_
.content
);
1847 TEST_F(DriveApiRequestsTest
, DownloadFileRequest
) {
1848 const base::FilePath kDownloadedFilePath
=
1849 temp_dir_
.path().AppendASCII("cache_file");
1850 const std::string
kTestId("dummyId");
1852 DriveApiErrorCode result_code
= DRIVE_OTHER_ERROR
;
1853 base::FilePath temp_file
;
1855 base::RunLoop run_loop
;
1856 drive::DownloadFileRequest
* request
= new drive::DownloadFileRequest(
1857 request_sender_
.get(),
1860 kDownloadedFilePath
,
1861 test_util::CreateQuitCallback(
1863 test_util::CreateCopyResultCallback(&result_code
, &temp_file
)),
1864 GetContentCallback(),
1865 ProgressCallback());
1866 request_sender_
->StartRequestWithAuthRetry(request
);
1870 std::string contents
;
1871 base::ReadFileToString(temp_file
, &contents
);
1872 base::DeleteFile(temp_file
, false);
1874 EXPECT_EQ(HTTP_SUCCESS
, result_code
);
1875 EXPECT_EQ(net::test_server::METHOD_GET
, http_request_
.method
);
1876 EXPECT_EQ(kTestDownloadPathPrefix
+ kTestId
, http_request_
.relative_url
);
1877 EXPECT_EQ(kDownloadedFilePath
, temp_file
);
1879 const std::string expected_contents
= kTestId
+ kTestId
+ kTestId
;
1880 EXPECT_EQ(expected_contents
, contents
);
1883 TEST_F(DriveApiRequestsTest
, DownloadFileRequest_GetContentCallback
) {
1884 const base::FilePath kDownloadedFilePath
=
1885 temp_dir_
.path().AppendASCII("cache_file");
1886 const std::string
kTestId("dummyId");
1888 DriveApiErrorCode result_code
= DRIVE_OTHER_ERROR
;
1889 base::FilePath temp_file
;
1890 std::string contents
;
1892 base::RunLoop run_loop
;
1893 drive::DownloadFileRequest
* request
= new drive::DownloadFileRequest(
1894 request_sender_
.get(),
1897 kDownloadedFilePath
,
1898 test_util::CreateQuitCallback(
1900 test_util::CreateCopyResultCallback(&result_code
, &temp_file
)),
1901 base::Bind(&AppendContent
, &contents
),
1902 ProgressCallback());
1903 request_sender_
->StartRequestWithAuthRetry(request
);
1907 base::DeleteFile(temp_file
, false);
1909 EXPECT_EQ(HTTP_SUCCESS
, result_code
);
1910 EXPECT_EQ(net::test_server::METHOD_GET
, http_request_
.method
);
1911 EXPECT_EQ(kTestDownloadPathPrefix
+ kTestId
, http_request_
.relative_url
);
1912 EXPECT_EQ(kDownloadedFilePath
, temp_file
);
1914 const std::string expected_contents
= kTestId
+ kTestId
+ kTestId
;
1915 EXPECT_EQ(expected_contents
, contents
);
1918 TEST_F(DriveApiRequestsTest
, PermissionsInsertRequest
) {
1919 expected_content_type_
= "application/json";
1920 expected_content_
= kTestPermissionResponse
;
1922 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
1924 // Add comment permission to the user "user@example.com".
1926 base::RunLoop run_loop
;
1927 drive::PermissionsInsertRequest
* request
=
1928 new drive::PermissionsInsertRequest(
1929 request_sender_
.get(),
1931 test_util::CreateQuitCallback(
1933 test_util::CreateCopyResultCallback(&error
)));
1934 request
->set_id("resource_id");
1935 request
->set_role(drive::PERMISSION_ROLE_COMMENTER
);
1936 request
->set_type(drive::PERMISSION_TYPE_USER
);
1937 request
->set_value("user@example.com");
1938 request_sender_
->StartRequestWithAuthRetry(request
);
1942 EXPECT_EQ(HTTP_SUCCESS
, error
);
1943 EXPECT_EQ(net::test_server::METHOD_POST
, http_request_
.method
);
1944 EXPECT_EQ("/drive/v2/files/resource_id/permissions",
1945 http_request_
.relative_url
);
1946 EXPECT_EQ("application/json", http_request_
.headers
["Content-Type"]);
1948 scoped_ptr
<base::Value
> expected
= base::JSONReader::Read(
1949 "{\"additionalRoles\":[\"commenter\"], \"role\":\"reader\", "
1950 "\"type\":\"user\",\"value\":\"user@example.com\"}");
1951 ASSERT_TRUE(expected
);
1953 scoped_ptr
<base::Value
> result
=
1954 base::JSONReader::Read(http_request_
.content
);
1955 EXPECT_TRUE(http_request_
.has_content
);
1956 EXPECT_TRUE(base::Value::Equals(expected
.get(), result
.get()));
1958 // Add "can edit" permission to users in "example.com".
1959 error
= DRIVE_OTHER_ERROR
;
1961 base::RunLoop run_loop
;
1962 drive::PermissionsInsertRequest
* request
=
1963 new drive::PermissionsInsertRequest(
1964 request_sender_
.get(),
1966 test_util::CreateQuitCallback(
1968 test_util::CreateCopyResultCallback(&error
)));
1969 request
->set_id("resource_id2");
1970 request
->set_role(drive::PERMISSION_ROLE_WRITER
);
1971 request
->set_type(drive::PERMISSION_TYPE_DOMAIN
);
1972 request
->set_value("example.com");
1973 request_sender_
->StartRequestWithAuthRetry(request
);
1977 EXPECT_EQ(HTTP_SUCCESS
, error
);
1978 EXPECT_EQ(net::test_server::METHOD_POST
, http_request_
.method
);
1979 EXPECT_EQ("/drive/v2/files/resource_id2/permissions",
1980 http_request_
.relative_url
);
1981 EXPECT_EQ("application/json", http_request_
.headers
["Content-Type"]);
1983 expected
= base::JSONReader::Read(
1984 "{\"role\":\"writer\", \"type\":\"domain\",\"value\":\"example.com\"}");
1985 ASSERT_TRUE(expected
);
1987 result
= base::JSONReader::Read(http_request_
.content
);
1988 EXPECT_TRUE(http_request_
.has_content
);
1989 EXPECT_TRUE(base::Value::Equals(expected
.get(), result
.get()));
1992 TEST_F(DriveApiRequestsTest
, BatchUploadRequest
) {
1993 // Preapre constants.
1994 const char kTestContentType
[] = "text/plain";
1995 const std::string
kTestContent(10, 'a');
1996 const base::FilePath kTestFilePath
=
1997 temp_dir_
.path().AppendASCII("upload_file.txt");
1998 ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath
, kTestContent
));
2000 // Create batch request.
2001 drive::BatchUploadRequest
* const request
=
2002 new drive::BatchUploadRequest(request_sender_
.get(), *url_generator_
);
2003 request
->SetBoundaryForTesting("OUTERBOUNDARY");
2004 request_sender_
->StartRequestWithAuthRetry(request
);
2006 // Create child request.
2007 DriveApiErrorCode errors
[] = {DRIVE_OTHER_ERROR
, DRIVE_OTHER_ERROR
};
2008 scoped_ptr
<FileResource
> file_resources
[2];
2009 base::RunLoop run_loop
[2];
2010 for (int i
= 0; i
< 2; ++i
) {
2011 const FileResourceCallback callback
= test_util::CreateQuitCallback(
2013 test_util::CreateCopyResultCallback(&errors
[i
], &file_resources
[i
]));
2014 drive::MultipartUploadNewFileDelegate
* const child_request
=
2015 new drive::MultipartUploadNewFileDelegate(
2016 request_sender_
->blocking_task_runner(),
2017 base::StringPrintf("new file title %d", i
),
2018 "parent_resource_id", kTestContentType
, kTestContent
.size(),
2019 base::Time(), base::Time(), kTestFilePath
, drive::Properties(),
2020 *url_generator_
, callback
, ProgressCallback());
2021 child_request
->SetBoundaryForTesting("INNERBOUNDARY");
2022 request
->AddRequest(child_request
);
2028 EXPECT_EQ(net::test_server::METHOD_PUT
, http_request_
.method
);
2029 EXPECT_EQ("batch", http_request_
.headers
["X-Goog-Upload-Protocol"]);
2030 EXPECT_EQ("multipart/mixed; boundary=OUTERBOUNDARY",
2031 http_request_
.headers
["Content-Type"]);
2034 "Content-Type: application/http\n"
2036 "POST /upload/drive/v2/files HTTP/1.1\n"
2038 "X-Goog-Upload-Protocol: multipart\n"
2039 "Content-Type: multipart/related; boundary=INNERBOUNDARY\n"
2042 "Content-Type: application/json\n"
2044 "{\"parents\":[{\"id\":\"parent_resource_id\","
2045 "\"kind\":\"drive#fileLink\"}],\"title\":\"new file title 0\"}\n"
2047 "Content-Type: text/plain\n"
2050 "--INNERBOUNDARY--\n"
2052 "Content-Type: application/http\n"
2054 "POST /upload/drive/v2/files HTTP/1.1\n"
2056 "X-Goog-Upload-Protocol: multipart\n"
2057 "Content-Type: multipart/related; boundary=INNERBOUNDARY\n"
2060 "Content-Type: application/json\n"
2062 "{\"parents\":[{\"id\":\"parent_resource_id\","
2063 "\"kind\":\"drive#fileLink\"}],\"title\":\"new file title 1\"}\n"
2065 "Content-Type: text/plain\n"
2068 "--INNERBOUNDARY--\n"
2069 "--OUTERBOUNDARY--",
2070 http_request_
.content
);
2071 EXPECT_EQ(HTTP_SUCCESS
, errors
[0]);
2072 ASSERT_TRUE(file_resources
[0]);
2073 EXPECT_EQ("file_id_1", file_resources
[0]->file_id());
2074 ASSERT_FALSE(file_resources
[1]);
2075 EXPECT_EQ(HTTP_SERVICE_UNAVAILABLE
, errors
[1]);
2078 TEST_F(DriveApiRequestsTest
, EmptyBatchUploadRequest
) {
2079 drive::BatchUploadRequest
* const request
=
2080 new drive::BatchUploadRequest(request_sender_
.get(), *url_generator_
);
2081 base::WeakPtr
<drive::BatchUploadRequest
> weak_ptr
=
2082 request
->GetWeakPtrAsBatchUploadRequest();
2084 ASSERT_FALSE(weak_ptr
.get());
2087 TEST_F(DriveApiRequestsTest
, BatchUploadRequestWithBodyIncludingZero
) {
2088 // Create batch request.
2089 drive::BatchUploadRequest
* const request
=
2090 new drive::BatchUploadRequest(request_sender_
.get(), *url_generator_
);
2091 request
->SetBoundaryForTesting("OUTERBOUNDARY");
2092 request_sender_
->StartRequestWithAuthRetry(request
);
2094 // Create child request.
2097 TestBatchableDelegate
* const child_request
= new TestBatchableDelegate(
2098 GURL("http://example.com/test"), "application/binary",
2099 std::string("Apple\0Orange\0", 13), loop
.QuitClosure());
2100 request
->AddRequest(child_request
);
2105 EXPECT_EQ(net::test_server::METHOD_PUT
, http_request_
.method
);
2106 EXPECT_EQ("batch", http_request_
.headers
["X-Goog-Upload-Protocol"]);
2107 EXPECT_EQ("multipart/mixed; boundary=OUTERBOUNDARY",
2108 http_request_
.headers
["Content-Type"]);
2111 "Content-Type: application/http\n"
2113 "PUT /test HTTP/1.1\n"
2115 "X-Goog-Upload-Protocol: multipart\n"
2116 "Content-Type: application/binary\n"
2118 std::string("Apple\0Orange\0", 13) +
2120 "--OUTERBOUNDARY--",
2121 http_request_
.content
);
2124 TEST_F(DriveApiRequestsTest
, BatchUploadRequestProgress
) {
2125 // Create batch request.
2126 drive::BatchUploadRequest
* const request
=
2127 new drive::BatchUploadRequest(request_sender_
.get(), *url_generator_
);
2128 TestBatchableDelegate
* requests
[] = {
2129 new TestBatchableDelegate(GURL("http://example.com/test"),
2130 "application/binary", std::string(100, 'a'),
2131 base::Bind(&EmptyClosure
)),
2132 new TestBatchableDelegate(GURL("http://example.com/test"),
2133 "application/binary", std::string(50, 'b'),
2134 base::Bind(&EmptyClosure
)),
2135 new TestBatchableDelegate(GURL("http://example.com/test"),
2136 "application/binary", std::string(0, 'c'),
2137 base::Bind(&EmptyClosure
))};
2138 const size_t kExpectedUploadDataPosition
[] = {208, 517, 776};
2139 const size_t kExpectedUploadDataSize
= 851;
2140 request
->AddRequest(requests
[0]);
2141 request
->AddRequest(requests
[1]);
2142 request
->AddRequest(requests
[2]);
2144 request
->Prepare(base::Bind(&EmptyPreapreCallback
));
2146 request
->OnURLFetchUploadProgress(nullptr, 0, kExpectedUploadDataSize
);
2147 request
->OnURLFetchUploadProgress(nullptr, 150, kExpectedUploadDataSize
);
2148 EXPECT_EQ(0u, requests
[0]->progress_values().size());
2149 EXPECT_EQ(0u, requests
[1]->progress_values().size());
2150 EXPECT_EQ(0u, requests
[2]->progress_values().size());
2151 request
->OnURLFetchUploadProgress(nullptr, kExpectedUploadDataPosition
[0],
2152 kExpectedUploadDataSize
);
2153 EXPECT_EQ(1u, requests
[0]->progress_values().size());
2154 EXPECT_EQ(0u, requests
[1]->progress_values().size());
2155 EXPECT_EQ(0u, requests
[2]->progress_values().size());
2156 request
->OnURLFetchUploadProgress(
2157 nullptr, kExpectedUploadDataPosition
[0] + 50, kExpectedUploadDataSize
);
2158 EXPECT_EQ(2u, requests
[0]->progress_values().size());
2159 EXPECT_EQ(0u, requests
[1]->progress_values().size());
2160 EXPECT_EQ(0u, requests
[2]->progress_values().size());
2161 request
->OnURLFetchUploadProgress(
2162 nullptr, kExpectedUploadDataPosition
[1] + 20, kExpectedUploadDataSize
);
2163 EXPECT_EQ(3u, requests
[0]->progress_values().size());
2164 EXPECT_EQ(1u, requests
[1]->progress_values().size());
2165 EXPECT_EQ(0u, requests
[2]->progress_values().size());
2166 request
->OnURLFetchUploadProgress(nullptr, kExpectedUploadDataPosition
[2],
2167 kExpectedUploadDataSize
);
2168 EXPECT_EQ(3u, requests
[0]->progress_values().size());
2169 EXPECT_EQ(2u, requests
[1]->progress_values().size());
2170 EXPECT_EQ(1u, requests
[2]->progress_values().size());
2171 request
->OnURLFetchUploadProgress(nullptr, kExpectedUploadDataSize
,
2172 kExpectedUploadDataSize
);
2173 ASSERT_EQ(3u, requests
[0]->progress_values().size());
2174 EXPECT_EQ(0, requests
[0]->progress_values()[0]);
2175 EXPECT_EQ(50, requests
[0]->progress_values()[1]);
2176 EXPECT_EQ(100, requests
[0]->progress_values()[2]);
2177 ASSERT_EQ(2u, requests
[1]->progress_values().size());
2178 EXPECT_EQ(20, requests
[1]->progress_values()[0]);
2179 EXPECT_EQ(50, requests
[1]->progress_values()[1]);
2180 ASSERT_EQ(1u, requests
[2]->progress_values().size());
2181 EXPECT_EQ(0, requests
[2]->progress_values()[0]);
2186 TEST(ParseMultipartResponseTest
, Empty
) {
2187 std::vector
<drive::MultipartHttpResponse
> parts
;
2188 EXPECT_FALSE(drive::ParseMultipartResponse(
2189 "multipart/mixed; boundary=BOUNDARY", "", &parts
));
2190 EXPECT_FALSE(drive::ParseMultipartResponse("multipart/mixed; boundary=",
2191 "CONTENT", &parts
));
2194 TEST(ParseMultipartResponseTest
, Basic
) {
2195 std::vector
<drive::MultipartHttpResponse
> parts
;
2197 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2199 "Content-Type: application/http\r\n"
2201 "HTTP/1.1 200 OK\r\n"
2207 "Content-Type: application/http\r\n"
2209 "HTTP/1.1 404 Not Found\r\n"
2213 ASSERT_EQ(2u, parts
.size());
2214 EXPECT_EQ(HTTP_SUCCESS
, parts
[0].code
);
2215 EXPECT_EQ("First line\r\nSecond line", parts
[0].body
);
2216 EXPECT_EQ(HTTP_NOT_FOUND
, parts
[1].code
);
2217 EXPECT_EQ("", parts
[1].body
);
2220 TEST(ParseMultipartResponseTest
, InvalidStatusLine
) {
2221 std::vector
<drive::MultipartHttpResponse
> parts
;
2223 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2225 "Content-Type: application/http\r\n"
2227 "InvalidStatusLine 200 \r\n"
2233 ASSERT_EQ(1u, parts
.size());
2234 EXPECT_EQ(DRIVE_PARSE_ERROR
, parts
[0].code
);
2235 EXPECT_EQ("{}", parts
[0].body
);
2238 TEST(ParseMultipartResponseTest
, BoundaryInTheBodyAndPreamble
) {
2239 std::vector
<drive::MultipartHttpResponse
> parts
;
2241 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2245 "Content-Type: application/http\r\n"
2247 "HTTP/1.1 200 OK\r\n"
2253 ASSERT_EQ(1u, parts
.size());
2254 EXPECT_EQ(HTTP_SUCCESS
, parts
[0].code
);
2255 EXPECT_EQ("{--BOUNDARY}", parts
[0].body
);
2258 TEST(ParseMultipartResponseTest
, QuatedBoundary
) {
2259 std::vector
<drive::MultipartHttpResponse
> parts
;
2261 drive::ParseMultipartResponse("multipart/mixed; boundary=\"BOUNDARY\"",
2263 "Content-Type: application/http\r\n"
2265 "HTTP/1.1 200 OK\r\n"
2271 ASSERT_EQ(1u, parts
.size());
2272 EXPECT_EQ(HTTP_SUCCESS
, parts
[0].code
);
2273 EXPECT_EQ("BODY", parts
[0].body
);
2276 TEST(ParseMultipartResponseTest
, BoundaryWithTransportPadding
) {
2277 std::vector
<drive::MultipartHttpResponse
> parts
;
2279 drive::ParseMultipartResponse("multipart/mixed; boundary=BOUNDARY",
2281 "Content-Type: application/http\r\n"
2283 "HTTP/1.1 200 OK\r\n"
2289 ASSERT_EQ(1u, parts
.size());
2290 EXPECT_EQ(HTTP_SUCCESS
, parts
[0].code
);
2291 EXPECT_EQ("BODY", parts
[0].body
);
2293 } // namespace google_apis