1 // Copyright (c) 2012 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.
5 #include "google_apis/drive/base_requests.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h"
11 #include "base/values.h"
12 #include "google_apis/drive/drive_api_parser.h"
13 #include "google_apis/drive/drive_api_requests.h"
14 #include "google_apis/drive/dummy_auth_service.h"
15 #include "google_apis/drive/request_sender.h"
16 #include "google_apis/drive/test_util.h"
17 #include "net/test/embedded_test_server/embedded_test_server.h"
18 #include "net/test/embedded_test_server/http_request.h"
19 #include "net/test/embedded_test_server/http_response.h"
20 #include "net/url_request/url_request_test_util.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 namespace google_apis
{
27 const char kValidJsonString
[] = "{ \"test\": 123 }";
28 const char kInvalidJsonString
[] = "$$$";
30 class FakeUrlFetchRequest
: public UrlFetchRequestBase
{
32 FakeUrlFetchRequest(RequestSender
* sender
,
33 const EntryActionCallback
& callback
,
35 : UrlFetchRequestBase(sender
),
40 ~FakeUrlFetchRequest() override
{}
43 GURL
GetURL() const override
{ return url_
; }
44 void ProcessURLFetchResults(const net::URLFetcher
* source
) override
{
45 callback_
.Run(GetErrorCode());
47 void RunCallbackOnPrematureFailure(DriveApiErrorCode code
) override
{
51 EntryActionCallback callback_
;
55 class FakeMultipartUploadRequest
: public MultipartUploadRequestBase
{
57 FakeMultipartUploadRequest(
58 base::SequencedTaskRunner
* blocking_task_runner
,
59 const std::string
& metadata_json
,
60 const std::string
& content_type
,
62 const base::FilePath
& local_file_path
,
63 const FileResourceCallback
& callback
,
64 const google_apis::ProgressCallback
& progress_callback
,
66 std::string
* upload_content_type
,
67 std::string
* upload_content_data
)
68 : MultipartUploadRequestBase(blocking_task_runner
,
76 upload_content_type_(upload_content_type
),
77 upload_content_data_(upload_content_data
) {}
79 ~FakeMultipartUploadRequest() override
{}
81 net::URLFetcher::RequestType
GetRequestType() const override
{
82 return net::URLFetcher::POST
;
85 bool GetContentData(std::string
* content_type
,
86 std::string
* content_data
) override
{
88 MultipartUploadRequestBase::GetContentData(content_type
, content_data
);
89 *upload_content_type_
= *content_type
;
90 *upload_content_data_
= *content_data
;
95 GURL
GetURL() const override
{ return url_
; }
99 std::string
* const upload_content_type_
;
100 std::string
* const upload_content_data_
;
105 class BaseRequestsTest
: public testing::Test
{
107 BaseRequestsTest() : response_code_(net::HTTP_OK
) {}
109 void SetUp() override
{
110 request_context_getter_
= new net::TestURLRequestContextGetter(
111 message_loop_
.task_runner());
113 sender_
.reset(new RequestSender(new DummyAuthService
,
114 request_context_getter_
.get(),
115 message_loop_
.task_runner(),
116 std::string() /* custom user agent */));
118 ASSERT_TRUE(test_server_
.InitializeAndWaitUntilReady());
119 test_server_
.RegisterRequestHandler(
120 base::Bind(&BaseRequestsTest::HandleRequest
, base::Unretained(this)));
123 scoped_ptr
<net::test_server::HttpResponse
> HandleRequest(
124 const net::test_server::HttpRequest
& request
) {
125 scoped_ptr
<net::test_server::BasicHttpResponse
> response(
126 new net::test_server::BasicHttpResponse
);
127 response
->set_code(response_code_
);
128 response
->set_content(response_body_
);
129 response
->set_content_type("application/json");
130 return response
.Pass();
133 base::MessageLoopForIO message_loop_
;
134 scoped_refptr
<net::TestURLRequestContextGetter
> request_context_getter_
;
135 scoped_ptr
<RequestSender
> sender_
;
136 net::test_server::EmbeddedTestServer test_server_
;
138 net::HttpStatusCode response_code_
;
139 std::string response_body_
;
142 typedef BaseRequestsTest MultipartUploadRequestBaseTest
;
144 TEST_F(BaseRequestsTest
, ParseValidJson
) {
145 scoped_ptr
<base::Value
> json(ParseJson(kValidJsonString
));
147 base::DictionaryValue
* root_dict
= NULL
;
149 ASSERT_TRUE(json
->GetAsDictionary(&root_dict
));
152 ASSERT_TRUE(root_dict
->GetInteger("test", &int_value
));
153 EXPECT_EQ(123, int_value
);
156 TEST_F(BaseRequestsTest
, ParseInvalidJson
) {
157 EXPECT_FALSE(ParseJson(kInvalidJsonString
));
160 TEST_F(BaseRequestsTest
, UrlFetchRequestBaseResponseCodeOverride
) {
161 response_code_
= net::HTTP_FORBIDDEN
;
166 " \"domain\": \"usageLimits\",\n"
167 " \"reason\": \"rateLimitExceeded\",\n"
168 " \"message\": \"Rate Limit Exceeded\"\n"
172 " \"message\": \"Rate Limit Exceeded\"\n"
176 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
177 base::RunLoop run_loop
;
178 sender_
->StartRequestWithAuthRetry(new FakeUrlFetchRequest(
180 test_util::CreateQuitCallback(
181 &run_loop
, test_util::CreateCopyResultCallback(&error
)),
182 test_server_
.base_url()));
185 // HTTP_FORBIDDEN (403) is overridden by the error reason.
186 EXPECT_EQ(HTTP_SERVICE_UNAVAILABLE
, error
);
189 TEST_F(MultipartUploadRequestBaseTest
, Basic
) {
190 response_code_
= net::HTTP_OK
;
191 response_body_
= "{\"kind\": \"drive#file\", \"id\": \"file_id\"}";
192 scoped_ptr
<google_apis::FileResource
> file
;
193 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
194 base::RunLoop run_loop
;
195 const base::FilePath source_path
=
196 google_apis::test_util::GetTestFilePath("drive/text.txt");
197 std::string upload_content_type
;
198 std::string upload_content_data
;
199 FakeMultipartUploadRequest
* const multipart_request
=
200 new FakeMultipartUploadRequest(
201 sender_
->blocking_task_runner(), "{json:\"test\"}", "text/plain", 10,
203 test_util::CreateQuitCallback(
204 &run_loop
, test_util::CreateCopyResultCallback(&error
, &file
)),
205 ProgressCallback(), test_server_
.base_url(), &upload_content_type
,
206 &upload_content_data
);
207 multipart_request
->SetBoundaryForTesting("TESTBOUNDARY");
208 scoped_ptr
<drive::SingleBatchableDelegateRequest
> request(
209 new drive::SingleBatchableDelegateRequest(
210 sender_
.get(), multipart_request
));
211 sender_
->StartRequestWithAuthRetry(request
.release());
213 EXPECT_EQ("multipart/related; boundary=TESTBOUNDARY", upload_content_type
);
216 "Content-Type: application/json\n"
220 "Content-Type: text/plain\n"
222 "This is a sample file. I like chocolate and chips.\n"
225 upload_content_data
);
226 ASSERT_EQ(HTTP_SUCCESS
, error
);
227 EXPECT_EQ("file_id", file
->file_id());
230 } // Namespace google_apis