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/dummy_auth_service.h"
14 #include "google_apis/drive/request_sender.h"
15 #include "google_apis/drive/test_util.h"
16 #include "net/test/embedded_test_server/embedded_test_server.h"
17 #include "net/test/embedded_test_server/http_request.h"
18 #include "net/test/embedded_test_server/http_response.h"
19 #include "net/url_request/url_request_test_util.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 namespace google_apis
{
26 const char kValidJsonString
[] = "{ \"test\": 123 }";
27 const char kInvalidJsonString
[] = "$$$";
29 class FakeUrlFetchRequest
: public UrlFetchRequestBase
{
31 FakeUrlFetchRequest(RequestSender
* sender
,
32 const EntryActionCallback
& callback
,
34 : UrlFetchRequestBase(sender
),
39 ~FakeUrlFetchRequest() override
{}
42 GURL
GetURL() const override
{ return url_
; }
43 void ProcessURLFetchResults(const net::URLFetcher
* source
) override
{
44 callback_
.Run(GetErrorCode());
46 void RunCallbackOnPrematureFailure(DriveApiErrorCode code
) override
{
50 EntryActionCallback callback_
;
54 class FakeMultipartUploadRequest
: public MultipartUploadRequestBase
{
56 FakeMultipartUploadRequest(
57 RequestSender
* sender
,
58 const std::string
& metadata_json
,
59 const std::string
& content_type
,
61 const base::FilePath
& local_file_path
,
62 const FileResourceCallback
& callback
,
63 const google_apis::ProgressCallback
& progress_callback
,
65 std::string
* upload_content_type
,
66 std::string
* upload_content_data
)
67 : MultipartUploadRequestBase(sender
,
75 upload_content_type_(upload_content_type
),
76 upload_content_data_(upload_content_data
) {}
78 ~FakeMultipartUploadRequest() override
{}
80 bool GetContentData(std::string
* content_type
,
81 std::string
* content_data
) override
{
83 MultipartUploadRequestBase::GetContentData(content_type
, content_data
);
84 *upload_content_type_
= *content_type
;
85 *upload_content_data_
= *content_data
;
89 base::SequencedTaskRunner
* blocking_task_runner() const {
90 return MultipartUploadRequestBase::blocking_task_runner();
94 GURL
GetURL() const override
{ return url_
; }
98 std::string
* const upload_content_type_
;
99 std::string
* const upload_content_data_
;
104 class BaseRequestsTest
: public testing::Test
{
106 BaseRequestsTest() : response_code_(net::HTTP_OK
) {}
108 void SetUp() override
{
109 request_context_getter_
= new net::TestURLRequestContextGetter(
110 message_loop_
.message_loop_proxy());
112 sender_
.reset(new RequestSender(new DummyAuthService
,
113 request_context_getter_
.get(),
114 message_loop_
.message_loop_proxy(),
115 std::string() /* custom user agent */));
117 ASSERT_TRUE(test_server_
.InitializeAndWaitUntilReady());
118 test_server_
.RegisterRequestHandler(
119 base::Bind(&BaseRequestsTest::HandleRequest
, base::Unretained(this)));
122 scoped_ptr
<net::test_server::HttpResponse
> HandleRequest(
123 const net::test_server::HttpRequest
& request
) {
124 scoped_ptr
<net::test_server::BasicHttpResponse
> response(
125 new net::test_server::BasicHttpResponse
);
126 response
->set_code(response_code_
);
127 response
->set_content(response_body_
);
128 response
->set_content_type("application/json");
129 return response
.Pass();
132 base::MessageLoopForIO message_loop_
;
133 scoped_refptr
<net::TestURLRequestContextGetter
> request_context_getter_
;
134 scoped_ptr
<RequestSender
> sender_
;
135 net::test_server::EmbeddedTestServer test_server_
;
137 net::HttpStatusCode response_code_
;
138 std::string response_body_
;
141 typedef BaseRequestsTest MultipartUploadRequestBaseTest
;
143 TEST_F(BaseRequestsTest
, ParseValidJson
) {
144 scoped_ptr
<base::Value
> json(ParseJson(kValidJsonString
));
146 base::DictionaryValue
* root_dict
= NULL
;
148 ASSERT_TRUE(json
->GetAsDictionary(&root_dict
));
151 ASSERT_TRUE(root_dict
->GetInteger("test", &int_value
));
152 EXPECT_EQ(123, int_value
);
155 TEST_F(BaseRequestsTest
, ParseInvalidJson
) {
156 EXPECT_FALSE(ParseJson(kInvalidJsonString
));
159 TEST_F(BaseRequestsTest
, UrlFetchRequestBaseResponseCodeOverride
) {
160 response_code_
= net::HTTP_FORBIDDEN
;
165 " \"domain\": \"usageLimits\",\n"
166 " \"reason\": \"rateLimitExceeded\",\n"
167 " \"message\": \"Rate Limit Exceeded\"\n"
171 " \"message\": \"Rate Limit Exceeded\"\n"
175 DriveApiErrorCode error
= DRIVE_OTHER_ERROR
;
176 base::RunLoop run_loop
;
177 sender_
->StartRequestWithRetry(
178 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("chromeos/file_manager/text.txt");
197 std::string upload_content_type
;
198 std::string upload_content_data
;
199 scoped_ptr
<FakeMultipartUploadRequest
> request(new FakeMultipartUploadRequest(
200 sender_
.get(), "{json:\"test\"}", "text/plain", 10, source_path
,
201 test_util::CreateQuitCallback(
202 &run_loop
, test_util::CreateCopyResultCallback(&error
, &file
)),
203 ProgressCallback(), test_server_
.base_url(), &upload_content_type
,
204 &upload_content_data
));
205 request
->SetBoundaryForTesting("TESTBOUNDARY");
206 sender_
->StartRequestWithRetry(request
.release());
208 EXPECT_EQ("multipart/related; boundary=TESTBOUNDARY", upload_content_type
);
211 "Content-Type: application/json\n"
215 "Content-Type: text/plain\n"
217 "This is a sample file. I like chocolate and chips.\n"
220 upload_content_data
);
221 ASSERT_EQ(HTTP_SUCCESS
, error
);
222 EXPECT_EQ("file_id", file
->file_id());
225 } // Namespace google_apis