Home | History | Annotate | Download | only in drive
      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, UploadExistingFileRequest) {
   1261   // Set an expected url for uploading.
   1262   expected_upload_path_ = kTestUploadExistingFilePath;
   1263 
   1264   const char kTestContentType[] = "text/plain";
   1265   const std::string kTestContent(100, 'a');
   1266   const base::FilePath kTestFilePath =
   1267       temp_dir_.path().AppendASCII("upload_file.txt");
   1268   ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
   1269 
   1270   GDataErrorCode error = GDATA_OTHER_ERROR;
   1271   GURL upload_url;
   1272 
   1273   // Initiate uploading a new file to the directory with "parent_resource_id".
   1274   {
   1275     base::RunLoop run_loop;
   1276     drive::InitiateUploadExistingFileRequest* request =
   1277         new drive::InitiateUploadExistingFileRequest(
   1278             request_sender_.get(),
   1279             *url_generator_,
   1280             kTestContentType,
   1281             kTestContent.size(),
   1282             "resource_id",  // The resource id of the file to be overwritten.
   1283             std::string(),  // No etag.
   1284             test_util::CreateQuitCallback(
   1285                 &run_loop,
   1286                 test_util::CreateCopyResultCallback(&error, &upload_url)));
   1287     request_sender_->StartRequestWithRetry(request);
   1288     run_loop.Run();
   1289   }
   1290 
   1291   EXPECT_EQ(HTTP_SUCCESS, error);
   1292   EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
   1293   EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
   1294   EXPECT_EQ(base::Int64ToString(kTestContent.size()),
   1295             http_request_.headers["X-Upload-Content-Length"]);
   1296   EXPECT_EQ("*", http_request_.headers["If-Match"]);
   1297 
   1298   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
   1299   EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
   1300             http_request_.relative_url);
   1301   EXPECT_TRUE(http_request_.has_content);
   1302   EXPECT_TRUE(http_request_.content.empty());
   1303 
   1304   // Upload the content to the upload URL.
   1305   UploadRangeResponse response;
   1306   scoped_ptr<FileResource> new_entry;
   1307 
   1308   {
   1309     base::RunLoop run_loop;
   1310     drive::ResumeUploadRequest* resume_request =
   1311         new drive::ResumeUploadRequest(
   1312             request_sender_.get(),
   1313             upload_url,
   1314             0,  // start_position
   1315             kTestContent.size(),  // end_position (exclusive)
   1316             kTestContent.size(),  // content_length,
   1317             kTestContentType,
   1318             kTestFilePath,
   1319             test_util::CreateQuitCallback(
   1320                 &run_loop,
   1321                 test_util::CreateCopyResultCallback(&response, &new_entry)),
   1322             ProgressCallback());
   1323     request_sender_->StartRequestWithRetry(resume_request);
   1324     run_loop.Run();
   1325   }
   1326 
   1327   // METHOD_PUT should be used to upload data.
   1328   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
   1329   // Request should go to the upload URL.
   1330   EXPECT_EQ(upload_url.path(), http_request_.relative_url);
   1331   // Content-Range header should be added.
   1332   EXPECT_EQ("bytes 0-" +
   1333             base::Int64ToString(kTestContent.size() - 1) + "/" +
   1334             base::Int64ToString(kTestContent.size()),
   1335             http_request_.headers["Content-Range"]);
   1336   // The upload content should be set in the HTTP request.
   1337   EXPECT_TRUE(http_request_.has_content);
   1338   EXPECT_EQ(kTestContent, http_request_.content);
   1339 
   1340   // Check the response.
   1341   EXPECT_EQ(HTTP_SUCCESS, response.code);  // Because it's an existing file
   1342   // The start and end positions should be set to -1, if an upload is complete.
   1343   EXPECT_EQ(-1, response.start_position_received);
   1344   EXPECT_EQ(-1, response.end_position_received);
   1345 }
   1346 
   1347 TEST_F(DriveApiRequestsTest, UploadExistingFileRequestWithETag) {
   1348   // Set an expected url for uploading.
   1349   expected_upload_path_ = kTestUploadExistingFilePath;
   1350 
   1351   const char kTestContentType[] = "text/plain";
   1352   const std::string kTestContent(100, 'a');
   1353   const base::FilePath kTestFilePath =
   1354       temp_dir_.path().AppendASCII("upload_file.txt");
   1355   ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
   1356 
   1357   GDataErrorCode error = GDATA_OTHER_ERROR;
   1358   GURL upload_url;
   1359 
   1360   // Initiate uploading a new file to the directory with "parent_resource_id".
   1361   {
   1362     base::RunLoop run_loop;
   1363     drive::InitiateUploadExistingFileRequest* request =
   1364         new drive::InitiateUploadExistingFileRequest(
   1365             request_sender_.get(),
   1366             *url_generator_,
   1367             kTestContentType,
   1368             kTestContent.size(),
   1369             "resource_id",  // The resource id of the file to be overwritten.
   1370             kTestETag,
   1371             test_util::CreateQuitCallback(
   1372                 &run_loop,
   1373                 test_util::CreateCopyResultCallback(&error, &upload_url)));
   1374     request_sender_->StartRequestWithRetry(request);
   1375     run_loop.Run();
   1376   }
   1377 
   1378   EXPECT_EQ(HTTP_SUCCESS, error);
   1379   EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
   1380   EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
   1381   EXPECT_EQ(base::Int64ToString(kTestContent.size()),
   1382             http_request_.headers["X-Upload-Content-Length"]);
   1383   EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
   1384 
   1385   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
   1386   EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
   1387             http_request_.relative_url);
   1388   EXPECT_TRUE(http_request_.has_content);
   1389   EXPECT_TRUE(http_request_.content.empty());
   1390 
   1391   // Upload the content to the upload URL.
   1392   UploadRangeResponse response;
   1393   scoped_ptr<FileResource> new_entry;
   1394 
   1395   {
   1396     base::RunLoop run_loop;
   1397     drive::ResumeUploadRequest* resume_request =
   1398         new drive::ResumeUploadRequest(
   1399             request_sender_.get(),
   1400             upload_url,
   1401             0,  // start_position
   1402             kTestContent.size(),  // end_position (exclusive)
   1403             kTestContent.size(),  // content_length,
   1404             kTestContentType,
   1405             kTestFilePath,
   1406             test_util::CreateQuitCallback(
   1407                 &run_loop,
   1408                 test_util::CreateCopyResultCallback(&response, &new_entry)),
   1409             ProgressCallback());
   1410     request_sender_->StartRequestWithRetry(resume_request);
   1411     run_loop.Run();
   1412   }
   1413 
   1414   // METHOD_PUT should be used to upload data.
   1415   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
   1416   // Request should go to the upload URL.
   1417   EXPECT_EQ(upload_url.path(), http_request_.relative_url);
   1418   // Content-Range header should be added.
   1419   EXPECT_EQ("bytes 0-" +
   1420             base::Int64ToString(kTestContent.size() - 1) + "/" +
   1421             base::Int64ToString(kTestContent.size()),
   1422             http_request_.headers["Content-Range"]);
   1423   // The upload content should be set in the HTTP request.
   1424   EXPECT_TRUE(http_request_.has_content);
   1425   EXPECT_EQ(kTestContent, http_request_.content);
   1426 
   1427   // Check the response.
   1428   EXPECT_EQ(HTTP_SUCCESS, response.code);  // Because it's an existing file
   1429   // The start and end positions should be set to -1, if an upload is complete.
   1430   EXPECT_EQ(-1, response.start_position_received);
   1431   EXPECT_EQ(-1, response.end_position_received);
   1432 }
   1433 
   1434 TEST_F(DriveApiRequestsTest, UploadExistingFileRequestWithETagConflicting) {
   1435   // Set an expected url for uploading.
   1436   expected_upload_path_ = kTestUploadExistingFilePath;
   1437 
   1438   // If it turned out that the etag is conflicting, PRECONDITION_FAILED should
   1439   // be returned.
   1440   expected_precondition_failed_file_path_ =
   1441       test_util::GetTestFilePath("drive/error.json");
   1442 
   1443   const char kTestContentType[] = "text/plain";
   1444   const std::string kTestContent(100, 'a');
   1445 
   1446   GDataErrorCode error = GDATA_OTHER_ERROR;
   1447   GURL upload_url;
   1448 
   1449   // Initiate uploading a new file to the directory with "parent_resource_id".
   1450   {
   1451     base::RunLoop run_loop;
   1452     drive::InitiateUploadExistingFileRequest* request =
   1453         new drive::InitiateUploadExistingFileRequest(
   1454             request_sender_.get(),
   1455             *url_generator_,
   1456             kTestContentType,
   1457             kTestContent.size(),
   1458             "resource_id",  // The resource id of the file to be overwritten.
   1459             "Conflicting-etag",
   1460             test_util::CreateQuitCallback(
   1461                 &run_loop,
   1462                 test_util::CreateCopyResultCallback(&error, &upload_url)));
   1463     request_sender_->StartRequestWithRetry(request);
   1464     run_loop.Run();
   1465   }
   1466 
   1467   EXPECT_EQ(HTTP_PRECONDITION, error);
   1468   EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
   1469   EXPECT_EQ(base::Int64ToString(kTestContent.size()),
   1470             http_request_.headers["X-Upload-Content-Length"]);
   1471   EXPECT_EQ("Conflicting-etag", http_request_.headers["If-Match"]);
   1472 
   1473   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
   1474   EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
   1475             http_request_.relative_url);
   1476   EXPECT_TRUE(http_request_.has_content);
   1477   EXPECT_TRUE(http_request_.content.empty());
   1478 }
   1479 
   1480 TEST_F(DriveApiRequestsTest,
   1481        UploadExistingFileRequestWithETagConflictOnResumeUpload) {
   1482   // Set an expected url for uploading.
   1483   expected_upload_path_ = kTestUploadExistingFilePath;
   1484 
   1485   const char kTestContentType[] = "text/plain";
   1486   const std::string kTestContent(100, 'a');
   1487   const base::FilePath kTestFilePath =
   1488       temp_dir_.path().AppendASCII("upload_file.txt");
   1489   ASSERT_TRUE(test_util::WriteStringToFile(kTestFilePath, kTestContent));
   1490 
   1491   GDataErrorCode error = GDATA_OTHER_ERROR;
   1492   GURL upload_url;
   1493 
   1494   // Initiate uploading a new file to the directory with "parent_resource_id".
   1495   {
   1496     base::RunLoop run_loop;
   1497     drive::InitiateUploadExistingFileRequest* request =
   1498         new drive::InitiateUploadExistingFileRequest(
   1499             request_sender_.get(),
   1500             *url_generator_,
   1501             kTestContentType,
   1502             kTestContent.size(),
   1503             "resource_id",  // The resource id of the file to be overwritten.
   1504             kTestETag,
   1505             test_util::CreateQuitCallback(
   1506                 &run_loop,
   1507                 test_util::CreateCopyResultCallback(&error, &upload_url)));
   1508     request_sender_->StartRequestWithRetry(request);
   1509     run_loop.Run();
   1510   }
   1511 
   1512   EXPECT_EQ(HTTP_SUCCESS, error);
   1513   EXPECT_EQ(kTestUploadExistingFilePath, upload_url.path());
   1514   EXPECT_EQ(kTestContentType, http_request_.headers["X-Upload-Content-Type"]);
   1515   EXPECT_EQ(base::Int64ToString(kTestContent.size()),
   1516             http_request_.headers["X-Upload-Content-Length"]);
   1517   EXPECT_EQ(kTestETag, http_request_.headers["If-Match"]);
   1518 
   1519   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
   1520   EXPECT_EQ("/upload/drive/v2/files/resource_id?uploadType=resumable",
   1521             http_request_.relative_url);
   1522   EXPECT_TRUE(http_request_.has_content);
   1523   EXPECT_TRUE(http_request_.content.empty());
   1524 
   1525   // Set PRECONDITION_FAILED to the server. This is the emulation of the
   1526   // confliction during uploading.
   1527   expected_precondition_failed_file_path_ =
   1528       test_util::GetTestFilePath("drive/error.json");
   1529 
   1530   // Upload the content to the upload URL.
   1531   UploadRangeResponse response;
   1532   scoped_ptr<FileResource> new_entry;
   1533 
   1534   {
   1535     base::RunLoop run_loop;
   1536     drive::ResumeUploadRequest* resume_request =
   1537         new drive::ResumeUploadRequest(
   1538             request_sender_.get(),
   1539             upload_url,
   1540             0,  // start_position
   1541             kTestContent.size(),  // end_position (exclusive)
   1542             kTestContent.size(),  // content_length,
   1543             kTestContentType,
   1544             kTestFilePath,
   1545             test_util::CreateQuitCallback(
   1546                 &run_loop,
   1547                 test_util::CreateCopyResultCallback(&response, &new_entry)),
   1548             ProgressCallback());
   1549     request_sender_->StartRequestWithRetry(resume_request);
   1550     run_loop.Run();
   1551   }
   1552 
   1553   // METHOD_PUT should be used to upload data.
   1554   EXPECT_EQ(net::test_server::METHOD_PUT, http_request_.method);
   1555   // Request should go to the upload URL.
   1556   EXPECT_EQ(upload_url.path(), http_request_.relative_url);
   1557   // Content-Range header should be added.
   1558   EXPECT_EQ("bytes 0-" +
   1559             base::Int64ToString(kTestContent.size() - 1) + "/" +
   1560             base::Int64ToString(kTestContent.size()),
   1561             http_request_.headers["Content-Range"]);
   1562   // The upload content should be set in the HTTP request.
   1563   EXPECT_TRUE(http_request_.has_content);
   1564   EXPECT_EQ(kTestContent, http_request_.content);
   1565 
   1566   // Check the response.
   1567   EXPECT_EQ(HTTP_PRECONDITION, response.code);
   1568   // The start and end positions should be set to -1 for error.
   1569   EXPECT_EQ(-1, response.start_position_received);
   1570   EXPECT_EQ(-1, response.end_position_received);
   1571 
   1572   // New entry should be NULL.
   1573   EXPECT_FALSE(new_entry.get());
   1574 }
   1575 
   1576 TEST_F(DriveApiRequestsTest, DownloadFileRequest) {
   1577   const base::FilePath kDownloadedFilePath =
   1578       temp_dir_.path().AppendASCII("cache_file");
   1579   const std::string kTestId("dummyId");
   1580 
   1581   GDataErrorCode result_code = GDATA_OTHER_ERROR;
   1582   base::FilePath temp_file;
   1583   {
   1584     base::RunLoop run_loop;
   1585     drive::DownloadFileRequest* request = new drive::DownloadFileRequest(
   1586         request_sender_.get(),
   1587         *url_generator_,
   1588         kTestId,
   1589         kDownloadedFilePath,
   1590         test_util::CreateQuitCallback(
   1591             &run_loop,
   1592             test_util::CreateCopyResultCallback(&result_code, &temp_file)),
   1593         GetContentCallback(),
   1594         ProgressCallback());
   1595     request_sender_->StartRequestWithRetry(request);
   1596     run_loop.Run();
   1597   }
   1598 
   1599   std::string contents;
   1600   base::ReadFileToString(temp_file, &contents);
   1601   base::DeleteFile(temp_file, false);
   1602 
   1603   EXPECT_EQ(HTTP_SUCCESS, result_code);
   1604   EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
   1605   EXPECT_EQ(kTestDownloadPathPrefix + kTestId, http_request_.relative_url);
   1606   EXPECT_EQ(kDownloadedFilePath, temp_file);
   1607 
   1608   const std::string expected_contents = kTestId + kTestId + kTestId;
   1609   EXPECT_EQ(expected_contents, contents);
   1610 }
   1611 
   1612 TEST_F(DriveApiRequestsTest, DownloadFileRequest_GetContentCallback) {
   1613   const base::FilePath kDownloadedFilePath =
   1614       temp_dir_.path().AppendASCII("cache_file");
   1615   const std::string kTestId("dummyId");
   1616 
   1617   GDataErrorCode result_code = GDATA_OTHER_ERROR;
   1618   base::FilePath temp_file;
   1619   std::string contents;
   1620   {
   1621     base::RunLoop run_loop;
   1622     drive::DownloadFileRequest* request = new drive::DownloadFileRequest(
   1623         request_sender_.get(),
   1624         *url_generator_,
   1625         kTestId,
   1626         kDownloadedFilePath,
   1627         test_util::CreateQuitCallback(
   1628             &run_loop,
   1629             test_util::CreateCopyResultCallback(&result_code, &temp_file)),
   1630         base::Bind(&AppendContent, &contents),
   1631         ProgressCallback());
   1632     request_sender_->StartRequestWithRetry(request);
   1633     run_loop.Run();
   1634   }
   1635 
   1636   base::DeleteFile(temp_file, false);
   1637 
   1638   EXPECT_EQ(HTTP_SUCCESS, result_code);
   1639   EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
   1640   EXPECT_EQ(kTestDownloadPathPrefix + kTestId, http_request_.relative_url);
   1641   EXPECT_EQ(kDownloadedFilePath, temp_file);
   1642 
   1643   const std::string expected_contents = kTestId + kTestId + kTestId;
   1644   EXPECT_EQ(expected_contents, contents);
   1645 }
   1646 
   1647 }  // namespace google_apis
   1648