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