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