Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / google_apis / drive / drive_api_requests_unittest.cc
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.
4
5 #include "base/bind.h"
6 #include "base/file_util.h"
7 #include "base/files/file_path.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/values.h"
13 #include "google_apis/drive/drive_api_parser.h"
14 #include "google_apis/drive/drive_api_requests.h"
15 #include "google_apis/drive/drive_api_url_generator.h"
16 #include "google_apis/drive/dummy_auth_service.h"
17 #include "google_apis/drive/request_sender.h"
18 #include "google_apis/drive/test_util.h"
19 #include "net/test/embedded_test_server/embedded_test_server.h"
20 #include "net/test/embedded_test_server/http_request.h"
21 #include "net/test/embedded_test_server/http_response.h"
22 #include "net/url_request/url_request_test_util.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24
25 namespace google_apis {
26
27 namespace {
28
29 const char kTestETag[] = "test_etag";
30 const char kTestUserAgent[] = "test-user-agent";
31
32 const char kTestChildrenResponse[] =
33     "{\n"
34     "\"kind\": \"drive#childReference\",\n"
35     "\"id\": \"resource_id\",\n"
36     "\"selfLink\": \"self_link\",\n"
37     "\"childLink\": \"child_link\",\n"
38     "}\n";
39
40 const char kTestUploadExistingFilePath[] = "/upload/existingfile/path";
41 const char kTestUploadNewFilePath[] = "/upload/newfile/path";
42 const char kTestDownloadPathPrefix[] = "/download/";
43
44 // Used as a GetContentCallback.
45 void AppendContent(std::string* out,
46                    GDataErrorCode error,
47                    scoped_ptr<std::string> content) {
48   EXPECT_EQ(HTTP_SUCCESS, error);
49   out->append(*content);
50 }
51
52 }  // namespace
53
54 class DriveApiRequestsTest : public testing::Test {
55  public:
56   DriveApiRequestsTest() {
57   }
58
59   virtual void SetUp() OVERRIDE {
60     request_context_getter_ = new net::TestURLRequestContextGetter(
61         message_loop_.message_loop_proxy());
62
63     request_sender_.reset(new RequestSender(new DummyAuthService,
64                                             request_context_getter_.get(),
65                                             message_loop_.message_loop_proxy(),
66                                             kTestUserAgent));
67
68     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
69
70     ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady());
71     test_server_.RegisterRequestHandler(
72         base::Bind(&DriveApiRequestsTest::HandleChildrenDeleteRequest,
73                    base::Unretained(this)));
74     test_server_.RegisterRequestHandler(
75         base::Bind(&DriveApiRequestsTest::HandleDataFileRequest,
76                    base::Unretained(this)));
77     test_server_.RegisterRequestHandler(
78         base::Bind(&DriveApiRequestsTest::HandleDeleteRequest,
79                    base::Unretained(this)));
80     test_server_.RegisterRequestHandler(
81         base::Bind(&DriveApiRequestsTest::HandlePreconditionFailedRequest,
82                    base::Unretained(this)));
83     test_server_.RegisterRequestHandler(
84         base::Bind(&DriveApiRequestsTest::HandleResumeUploadRequest,
85                    base::Unretained(this)));
86     test_server_.RegisterRequestHandler(
87         base::Bind(&DriveApiRequestsTest::HandleInitiateUploadRequest,
88                    base::Unretained(this)));
89     test_server_.RegisterRequestHandler(
90         base::Bind(&DriveApiRequestsTest::HandleContentResponse,
91                    base::Unretained(this)));
92     test_server_.RegisterRequestHandler(
93         base::Bind(&DriveApiRequestsTest::HandleDownloadRequest,
94                    base::Unretained(this)));
95
96     GURL test_base_url = test_util::GetBaseUrlForTesting(test_server_.port());
97     url_generator_.reset(new DriveApiUrlGenerator(
98         test_base_url, test_base_url.Resolve(kTestDownloadPathPrefix)));
99
100     // Reset the server's expected behavior just in case.
101     ResetExpectedResponse();
102     received_bytes_ = 0;
103     content_length_ = 0;
104   }
105
106   base::MessageLoopForIO message_loop_;  // Test server needs IO thread.
107   net::test_server::EmbeddedTestServer test_server_;
108   scoped_ptr<RequestSender> request_sender_;
109   scoped_ptr<DriveApiUrlGenerator> url_generator_;
110   scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
111   base::ScopedTempDir temp_dir_;
112
113   // This is a path to the file which contains expected response from
114   // the server. See also HandleDataFileRequest below.
115   base::FilePath expected_data_file_path_;
116
117   // This is a path string in the expected response header from the server
118   // for initiating file uploading.
119   std::string expected_upload_path_;
120
121   // This is a path to the file which contains expected response for
122   // PRECONDITION_FAILED response.
123   base::FilePath expected_precondition_failed_file_path_;
124
125   // These are content and its type in the expected response from the server.
126   // See also HandleContentResponse below.
127   std::string expected_content_type_;
128   std::string expected_content_;
129
130   // The incoming HTTP request is saved so tests can verify the request
131   // parameters like HTTP method (ex. some requests should use DELETE
132   // instead of GET).
133   net::test_server::HttpRequest http_request_;
134
135  private:
136   void ResetExpectedResponse() {
137     expected_data_file_path_.clear();
138     expected_upload_path_.clear();
139     expected_content_type_.clear();
140     expected_content_.clear();
141   }
142
143   // For "Children: delete" request, the server will return "204 No Content"
144   // response meaning "success".
145   scoped_ptr<net::test_server::HttpResponse> HandleChildrenDeleteRequest(
146       const net::test_server::HttpRequest& request) {
147     if (request.method != net::test_server::METHOD_DELETE ||
148         request.relative_url.find("/children/") == string::npos) {
149       // The request is not the "Children: delete" request. Delegate the
150       // processing to the next handler.
151       return scoped_ptr<net::test_server::HttpResponse>();
152     }
153
154     http_request_ = request;
155
156     // Return the response with just "204 No Content" status code.
157     scoped_ptr<net::test_server::BasicHttpResponse> http_response(
158         new net::test_server::BasicHttpResponse);
159     http_response->set_code(net::HTTP_NO_CONTENT);
160     return http_response.PassAs<net::test_server::HttpResponse>();
161   }
162
163   // Reads the data file of |expected_data_file_path_| and returns its content
164   // for the request.
165   // To use this method, it is necessary to set |expected_data_file_path_|
166   // to the appropriate file path before sending the request to the server.
167   scoped_ptr<net::test_server::HttpResponse> HandleDataFileRequest(
168       const net::test_server::HttpRequest& request) {
169     if (expected_data_file_path_.empty()) {
170       // The file is not specified. Delegate the processing to the next
171       // handler.
172       return scoped_ptr<net::test_server::HttpResponse>();
173     }
174
175     http_request_ = request;
176
177     // Return the response from the data file.
178     return test_util::CreateHttpResponseFromFile(
179         expected_data_file_path_).PassAs<net::test_server::HttpResponse>();
180   }
181
182   // Deletes the resource and returns no content with HTTP_NO_CONTENT status
183   // code.
184   scoped_ptr<net::test_server::HttpResponse> HandleDeleteRequest(
185       const net::test_server::HttpRequest& request) {
186     if (request.method != net::test_server::METHOD_DELETE ||
187         request.relative_url.find("/files/") == string::npos) {
188       // The file is not file deletion request. Delegate the processing to the
189       // next handler.
190       return scoped_ptr<net::test_server::HttpResponse>();
191     }
192
193     http_request_ = request;
194
195     scoped_ptr<net::test_server::BasicHttpResponse> response(
196         new net::test_server::BasicHttpResponse);
197     response->set_code(net::HTTP_NO_CONTENT);
198
199     return response.PassAs<net::test_server::HttpResponse>();
200   }
201
202   // Returns PRECONDITION_FAILED response for ETag mismatching with error JSON
203   // content specified by |expected_precondition_failed_file_path_|.
204   // To use this method, it is necessary to set the variable to the appropriate
205   // file path before sending the request to the server.
206   scoped_ptr<net::test_server::HttpResponse> HandlePreconditionFailedRequest(
207       const net::test_server::HttpRequest& request) {
208     if (expected_precondition_failed_file_path_.empty()) {
209       // The file is not specified. Delegate the process to the next handler.
210       return scoped_ptr<net::test_server::HttpResponse>();
211     }
212
213     http_request_ = request;
214
215     scoped_ptr<net::test_server::BasicHttpResponse> response(
216         new net::test_server::BasicHttpResponse);
217     response->set_code(net::HTTP_PRECONDITION_FAILED);
218
219     std::string content;
220     if (base::ReadFileToString(expected_precondition_failed_file_path_,
221                                &content)) {
222       response->set_content(content);
223       response->set_content_type("application/json");
224     }
225
226     return response.PassAs<net::test_server::HttpResponse>();
227   }
228
229   // Returns the response based on set expected upload url.
230   // The response contains the url in its "Location: " header. Also, it doesn't
231   // have any content.
232   // To use this method, it is necessary to set |expected_upload_path_|
233   // to the string representation of the url to be returned.
234   scoped_ptr<net::test_server::HttpResponse> HandleInitiateUploadRequest(
235       const net::test_server::HttpRequest& request) {
236     if (request.relative_url == expected_upload_path_ ||
237         expected_upload_path_.empty()) {
238       // The request is for resume uploading or the expected upload url is not
239       // set. Delegate the processing to the next handler.
240       return scoped_ptr<net::test_server::HttpResponse>();
241     }
242
243     http_request_ = request;
244
245     scoped_ptr<net::test_server::BasicHttpResponse> response(
246         new net::test_server::BasicHttpResponse);
247
248     // Check if the X-Upload-Content-Length is present. If yes, store the
249     // length of the file.
250     std::map<std::string, std::string>::const_iterator found =
251         request.headers.find("X-Upload-Content-Length");
252     if (found == request.headers.end() ||
253         !base::StringToInt64(found->second, &content_length_)) {
254       return scoped_ptr<net::test_server::HttpResponse>();
255     }
256     received_bytes_ = 0;
257
258     response->set_code(net::HTTP_OK);
259     response->AddCustomHeader(
260         "Location",
261         test_server_.base_url().Resolve(expected_upload_path_).spec());
262     return response.PassAs<net::test_server::HttpResponse>();
263   }
264
265   scoped_ptr<net::test_server::HttpResponse> HandleResumeUploadRequest(
266       const net::test_server::HttpRequest& request) {
267     if (request.relative_url != expected_upload_path_) {
268       // The request path is different from the expected path for uploading.
269       // Delegate the processing to the next handler.
270       return scoped_ptr<net::test_server::HttpResponse>();
271     }
272
273     http_request_ = request;
274
275     if (!request.content.empty()) {
276       std::map<std::string, std::string>::const_iterator iter =
277           request.headers.find("Content-Range");
278       if (iter == request.headers.end()) {
279         // The range must be set.
280         return scoped_ptr<net::test_server::HttpResponse>();
281       }
282
283       int64 length = 0;
284       int64 start_position = 0;
285       int64 end_position = 0;
286       if (!test_util::ParseContentRangeHeader(
287               iter->second, &start_position, &end_position, &length)) {
288         // Invalid "Content-Range" value.
289         return scoped_ptr<net::test_server::HttpResponse>();
290       }
291
292       EXPECT_EQ(start_position, received_bytes_);
293       EXPECT_EQ(length, content_length_);
294
295       // end_position is inclusive, but so +1 to change the range to byte size.
296       received_bytes_ = end_position + 1;
297     }
298
299     if (received_bytes_ < content_length_) {
300       scoped_ptr<net::test_server::BasicHttpResponse> response(
301           new net::test_server::BasicHttpResponse);
302       // Set RESUME INCOMPLETE (308) status code.
303       response->set_code(static_cast<net::HttpStatusCode>(308));
304
305       // Add Range header to the response, based on the values of
306       // Content-Range header in the request.
307       // The header is annotated only when at least one byte is received.
308       if (received_bytes_ > 0) {
309         response->AddCustomHeader(
310             "Range", "bytes=0-" + base::Int64ToString(received_bytes_ - 1));
311       }
312
313       return response.PassAs<net::test_server::HttpResponse>();
314     }
315
316     // All bytes are received. Return the "success" response with the file's
317     // (dummy) metadata.
318     scoped_ptr<net::test_server::BasicHttpResponse> response =
319         test_util::CreateHttpResponseFromFile(
320             test_util::GetTestFilePath("drive/file_entry.json"));
321
322     // The response code is CREATED if it is new file uploading.
323     if (http_request_.relative_url == kTestUploadNewFilePath) {
324       response->set_code(net::HTTP_CREATED);
325     }
326
327     return response.PassAs<net::test_server::HttpResponse>();
328   }
329
330   // Returns the response based on set expected content and its type.
331   // To use this method, both |expected_content_type_| and |expected_content_|
332   // must be set in advance.
333   scoped_ptr<net::test_server::HttpResponse> HandleContentResponse(
334       const net::test_server::HttpRequest& request) {
335     if (expected_content_type_.empty() || expected_content_.empty()) {
336       // Expected content is not set. Delegate the processing to the next
337       // handler.
338       return scoped_ptr<net::test_server::HttpResponse>();
339     }
340
341     http_request_ = request;
342
343     scoped_ptr<net::test_server::BasicHttpResponse> response(
344         new net::test_server::BasicHttpResponse);
345     response->set_code(net::HTTP_OK);
346     response->set_content_type(expected_content_type_);
347     response->set_content(expected_content_);
348     return response.PassAs<net::test_server::HttpResponse>();
349   }
350
351   // Handles a request for downloading a file.
352   scoped_ptr<net::test_server::HttpResponse> HandleDownloadRequest(
353       const net::test_server::HttpRequest& request) {
354     http_request_ = request;
355
356     const GURL absolute_url = test_server_.GetURL(request.relative_url);
357     std::string id;
358     if (!test_util::RemovePrefix(absolute_url.path(),
359                                  kTestDownloadPathPrefix,
360                                  &id)) {
361       return scoped_ptr<net::test_server::HttpResponse>();
362     }
363
364     // For testing, returns a text with |id| repeated 3 times.
365     scoped_ptr<net::test_server::BasicHttpResponse> response(
366         new net::test_server::BasicHttpResponse);
367     response->set_code(net::HTTP_OK);
368     response->set_content(id + id + id);
369     response->set_content_type("text/plain");
370     return response.PassAs<net::test_server::HttpResponse>();
371   }
372
373   // These are for the current upload file status.
374   int64 received_bytes_;
375   int64 content_length_;
376 };
377
378 TEST_F(DriveApiRequestsTest, DriveApiDataRequest_Fields) {
379   // Make sure that "fields" query param is supported by using its subclass,
380   // AboutGetRequest.
381
382   // Set an expected data file containing valid result.
383   expected_data_file_path_ = test_util::GetTestFilePath(
384       "drive/about.json");
385
386   GDataErrorCode error = GDATA_OTHER_ERROR;
387   scoped_ptr<AboutResource> about_resource;
388
389   {
390     base::RunLoop run_loop;
391     drive::AboutGetRequest* request = new drive::AboutGetRequest(
392         request_sender_.get(),
393         *url_generator_,
394         test_util::CreateQuitCallback(
395             &run_loop,
396             test_util::CreateCopyResultCallback(&error, &about_resource)));
397     request->set_fields(
398         "kind,quotaBytesTotal,quotaBytesUsed,largestChangeId,rootFolderId");
399     request_sender_->StartRequestWithRetry(request);
400     run_loop.Run();
401   }
402
403   EXPECT_EQ(HTTP_SUCCESS, error);
404   EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
405   EXPECT_EQ("/drive/v2/about?"
406             "fields=kind%2CquotaBytesTotal%2CquotaBytesUsed%2C"
407             "largestChangeId%2CrootFolderId",
408             http_request_.relative_url);
409
410   scoped_ptr<AboutResource> expected(
411       AboutResource::CreateFrom(
412           *test_util::LoadJSONFile("drive/about.json")));
413   ASSERT_TRUE(about_resource.get());
414   EXPECT_EQ(expected->largest_change_id(), about_resource->largest_change_id());
415   EXPECT_EQ(expected->quota_bytes_total(), about_resource->quota_bytes_total());
416   EXPECT_EQ(expected->quota_bytes_used(), about_resource->quota_bytes_used());
417   EXPECT_EQ(expected->root_folder_id(), about_resource->root_folder_id());
418 }
419
420 TEST_F(DriveApiRequestsTest, FilesInsertRequest) {
421   // Set an expected data file containing the directory's entry data.
422   expected_data_file_path_ =
423       test_util::GetTestFilePath("drive/directory_entry.json");
424
425   GDataErrorCode error = GDATA_OTHER_ERROR;
426   scoped_ptr<FileResource> file_resource;
427
428   // Create "new directory" in the root directory.
429   {
430     base::RunLoop run_loop;
431     drive::FilesInsertRequest* request = new drive::FilesInsertRequest(
432         request_sender_.get(),
433         *url_generator_,
434         test_util::CreateQuitCallback(
435             &run_loop,
436             test_util::CreateCopyResultCallback(&error, &file_resource)));
437     request->set_mime_type("application/vnd.google-apps.folder");
438     request->add_parent("root");
439     request->set_title("new directory");
440     request_sender_->StartRequestWithRetry(request);
441     run_loop.Run();
442   }
443
444   EXPECT_EQ(HTTP_SUCCESS, error);
445   EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
446   EXPECT_EQ("/drive/v2/files", http_request_.relative_url);
447   EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
448
449   EXPECT_TRUE(http_request_.has_content);
450
451   scoped_ptr<FileResource> expected(
452       FileResource::CreateFrom(
453           *test_util::LoadJSONFile("drive/directory_entry.json")));
454
455   // Sanity check.
456   ASSERT_TRUE(file_resource.get());
457
458   EXPECT_EQ(expected->file_id(), file_resource->file_id());
459   EXPECT_EQ(expected->title(), file_resource->title());
460   EXPECT_EQ(expected->mime_type(), file_resource->mime_type());
461   EXPECT_EQ(expected->parents().size(), file_resource->parents().size());
462 }
463
464 TEST_F(DriveApiRequestsTest, FilesPatchRequest) {
465   const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
466   const base::Time::Exploded kLastViewedByMeDate =
467       {2013, 7, 0, 19, 15, 59, 13, 123};
468
469   // Set an expected data file containing valid result.
470   expected_data_file_path_ =
471       test_util::GetTestFilePath("drive/file_entry.json");
472
473   GDataErrorCode error = GDATA_OTHER_ERROR;
474   scoped_ptr<FileResource> file_resource;
475
476   {
477     base::RunLoop run_loop;
478     drive::FilesPatchRequest* request = new drive::FilesPatchRequest(
479         request_sender_.get(),
480         *url_generator_,
481         test_util::CreateQuitCallback(
482             &run_loop,
483             test_util::CreateCopyResultCallback(&error, &file_resource)));
484     request->set_file_id("resource_id");
485     request->set_set_modified_date(true);
486     request->set_update_viewed_date(false);
487
488     request->set_title("new title");
489     request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
490     request->set_last_viewed_by_me_date(
491         base::Time::FromUTCExploded(kLastViewedByMeDate));
492     request->add_parent("parent_resource_id");
493
494     request_sender_->StartRequestWithRetry(request);
495     run_loop.Run();
496   }
497
498   EXPECT_EQ(HTTP_SUCCESS, error);
499   EXPECT_EQ(net::test_server::METHOD_PATCH, http_request_.method);
500   EXPECT_EQ("/drive/v2/files/resource_id"
501             "?setModifiedDate=true&updateViewedDate=false",
502             http_request_.relative_url);
503
504   EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
505   EXPECT_TRUE(http_request_.has_content);
506   EXPECT_EQ("{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
507             "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
508             "\"parents\":[{\"id\":\"parent_resource_id\"}],"
509             "\"title\":\"new title\"}",
510             http_request_.content);
511   EXPECT_TRUE(file_resource);
512 }
513
514 TEST_F(DriveApiRequestsTest, AboutGetRequest_ValidJson) {
515   // Set an expected data file containing valid result.
516   expected_data_file_path_ = test_util::GetTestFilePath(
517       "drive/about.json");
518
519   GDataErrorCode error = GDATA_OTHER_ERROR;
520   scoped_ptr<AboutResource> about_resource;
521
522   {
523     base::RunLoop run_loop;
524     drive::AboutGetRequest* request = new drive::AboutGetRequest(
525         request_sender_.get(),
526         *url_generator_,
527         test_util::CreateQuitCallback(
528             &run_loop,
529             test_util::CreateCopyResultCallback(&error, &about_resource)));
530     request_sender_->StartRequestWithRetry(request);
531     run_loop.Run();
532   }
533
534   EXPECT_EQ(HTTP_SUCCESS, error);
535   EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
536   EXPECT_EQ("/drive/v2/about", http_request_.relative_url);
537
538   scoped_ptr<AboutResource> expected(
539       AboutResource::CreateFrom(
540           *test_util::LoadJSONFile("drive/about.json")));
541   ASSERT_TRUE(about_resource.get());
542   EXPECT_EQ(expected->largest_change_id(), about_resource->largest_change_id());
543   EXPECT_EQ(expected->quota_bytes_total(), about_resource->quota_bytes_total());
544   EXPECT_EQ(expected->quota_bytes_used(), about_resource->quota_bytes_used());
545   EXPECT_EQ(expected->root_folder_id(), about_resource->root_folder_id());
546 }
547
548 TEST_F(DriveApiRequestsTest, AboutGetRequest_InvalidJson) {
549   // Set an expected data file containing invalid result.
550   expected_data_file_path_ = test_util::GetTestFilePath(
551       "gdata/testfile.txt");
552
553   GDataErrorCode error = GDATA_OTHER_ERROR;
554   scoped_ptr<AboutResource> about_resource;
555
556   {
557     base::RunLoop run_loop;
558     drive::AboutGetRequest* request = new drive::AboutGetRequest(
559         request_sender_.get(),
560         *url_generator_,
561         test_util::CreateQuitCallback(
562             &run_loop,
563             test_util::CreateCopyResultCallback(&error, &about_resource)));
564     request_sender_->StartRequestWithRetry(request);
565     run_loop.Run();
566   }
567
568   // "parse error" should be returned, and the about resource should be NULL.
569   EXPECT_EQ(GDATA_PARSE_ERROR, error);
570   EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
571   EXPECT_EQ("/drive/v2/about", http_request_.relative_url);
572   EXPECT_FALSE(about_resource);
573 }
574
575 TEST_F(DriveApiRequestsTest, AppsListRequest) {
576   // Set an expected data file containing valid result.
577   expected_data_file_path_ = test_util::GetTestFilePath(
578       "drive/applist.json");
579
580   GDataErrorCode error = GDATA_OTHER_ERROR;
581   scoped_ptr<AppList> app_list;
582
583   {
584     base::RunLoop run_loop;
585     drive::AppsListRequest* request = new drive::AppsListRequest(
586         request_sender_.get(),
587         *url_generator_,
588         test_util::CreateQuitCallback(
589             &run_loop,
590             test_util::CreateCopyResultCallback(&error, &app_list)));
591     request_sender_->StartRequestWithRetry(request);
592     run_loop.Run();
593   }
594
595   EXPECT_EQ(HTTP_SUCCESS, error);
596   EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
597   EXPECT_EQ("/drive/v2/apps", http_request_.relative_url);
598   EXPECT_TRUE(app_list);
599 }
600
601 TEST_F(DriveApiRequestsTest, ChangesListRequest) {
602   // Set an expected data file containing valid result.
603   expected_data_file_path_ = test_util::GetTestFilePath(
604       "drive/changelist.json");
605
606   GDataErrorCode error = GDATA_OTHER_ERROR;
607   scoped_ptr<ChangeList> result;
608
609   {
610     base::RunLoop run_loop;
611     drive::ChangesListRequest* request = new drive::ChangesListRequest(
612         request_sender_.get(), *url_generator_,
613         test_util::CreateQuitCallback(
614             &run_loop,
615             test_util::CreateCopyResultCallback(&error, &result)));
616     request->set_include_deleted(true);
617     request->set_start_change_id(100);
618     request->set_max_results(500);
619     request_sender_->StartRequestWithRetry(request);
620     run_loop.Run();
621   }
622
623   EXPECT_EQ(HTTP_SUCCESS, error);
624   EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
625   EXPECT_EQ("/drive/v2/changes?maxResults=500&startChangeId=100",
626             http_request_.relative_url);
627   EXPECT_TRUE(result);
628 }
629
630 TEST_F(DriveApiRequestsTest, ChangesListNextPageRequest) {
631   // Set an expected data file containing valid result.
632   expected_data_file_path_ = test_util::GetTestFilePath(
633       "drive/changelist.json");
634
635   GDataErrorCode error = GDATA_OTHER_ERROR;
636   scoped_ptr<ChangeList> result;
637
638   {
639     base::RunLoop run_loop;
640     drive::ChangesListNextPageRequest* request =
641         new drive::ChangesListNextPageRequest(
642             request_sender_.get(),
643             test_util::CreateQuitCallback(
644                 &run_loop,
645                 test_util::CreateCopyResultCallback(&error, &result)));
646     request->set_next_link(test_server_.GetURL("/continue/get/change/list"));
647     request_sender_->StartRequestWithRetry(request);
648     run_loop.Run();
649   }
650
651   EXPECT_EQ(HTTP_SUCCESS, error);
652   EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
653   EXPECT_EQ("/continue/get/change/list", http_request_.relative_url);
654   EXPECT_TRUE(result);
655 }
656
657 TEST_F(DriveApiRequestsTest, FilesCopyRequest) {
658   const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
659
660   // Set an expected data file containing the dummy file entry data.
661   // It'd be returned if we copy a file.
662   expected_data_file_path_ =
663       test_util::GetTestFilePath("drive/file_entry.json");
664
665   GDataErrorCode error = GDATA_OTHER_ERROR;
666   scoped_ptr<FileResource> file_resource;
667
668   // Copy the file to a new file named "new title".
669   {
670     base::RunLoop run_loop;
671     drive::FilesCopyRequest* request = new drive::FilesCopyRequest(
672         request_sender_.get(),
673         *url_generator_,
674         test_util::CreateQuitCallback(
675             &run_loop,
676             test_util::CreateCopyResultCallback(&error, &file_resource)));
677     request->set_file_id("resource_id");
678     request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
679     request->add_parent("parent_resource_id");
680     request->set_title("new title");
681     request_sender_->StartRequestWithRetry(request);
682     run_loop.Run();
683   }
684
685   EXPECT_EQ(HTTP_SUCCESS, error);
686   EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
687   EXPECT_EQ("/drive/v2/files/resource_id/copy", http_request_.relative_url);
688   EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
689
690   EXPECT_TRUE(http_request_.has_content);
691   EXPECT_EQ(
692       "{\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
693       "\"parents\":[{\"id\":\"parent_resource_id\"}],\"title\":\"new title\"}",
694       http_request_.content);
695   EXPECT_TRUE(file_resource);
696 }
697
698 TEST_F(DriveApiRequestsTest, FilesCopyRequest_EmptyParentResourceId) {
699   // Set an expected data file containing the dummy file entry data.
700   // It'd be returned if we copy a file.
701   expected_data_file_path_ =
702       test_util::GetTestFilePath("drive/file_entry.json");
703
704   GDataErrorCode error = GDATA_OTHER_ERROR;
705   scoped_ptr<FileResource> file_resource;
706
707   // Copy the file to a new file named "new title".
708   {
709     base::RunLoop run_loop;
710     drive::FilesCopyRequest* request = new drive::FilesCopyRequest(
711         request_sender_.get(),
712         *url_generator_,
713         test_util::CreateQuitCallback(
714             &run_loop,
715             test_util::CreateCopyResultCallback(&error, &file_resource)));
716     request->set_file_id("resource_id");
717     request->set_title("new title");
718     request_sender_->StartRequestWithRetry(request);
719     run_loop.Run();
720   }
721
722   EXPECT_EQ(HTTP_SUCCESS, error);
723   EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
724   EXPECT_EQ("/drive/v2/files/resource_id/copy", http_request_.relative_url);
725   EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
726
727   EXPECT_TRUE(http_request_.has_content);
728   EXPECT_EQ("{\"title\":\"new title\"}", http_request_.content);
729   EXPECT_TRUE(file_resource);
730 }
731
732 TEST_F(DriveApiRequestsTest, FilesListRequest) {
733   // Set an expected data file containing valid result.
734   expected_data_file_path_ = test_util::GetTestFilePath(
735       "drive/filelist.json");
736
737   GDataErrorCode error = GDATA_OTHER_ERROR;
738   scoped_ptr<FileList> result;
739
740   {
741     base::RunLoop run_loop;
742     drive::FilesListRequest* request = new drive::FilesListRequest(
743         request_sender_.get(), *url_generator_,
744         test_util::CreateQuitCallback(
745             &run_loop,
746             test_util::CreateCopyResultCallback(&error, &result)));
747     request->set_max_results(50);
748     request->set_q("\"abcde\" in parents");
749     request_sender_->StartRequestWithRetry(request);
750     run_loop.Run();
751   }
752
753   EXPECT_EQ(HTTP_SUCCESS, error);
754   EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
755   EXPECT_EQ("/drive/v2/files?maxResults=50&q=%22abcde%22+in+parents",
756             http_request_.relative_url);
757   EXPECT_TRUE(result);
758 }
759
760 TEST_F(DriveApiRequestsTest, FilesListNextPageRequest) {
761   // Set an expected data file containing valid result.
762   expected_data_file_path_ = test_util::GetTestFilePath(
763       "drive/filelist.json");
764
765   GDataErrorCode error = GDATA_OTHER_ERROR;
766   scoped_ptr<FileList> result;
767
768   {
769     base::RunLoop run_loop;
770     drive::FilesListNextPageRequest* request =
771         new drive::FilesListNextPageRequest(
772             request_sender_.get(),
773             test_util::CreateQuitCallback(
774                 &run_loop,
775                 test_util::CreateCopyResultCallback(&error, &result)));
776     request->set_next_link(test_server_.GetURL("/continue/get/file/list"));
777     request_sender_->StartRequestWithRetry(request);
778     run_loop.Run();
779   }
780
781   EXPECT_EQ(HTTP_SUCCESS, error);
782   EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
783   EXPECT_EQ("/continue/get/file/list", http_request_.relative_url);
784   EXPECT_TRUE(result);
785 }
786
787 TEST_F(DriveApiRequestsTest, FilesDeleteRequest) {
788   GDataErrorCode error = GDATA_OTHER_ERROR;
789
790   // Delete a resource with the given resource id.
791   {
792     base::RunLoop run_loop;
793     drive::FilesDeleteRequest* request = new drive::FilesDeleteRequest(
794         request_sender_.get(),
795         *url_generator_,
796         test_util::CreateQuitCallback(
797             &run_loop, test_util::CreateCopyResultCallback(&error)));
798     request->set_file_id("resource_id");
799     request->set_etag(kTestETag);
800     request_sender_->StartRequestWithRetry(request);
801     run_loop.Run();
802   }
803
804   EXPECT_EQ(HTTP_NO_CONTENT, error);
805   EXPECT_EQ(net::test_server::METHOD_DELETE, http_request_.method);
806   EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
807   EXPECT_EQ("/drive/v2/files/resource_id", http_request_.relative_url);
808   EXPECT_FALSE(http_request_.has_content);
809 }
810
811 TEST_F(DriveApiRequestsTest, FilesTrashRequest) {
812   // Set data for the expected result. Directory entry should be returned
813   // if the trashing entry is a directory, so using it here should be fine.
814   expected_data_file_path_ =
815       test_util::GetTestFilePath("drive/directory_entry.json");
816
817   GDataErrorCode error = GDATA_OTHER_ERROR;
818   scoped_ptr<FileResource> file_resource;
819
820   // Trash a resource with the given resource id.
821   {
822     base::RunLoop run_loop;
823     drive::FilesTrashRequest* request = new drive::FilesTrashRequest(
824         request_sender_.get(),
825         *url_generator_,
826         test_util::CreateQuitCallback(
827             &run_loop,
828             test_util::CreateCopyResultCallback(&error, &file_resource)));
829     request->set_file_id("resource_id");
830     request_sender_->StartRequestWithRetry(request);
831     run_loop.Run();
832   }
833
834   EXPECT_EQ(HTTP_SUCCESS, error);
835   EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
836   EXPECT_EQ("/drive/v2/files/resource_id/trash", http_request_.relative_url);
837   EXPECT_TRUE(http_request_.has_content);
838   EXPECT_TRUE(http_request_.content.empty());
839 }
840
841 TEST_F(DriveApiRequestsTest, ChildrenInsertRequest) {
842   // Set an expected data file containing the children entry.
843   expected_content_type_ = "application/json";
844   expected_content_ = kTestChildrenResponse;
845
846   GDataErrorCode error = GDATA_OTHER_ERROR;
847
848   // Add a resource with "resource_id" to a directory with
849   // "parent_resource_id".
850   {
851     base::RunLoop run_loop;
852     drive::ChildrenInsertRequest* request = new drive::ChildrenInsertRequest(
853         request_sender_.get(),
854         *url_generator_,
855         test_util::CreateQuitCallback(
856             &run_loop,
857             test_util::CreateCopyResultCallback(&error)));
858     request->set_folder_id("parent_resource_id");
859     request->set_id("resource_id");
860     request_sender_->StartRequestWithRetry(request);
861     run_loop.Run();
862   }
863
864   EXPECT_EQ(HTTP_SUCCESS, error);
865   EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
866   EXPECT_EQ("/drive/v2/files/parent_resource_id/children",
867             http_request_.relative_url);
868   EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
869
870   EXPECT_TRUE(http_request_.has_content);
871   EXPECT_EQ("{\"id\":\"resource_id\"}", http_request_.content);
872 }
873
874 TEST_F(DriveApiRequestsTest, ChildrenDeleteRequest) {
875   GDataErrorCode error = GDATA_OTHER_ERROR;
876
877   // Remove a resource with "resource_id" from a directory with
878   // "parent_resource_id".
879   {
880     base::RunLoop run_loop;
881     drive::ChildrenDeleteRequest* request = new drive::ChildrenDeleteRequest(
882         request_sender_.get(),
883         *url_generator_,
884         test_util::CreateQuitCallback(
885             &run_loop,
886             test_util::CreateCopyResultCallback(&error)));
887     request->set_child_id("resource_id");
888     request->set_folder_id("parent_resource_id");
889     request_sender_->StartRequestWithRetry(request);
890     run_loop.Run();
891   }
892
893   EXPECT_EQ(HTTP_NO_CONTENT, error);
894   EXPECT_EQ(net::test_server::METHOD_DELETE, http_request_.method);
895   EXPECT_EQ("/drive/v2/files/parent_resource_id/children/resource_id",
896             http_request_.relative_url);
897   EXPECT_FALSE(http_request_.has_content);
898 }
899
900 TEST_F(DriveApiRequestsTest, UploadNewFileRequest) {
901   // Set an expected url for uploading.
902   expected_upload_path_ = kTestUploadNewFilePath;
903
904   const char kTestContentType[] = "text/plain";
905   const std::string kTestContent(100, 'a');
906   const base::FilePath kTestFilePath =
907       temp_dir_.path().AppendASCII("upload_file.txt");
908   ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
909
910   GDataErrorCode error = GDATA_OTHER_ERROR;
911   GURL upload_url;
912
913   // Initiate uploading a new file to the directory with
914   // "parent_resource_id".
915   {
916     base::RunLoop run_loop;
917     drive::InitiateUploadNewFileRequest* request =
918         new drive::InitiateUploadNewFileRequest(
919             request_sender_.get(),
920             *url_generator_,
921             kTestContentType,
922             kTestContent.size(),
923             "parent_resource_id",  // The resource id of the parent directory.
924             "new file title",  // The title of the file being uploaded.
925             test_util::CreateQuitCallback(
926                 &run_loop,
927                 test_util::CreateCopyResultCallback(&error, &upload_url)));
928     request_sender_->StartRequestWithRetry(request);
929     run_loop.Run();
930   }
931
932   EXPECT_EQ(HTTP_SUCCESS, error);
933   EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
934   EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
935   EXPECT_EQ(base::Int64ToString(kTestContent.size()),
936             http_request_.headers["X-Upload-Content-Length"]);
937
938   EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
939   EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
940             http_request_.relative_url);
941   EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
942   EXPECT_TRUE(http_request_.has_content);
943   EXPECT_EQ("{\"parents\":[{"
944             "\"id\":\"parent_resource_id\","
945             "\"kind\":\"drive#fileLink\""
946             "}],"
947             "\"title\":\"new file title\"}",
948             http_request_.content);
949
950   // Upload the content to the upload URL.
951   UploadRangeResponse response;
952   scoped_ptr<FileResource> new_entry;
953
954   {
955     base::RunLoop run_loop;
956     drive::ResumeUploadRequest* resume_request =
957         new drive::ResumeUploadRequest(
958             request_sender_.get(),
959             upload_url,
960             0,  // start_position
961             kTestContent.size(),  // end_position (exclusive)
962             kTestContent.size(),  // content_length,
963             kTestContentType,
964             kTestFilePath,
965             test_util::CreateQuitCallback(
966                 &run_loop,
967                 test_util::CreateCopyResultCallback(&response, &new_entry)),
968             ProgressCallback());
969     request_sender_->StartRequestWithRetry(resume_request);
970     run_loop.Run();
971   }
972
973   // METHOD_PUT should be used to upload data.
974   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
975   // Request should go to the upload URL.
976   EXPECT_EQ(upload_url.path(), http_request_.relative_url);
977   // Content-Range header should be added.
978   EXPECT_EQ("bytes 0-" +
979             base::Int64ToString(kTestContent.size() - 1) + "/" +
980             base::Int64ToString(kTestContent.size()),
981             http_request_.headers["Content-Range"]);
982   // The upload content should be set in the HTTP request.
983   EXPECT_TRUE(http_request_.has_content);
984   EXPECT_EQ(kTestContent, http_request_.content);
985
986   // Check the response.
987   EXPECT_EQ(HTTP_CREATED, response.code);  // Because it's a new file
988   // The start and end positions should be set to -1, if an upload is complete.
989   EXPECT_EQ(-1, response.start_position_received);
990   EXPECT_EQ(-1, response.end_position_received);
991 }
992
993 TEST_F(DriveApiRequestsTest, UploadNewEmptyFileRequest) {
994   // Set an expected url for uploading.
995   expected_upload_path_ = kTestUploadNewFilePath;
996
997   const char kTestContentType[] = "text/plain";
998   const char kTestContent[] = "";
999   const base::FilePath kTestFilePath =
1000       temp_dir_.path().AppendASCII("empty_file.txt");
1001   ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1002
1003   GDataErrorCode error = GDATA_OTHER_ERROR;
1004   GURL upload_url;
1005
1006   // Initiate uploading a new file to the directory with "parent_resource_id".
1007   {
1008     base::RunLoop run_loop;
1009     drive::InitiateUploadNewFileRequest* request =
1010         new drive::InitiateUploadNewFileRequest(
1011             request_sender_.get(),
1012             *url_generator_,
1013             kTestContentType,
1014             0,
1015             "parent_resource_id",  // The resource id of the parent directory.
1016             "new file title",  // The title of the file being uploaded.
1017             test_util::CreateQuitCallback(
1018                 &run_loop,
1019                 test_util::CreateCopyResultCallback(&error, &upload_url)));
1020     request_sender_->StartRequestWithRetry(request);
1021     run_loop.Run();
1022   }
1023
1024   EXPECT_EQ(HTTP_SUCCESS, error);
1025   EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1026   EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1027   EXPECT_EQ("0", http_request_.headers["X-Upload-Content-Length"]);
1028
1029   EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1030   EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
1031             http_request_.relative_url);
1032   EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1033   EXPECT_TRUE(http_request_.has_content);
1034   EXPECT_EQ("{\"parents\":[{"
1035             "\"id\":\"parent_resource_id\","
1036             "\"kind\":\"drive#fileLink\""
1037             "}],"
1038             "\"title\":\"new file title\"}",
1039             http_request_.content);
1040
1041   // Upload the content to the upload URL.
1042   UploadRangeResponse response;
1043   scoped_ptr<FileResource> new_entry;
1044
1045   {
1046     base::RunLoop run_loop;
1047     drive::ResumeUploadRequest* resume_request =
1048         new drive::ResumeUploadRequest(
1049             request_sender_.get(),
1050             upload_url,
1051             0,  // start_position
1052             0,  // end_position (exclusive)
1053             0,  // content_length,
1054             kTestContentType,
1055             kTestFilePath,
1056             test_util::CreateQuitCallback(
1057                 &run_loop,
1058                 test_util::CreateCopyResultCallback(&response, &new_entry)),
1059             ProgressCallback());
1060     request_sender_->StartRequestWithRetry(resume_request);
1061     run_loop.Run();
1062   }
1063
1064   // METHOD_PUT should be used to upload data.
1065   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1066   // Request should go to the upload URL.
1067   EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1068   // Content-Range header should NOT be added.
1069   EXPECT_EQ(0U, http_request_.headers.count("Content-Range"));
1070   // The upload content should be set in the HTTP request.
1071   EXPECT_TRUE(http_request_.has_content);
1072   EXPECT_EQ(kTestContent, http_request_.content);
1073
1074   // Check the response.
1075   EXPECT_EQ(HTTP_CREATED, response.code);  // Because it's a new file
1076   // The start and end positions should be set to -1, if an upload is complete.
1077   EXPECT_EQ(-1, response.start_position_received);
1078   EXPECT_EQ(-1, response.end_position_received);
1079 }
1080
1081 TEST_F(DriveApiRequestsTest, UploadNewLargeFileRequest) {
1082   // Set an expected url for uploading.
1083   expected_upload_path_ = kTestUploadNewFilePath;
1084
1085   const char kTestContentType[] = "text/plain";
1086   const size_t kNumChunkBytes = 10;  // Num bytes in a chunk.
1087   const std::string kTestContent(100, 'a');
1088   const base::FilePath kTestFilePath =
1089       temp_dir_.path().AppendASCII("upload_file.txt");
1090   ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1091
1092   GDataErrorCode error = GDATA_OTHER_ERROR;
1093   GURL upload_url;
1094
1095   // Initiate uploading a new file to the directory with "parent_resource_id".
1096   {
1097     base::RunLoop run_loop;
1098     drive::InitiateUploadNewFileRequest* request =
1099         new drive::InitiateUploadNewFileRequest(
1100             request_sender_.get(),
1101             *url_generator_,
1102             kTestContentType,
1103             kTestContent.size(),
1104             "parent_resource_id",  // The resource id of the parent directory.
1105             "new file title",  // The title of the file being uploaded.
1106             test_util::CreateQuitCallback(
1107                 &run_loop,
1108                 test_util::CreateCopyResultCallback(&error, &upload_url)));
1109     request_sender_->StartRequestWithRetry(request);
1110     run_loop.Run();
1111   }
1112
1113   EXPECT_EQ(HTTP_SUCCESS, error);
1114   EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1115   EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1116   EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1117             http_request_.headers["X-Upload-Content-Length"]);
1118
1119   EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1120   EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable",
1121             http_request_.relative_url);
1122   EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1123   EXPECT_TRUE(http_request_.has_content);
1124   EXPECT_EQ("{\"parents\":[{"
1125             "\"id\":\"parent_resource_id\","
1126             "\"kind\":\"drive#fileLink\""
1127             "}],"
1128             "\"title\":\"new file title\"}",
1129             http_request_.content);
1130
1131   // Before sending any data, check the current status.
1132   // This is an edge case test for GetUploadStatusRequest.
1133   {
1134     UploadRangeResponse response;
1135     scoped_ptr<FileResource> new_entry;
1136
1137     // Check the response by GetUploadStatusRequest.
1138     {
1139       base::RunLoop run_loop;
1140       drive::GetUploadStatusRequest* get_upload_status_request =
1141           new drive::GetUploadStatusRequest(
1142               request_sender_.get(),
1143               upload_url,
1144               kTestContent.size(),
1145               test_util::CreateQuitCallback(
1146                   &run_loop,
1147                   test_util::CreateCopyResultCallback(&response, &new_entry)));
1148       request_sender_->StartRequestWithRetry(get_upload_status_request);
1149       run_loop.Run();
1150     }
1151
1152     // METHOD_PUT should be used to upload data.
1153     EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1154     // Request should go to the upload URL.
1155     EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1156     // Content-Range header should be added.
1157     EXPECT_EQ("bytes */" + base::Int64ToString(kTestContent.size()),
1158               http_request_.headers["Content-Range"]);
1159     EXPECT_TRUE(http_request_.has_content);
1160     EXPECT_TRUE(http_request_.content.empty());
1161
1162     // Check the response.
1163     EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code);
1164     EXPECT_EQ(0, response.start_position_received);
1165     EXPECT_EQ(0, response.end_position_received);
1166   }
1167
1168   // Upload the content to the upload URL.
1169   for (size_t start_position = 0; start_position < kTestContent.size();
1170        start_position += kNumChunkBytes) {
1171     const std::string payload = kTestContent.substr(
1172         start_position,
1173         std::min(kNumChunkBytes, kTestContent.size() - start_position));
1174     const size_t end_position = start_position + payload.size();
1175
1176     UploadRangeResponse response;
1177     scoped_ptr<FileResource> new_entry;
1178
1179     {
1180       base::RunLoop run_loop;
1181       drive::ResumeUploadRequest* resume_request =
1182           new drive::ResumeUploadRequest(
1183               request_sender_.get(),
1184               upload_url,
1185               start_position,
1186               end_position,
1187               kTestContent.size(),  // content_length,
1188               kTestContentType,
1189               kTestFilePath,
1190               test_util::CreateQuitCallback(
1191                   &run_loop,
1192                   test_util::CreateCopyResultCallback(&response, &new_entry)),
1193               ProgressCallback());
1194       request_sender_->StartRequestWithRetry(resume_request);
1195       run_loop.Run();
1196     }
1197
1198     // METHOD_PUT should be used to upload data.
1199     EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1200     // Request should go to the upload URL.
1201     EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1202     // Content-Range header should be added.
1203     EXPECT_EQ("bytes " +
1204               base::Int64ToString(start_position) + "-" +
1205               base::Int64ToString(end_position - 1) + "/" +
1206               base::Int64ToString(kTestContent.size()),
1207               http_request_.headers["Content-Range"]);
1208     // The upload content should be set in the HTTP request.
1209     EXPECT_TRUE(http_request_.has_content);
1210     EXPECT_EQ(payload, http_request_.content);
1211
1212     if (end_position == kTestContent.size()) {
1213       // Check the response.
1214       EXPECT_EQ(HTTP_CREATED, response.code);  // Because it's a new file
1215       // The start and end positions should be set to -1, if an upload is
1216       // complete.
1217       EXPECT_EQ(-1, response.start_position_received);
1218       EXPECT_EQ(-1, response.end_position_received);
1219       break;
1220     }
1221
1222     // Check the response.
1223     EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code);
1224     EXPECT_EQ(0, response.start_position_received);
1225     EXPECT_EQ(static_cast<int64>(end_position), response.end_position_received);
1226
1227     // Check the response by GetUploadStatusRequest.
1228     {
1229       base::RunLoop run_loop;
1230       drive::GetUploadStatusRequest* get_upload_status_request =
1231           new drive::GetUploadStatusRequest(
1232               request_sender_.get(),
1233               upload_url,
1234               kTestContent.size(),
1235               test_util::CreateQuitCallback(
1236                   &run_loop,
1237                   test_util::CreateCopyResultCallback(&response, &new_entry)));
1238       request_sender_->StartRequestWithRetry(get_upload_status_request);
1239       run_loop.Run();
1240     }
1241
1242     // METHOD_PUT should be used to upload data.
1243     EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1244     // Request should go to the upload URL.
1245     EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1246     // Content-Range header should be added.
1247     EXPECT_EQ("bytes */" + base::Int64ToString(kTestContent.size()),
1248               http_request_.headers["Content-Range"]);
1249     EXPECT_TRUE(http_request_.has_content);
1250     EXPECT_TRUE(http_request_.content.empty());
1251
1252     // Check the response.
1253     EXPECT_EQ(HTTP_RESUME_INCOMPLETE, response.code);
1254     EXPECT_EQ(0, response.start_position_received);
1255     EXPECT_EQ(static_cast<int64>(end_position),
1256               response.end_position_received);
1257   }
1258 }
1259
1260 TEST_F(DriveApiRequestsTest, UploadNewFileWithMetadataRequest) {
1261   const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
1262   const base::Time::Exploded kLastViewedByMeDate =
1263       {2013, 7, 0, 19, 15, 59, 13, 123};
1264
1265   // Set an expected url for uploading.
1266   expected_upload_path_ = kTestUploadNewFilePath;
1267
1268   const char kTestContentType[] = "text/plain";
1269   const std::string kTestContent(100, 'a');
1270
1271   GDataErrorCode error = GDATA_OTHER_ERROR;
1272   GURL upload_url;
1273
1274   // Initiate uploading a new file to the directory with "parent_resource_id".
1275   {
1276     base::RunLoop run_loop;
1277     drive::InitiateUploadNewFileRequest* request =
1278         new drive::InitiateUploadNewFileRequest(
1279             request_sender_.get(),
1280             *url_generator_,
1281             kTestContentType,
1282             kTestContent.size(),
1283             "parent_resource_id",  // The resource id of the parent directory.
1284             "new file title",  // The title of the file being uploaded.
1285             test_util::CreateQuitCallback(
1286                 &run_loop,
1287                 test_util::CreateCopyResultCallback(&error, &upload_url)));
1288     request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
1289     request->set_last_viewed_by_me_date(
1290         base::Time::FromUTCExploded(kLastViewedByMeDate));
1291     request_sender_->StartRequestWithRetry(request);
1292     run_loop.Run();
1293   }
1294
1295   EXPECT_EQ(HTTP_SUCCESS, error);
1296   EXPECT_EQ(kTestUploadNewFilePath, upload_url.path());
1297   EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1298   EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1299             http_request_.headers["X-Upload-Content-Length"]);
1300
1301   EXPECT_EQ(net::test_server::METHOD_POST, http_request_.method);
1302   EXPECT_EQ("/upload/drive/v2/files?uploadType=resumable&setModifiedDate=true",
1303             http_request_.relative_url);
1304   EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1305   EXPECT_TRUE(http_request_.has_content);
1306   EXPECT_EQ("{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
1307             "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
1308             "\"parents\":[{\"id\":\"parent_resource_id\","
1309             "\"kind\":\"drive#fileLink\"}],"
1310             "\"title\":\"new file title\"}",
1311             http_request_.content);
1312 }
1313
1314 TEST_F(DriveApiRequestsTest, UploadExistingFileRequest) {
1315   // Set an expected url for uploading.
1316   expected_upload_path_ = kTestUploadExistingFilePath;
1317
1318   const char kTestContentType[] = "text/plain";
1319   const std::string kTestContent(100, 'a');
1320   const base::FilePath kTestFilePath =
1321       temp_dir_.path().AppendASCII("upload_file.txt");
1322   ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1323
1324   GDataErrorCode error = GDATA_OTHER_ERROR;
1325   GURL upload_url;
1326
1327   // Initiate uploading a new file to the directory with "parent_resource_id".
1328   {
1329     base::RunLoop run_loop;
1330     drive::InitiateUploadExistingFileRequest* request =
1331         new drive::InitiateUploadExistingFileRequest(
1332             request_sender_.get(),
1333             *url_generator_,
1334             kTestContentType,
1335             kTestContent.size(),
1336             "resource_id",  // The resource id of the file to be overwritten.
1337             std::string(),  // No etag.
1338             test_util::CreateQuitCallback(
1339                 &run_loop,
1340                 test_util::CreateCopyResultCallback(&error, &upload_url)));
1341     request_sender_->StartRequestWithRetry(request);
1342     run_loop.Run();
1343   }
1344
1345   EXPECT_EQ(HTTP_SUCCESS, error);
1346   EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1347   EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1348   EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1349             http_request_.headers["X-Upload-Content-Length"]);
1350   EXPECT_EQ("*", http_request_.headers["If-Match"]);
1351
1352   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1353   EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1354             http_request_.relative_url);
1355   EXPECT_TRUE(http_request_.has_content);
1356   EXPECT_TRUE(http_request_.content.empty());
1357
1358   // Upload the content to the upload URL.
1359   UploadRangeResponse response;
1360   scoped_ptr<FileResource> new_entry;
1361
1362   {
1363     base::RunLoop run_loop;
1364     drive::ResumeUploadRequest* resume_request =
1365         new drive::ResumeUploadRequest(
1366             request_sender_.get(),
1367             upload_url,
1368             0,  // start_position
1369             kTestContent.size(),  // end_position (exclusive)
1370             kTestContent.size(),  // content_length,
1371             kTestContentType,
1372             kTestFilePath,
1373             test_util::CreateQuitCallback(
1374                 &run_loop,
1375                 test_util::CreateCopyResultCallback(&response, &new_entry)),
1376             ProgressCallback());
1377     request_sender_->StartRequestWithRetry(resume_request);
1378     run_loop.Run();
1379   }
1380
1381   // METHOD_PUT should be used to upload data.
1382   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1383   // Request should go to the upload URL.
1384   EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1385   // Content-Range header should be added.
1386   EXPECT_EQ("bytes 0-" +
1387             base::Int64ToString(kTestContent.size() - 1) + "/" +
1388             base::Int64ToString(kTestContent.size()),
1389             http_request_.headers["Content-Range"]);
1390   // The upload content should be set in the HTTP request.
1391   EXPECT_TRUE(http_request_.has_content);
1392   EXPECT_EQ(kTestContent, http_request_.content);
1393
1394   // Check the response.
1395   EXPECT_EQ(HTTP_SUCCESS, response.code);  // Because it's an existing file
1396   // The start and end positions should be set to -1, if an upload is complete.
1397   EXPECT_EQ(-1, response.start_position_received);
1398   EXPECT_EQ(-1, response.end_position_received);
1399 }
1400
1401 TEST_F(DriveApiRequestsTest, UploadExistingFileRequestWithETag) {
1402   // Set an expected url for uploading.
1403   expected_upload_path_ = kTestUploadExistingFilePath;
1404
1405   const char kTestContentType[] = "text/plain";
1406   const std::string kTestContent(100, 'a');
1407   const base::FilePath kTestFilePath =
1408       temp_dir_.path().AppendASCII("upload_file.txt");
1409   ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1410
1411   GDataErrorCode error = GDATA_OTHER_ERROR;
1412   GURL upload_url;
1413
1414   // Initiate uploading a new file to the directory with "parent_resource_id".
1415   {
1416     base::RunLoop run_loop;
1417     drive::InitiateUploadExistingFileRequest* request =
1418         new drive::InitiateUploadExistingFileRequest(
1419             request_sender_.get(),
1420             *url_generator_,
1421             kTestContentType,
1422             kTestContent.size(),
1423             "resource_id",  // The resource id of the file to be overwritten.
1424             kTestETag,
1425             test_util::CreateQuitCallback(
1426                 &run_loop,
1427                 test_util::CreateCopyResultCallback(&error, &upload_url)));
1428     request_sender_->StartRequestWithRetry(request);
1429     run_loop.Run();
1430   }
1431
1432   EXPECT_EQ(HTTP_SUCCESS, error);
1433   EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1434   EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1435   EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1436             http_request_.headers["X-Upload-Content-Length"]);
1437   EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
1438
1439   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1440   EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1441             http_request_.relative_url);
1442   EXPECT_TRUE(http_request_.has_content);
1443   EXPECT_TRUE(http_request_.content.empty());
1444
1445   // Upload the content to the upload URL.
1446   UploadRangeResponse response;
1447   scoped_ptr<FileResource> new_entry;
1448
1449   {
1450     base::RunLoop run_loop;
1451     drive::ResumeUploadRequest* resume_request =
1452         new drive::ResumeUploadRequest(
1453             request_sender_.get(),
1454             upload_url,
1455             0,  // start_position
1456             kTestContent.size(),  // end_position (exclusive)
1457             kTestContent.size(),  // content_length,
1458             kTestContentType,
1459             kTestFilePath,
1460             test_util::CreateQuitCallback(
1461                 &run_loop,
1462                 test_util::CreateCopyResultCallback(&response, &new_entry)),
1463             ProgressCallback());
1464     request_sender_->StartRequestWithRetry(resume_request);
1465     run_loop.Run();
1466   }
1467
1468   // METHOD_PUT should be used to upload data.
1469   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1470   // Request should go to the upload URL.
1471   EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1472   // Content-Range header should be added.
1473   EXPECT_EQ("bytes 0-" +
1474             base::Int64ToString(kTestContent.size() - 1) + "/" +
1475             base::Int64ToString(kTestContent.size()),
1476             http_request_.headers["Content-Range"]);
1477   // The upload content should be set in the HTTP request.
1478   EXPECT_TRUE(http_request_.has_content);
1479   EXPECT_EQ(kTestContent, http_request_.content);
1480
1481   // Check the response.
1482   EXPECT_EQ(HTTP_SUCCESS, response.code);  // Because it's an existing file
1483   // The start and end positions should be set to -1, if an upload is complete.
1484   EXPECT_EQ(-1, response.start_position_received);
1485   EXPECT_EQ(-1, response.end_position_received);
1486 }
1487
1488 TEST_F(DriveApiRequestsTest, UploadExistingFileRequestWithETagConflicting) {
1489   // Set an expected url for uploading.
1490   expected_upload_path_ = kTestUploadExistingFilePath;
1491
1492   // If it turned out that the etag is conflicting, PRECONDITION_FAILED should
1493   // be returned.
1494   expected_precondition_failed_file_path_ =
1495       test_util::GetTestFilePath("drive/error.json");
1496
1497   const char kTestContentType[] = "text/plain";
1498   const std::string kTestContent(100, 'a');
1499
1500   GDataErrorCode error = GDATA_OTHER_ERROR;
1501   GURL upload_url;
1502
1503   // Initiate uploading a new file to the directory with "parent_resource_id".
1504   {
1505     base::RunLoop run_loop;
1506     drive::InitiateUploadExistingFileRequest* request =
1507         new drive::InitiateUploadExistingFileRequest(
1508             request_sender_.get(),
1509             *url_generator_,
1510             kTestContentType,
1511             kTestContent.size(),
1512             "resource_id",  // The resource id of the file to be overwritten.
1513             "Conflicting-etag",
1514             test_util::CreateQuitCallback(
1515                 &run_loop,
1516                 test_util::CreateCopyResultCallback(&error, &upload_url)));
1517     request_sender_->StartRequestWithRetry(request);
1518     run_loop.Run();
1519   }
1520
1521   EXPECT_EQ(HTTP_PRECONDITION, error);
1522   EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1523   EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1524             http_request_.headers["X-Upload-Content-Length"]);
1525   EXPECT_EQ("Conflicting-etag", http_request_.headers["If-Match"]);
1526
1527   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1528   EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1529             http_request_.relative_url);
1530   EXPECT_TRUE(http_request_.has_content);
1531   EXPECT_TRUE(http_request_.content.empty());
1532 }
1533
1534 TEST_F(DriveApiRequestsTest,
1535        UploadExistingFileRequestWithETagConflictOnResumeUpload) {
1536   // Set an expected url for uploading.
1537   expected_upload_path_ = kTestUploadExistingFilePath;
1538
1539   const char kTestContentType[] = "text/plain";
1540   const std::string kTestContent(100, 'a');
1541   const base::FilePath kTestFilePath =
1542       temp_dir_.path().AppendASCII("upload_file.txt");
1543   ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
1544
1545   GDataErrorCode error = GDATA_OTHER_ERROR;
1546   GURL upload_url;
1547
1548   // Initiate uploading a new file to the directory with "parent_resource_id".
1549   {
1550     base::RunLoop run_loop;
1551     drive::InitiateUploadExistingFileRequest* request =
1552         new drive::InitiateUploadExistingFileRequest(
1553             request_sender_.get(),
1554             *url_generator_,
1555             kTestContentType,
1556             kTestContent.size(),
1557             "resource_id",  // The resource id of the file to be overwritten.
1558             kTestETag,
1559             test_util::CreateQuitCallback(
1560                 &run_loop,
1561                 test_util::CreateCopyResultCallback(&error, &upload_url)));
1562     request_sender_->StartRequestWithRetry(request);
1563     run_loop.Run();
1564   }
1565
1566   EXPECT_EQ(HTTP_SUCCESS, error);
1567   EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1568   EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1569   EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1570             http_request_.headers["X-Upload-Content-Length"]);
1571   EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
1572
1573   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1574   EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
1575             http_request_.relative_url);
1576   EXPECT_TRUE(http_request_.has_content);
1577   EXPECT_TRUE(http_request_.content.empty());
1578
1579   // Set PRECONDITION_FAILED to the server. This is the emulation of the
1580   // confliction during uploading.
1581   expected_precondition_failed_file_path_ =
1582       test_util::GetTestFilePath("drive/error.json");
1583
1584   // Upload the content to the upload URL.
1585   UploadRangeResponse response;
1586   scoped_ptr<FileResource> new_entry;
1587
1588   {
1589     base::RunLoop run_loop;
1590     drive::ResumeUploadRequest* resume_request =
1591         new drive::ResumeUploadRequest(
1592             request_sender_.get(),
1593             upload_url,
1594             0,  // start_position
1595             kTestContent.size(),  // end_position (exclusive)
1596             kTestContent.size(),  // content_length,
1597             kTestContentType,
1598             kTestFilePath,
1599             test_util::CreateQuitCallback(
1600                 &run_loop,
1601                 test_util::CreateCopyResultCallback(&response, &new_entry)),
1602             ProgressCallback());
1603     request_sender_->StartRequestWithRetry(resume_request);
1604     run_loop.Run();
1605   }
1606
1607   // METHOD_PUT should be used to upload data.
1608   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1609   // Request should go to the upload URL.
1610   EXPECT_EQ(upload_url.path(), http_request_.relative_url);
1611   // Content-Range header should be added.
1612   EXPECT_EQ("bytes 0-" +
1613             base::Int64ToString(kTestContent.size() - 1) + "/" +
1614             base::Int64ToString(kTestContent.size()),
1615             http_request_.headers["Content-Range"]);
1616   // The upload content should be set in the HTTP request.
1617   EXPECT_TRUE(http_request_.has_content);
1618   EXPECT_EQ(kTestContent, http_request_.content);
1619
1620   // Check the response.
1621   EXPECT_EQ(HTTP_PRECONDITION, response.code);
1622   // The start and end positions should be set to -1 for error.
1623   EXPECT_EQ(-1, response.start_position_received);
1624   EXPECT_EQ(-1, response.end_position_received);
1625
1626   // New entry should be NULL.
1627   EXPECT_FALSE(new_entry.get());
1628 }
1629
1630 TEST_F(DriveApiRequestsTest, UploadExistingFileWithMetadataRequest) {
1631   const base::Time::Exploded kModifiedDate = {2012, 7, 0, 19, 15, 59, 13, 123};
1632   const base::Time::Exploded kLastViewedByMeDate =
1633       {2013, 7, 0, 19, 15, 59, 13, 123};
1634
1635   // Set an expected url for uploading.
1636   expected_upload_path_ = kTestUploadExistingFilePath;
1637
1638   const char kTestContentType[] = "text/plain";
1639   const std::string kTestContent(100, 'a');
1640
1641   GDataErrorCode error = GDATA_OTHER_ERROR;
1642   GURL upload_url;
1643
1644   // Initiate uploading a new file to the directory with "parent_resource_id".
1645   {
1646     base::RunLoop run_loop;
1647     drive::InitiateUploadExistingFileRequest* request =
1648         new drive::InitiateUploadExistingFileRequest(
1649             request_sender_.get(),
1650             *url_generator_,
1651             kTestContentType,
1652             kTestContent.size(),
1653             "resource_id",  // The resource id of the file to be overwritten.
1654             kTestETag,
1655             test_util::CreateQuitCallback(
1656                 &run_loop,
1657                 test_util::CreateCopyResultCallback(&error, &upload_url)));
1658     request->set_parent_resource_id("new_parent_resource_id");
1659     request->set_title("new file title");
1660     request->set_modified_date(base::Time::FromUTCExploded(kModifiedDate));
1661     request->set_last_viewed_by_me_date(
1662         base::Time::FromUTCExploded(kLastViewedByMeDate));
1663
1664     request_sender_->StartRequestWithRetry(request);
1665     run_loop.Run();
1666   }
1667
1668   EXPECT_EQ(HTTP_SUCCESS, error);
1669   EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
1670   EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
1671   EXPECT_EQ(base::Int64ToString(kTestContent.size()),
1672             http_request_.headers["X-Upload-Content-Length"]);
1673   EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
1674
1675   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
1676   EXPECT_EQ("/upload/drive/v2/files/resource_id?"
1677             "uploadType=resumable&setModifiedDate=true",
1678             http_request_.relative_url);
1679   EXPECT_EQ("application/json", http_request_.headers["Content-Type"]);
1680   EXPECT_TRUE(http_request_.has_content);
1681   EXPECT_EQ("{\"lastViewedByMeDate\":\"2013-07-19T15:59:13.123Z\","
1682             "\"modifiedDate\":\"2012-07-19T15:59:13.123Z\","
1683             "\"parents\":[{\"id\":\"new_parent_resource_id\","
1684             "\"kind\":\"drive#fileLink\"}],"
1685             "\"title\":\"new file title\"}",
1686             http_request_.content);
1687 }
1688
1689 TEST_F(DriveApiRequestsTest, DownloadFileRequest) {
1690   const base::FilePath kDownloadedFilePath =
1691       temp_dir_.path().AppendASCII("cache_file");
1692   const std::string kTestId("dummyId");
1693
1694   GDataErrorCode result_code = GDATA_OTHER_ERROR;
1695   base::FilePath temp_file;
1696   {
1697     base::RunLoop run_loop;
1698     drive::DownloadFileRequest* request = new drive::DownloadFileRequest(
1699         request_sender_.get(),
1700         *url_generator_,
1701         kTestId,
1702         kDownloadedFilePath,
1703         test_util::CreateQuitCallback(
1704             &run_loop,
1705             test_util::CreateCopyResultCallback(&result_code, &temp_file)),
1706         GetContentCallback(),
1707         ProgressCallback());
1708     request_sender_->StartRequestWithRetry(request);
1709     run_loop.Run();
1710   }
1711
1712   std::string contents;
1713   base::ReadFileToString(temp_file, &contents);
1714   base::DeleteFile(temp_file, false);
1715
1716   EXPECT_EQ(HTTP_SUCCESS, result_code);
1717   EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
1718   EXPECT_EQ(kTestDownloadPathPrefix + kTestId, http_request_.relative_url);
1719   EXPECT_EQ(kDownloadedFilePath, temp_file);
1720
1721   const std::string expected_contents = kTestId + kTestId + kTestId;
1722   EXPECT_EQ(expected_contents, contents);
1723 }
1724
1725 TEST_F(DriveApiRequestsTest, DownloadFileRequest_GetContentCallback) {
1726   const base::FilePath kDownloadedFilePath =
1727       temp_dir_.path().AppendASCII("cache_file");
1728   const std::string kTestId("dummyId");
1729
1730   GDataErrorCode result_code = GDATA_OTHER_ERROR;
1731   base::FilePath temp_file;
1732   std::string contents;
1733   {
1734     base::RunLoop run_loop;
1735     drive::DownloadFileRequest* request = new drive::DownloadFileRequest(
1736         request_sender_.get(),
1737         *url_generator_,
1738         kTestId,
1739         kDownloadedFilePath,
1740         test_util::CreateQuitCallback(
1741             &run_loop,
1742             test_util::CreateCopyResultCallback(&result_code, &temp_file)),
1743         base::Bind(&AppendContent, &contents),
1744         ProgressCallback());
1745     request_sender_->StartRequestWithRetry(request);
1746     run_loop.Run();
1747   }
1748
1749   base::DeleteFile(temp_file, false);
1750
1751   EXPECT_EQ(HTTP_SUCCESS, result_code);
1752   EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
1753   EXPECT_EQ(kTestDownloadPathPrefix + kTestId, http_request_.relative_url);
1754   EXPECT_EQ(kDownloadedFilePath, temp_file);
1755
1756   const std::string expected_contents = kTestId + kTestId + kTestId;
1757   EXPECT_EQ(expected_contents, contents);
1758 }
1759
1760 }  // namespace google_apis