drive_api_requests_unittest.cc 93 KB

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