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(GDataErrorCode code
) override
{
50 EntryActionCallback callback_
;
54 class FakeMultipartUploadRequest
: public MultipartUploadRequestBase
{
56 FakeMultipartUploadRequest(
57 RequestSender
* sender
,
58 const std::string
& title
,
59 const std::string
& parent_resource_id
,
60 const std::string
& content_type
,
62 const base::Time
& modified_date
,
63 const base::Time
& last_viewed_by_me_date
,
64 const base::FilePath
& local_file_path
,
65 const FileResourceCallback
& callback
,
66 const google_apis::ProgressCallback
& progress_callback
,
68 std::string
* upload_content_type
,
69 std::string
* upload_content_data
)
70 : MultipartUploadRequestBase(sender
,
76 last_viewed_by_me_date
,
81 upload_content_type_(upload_content_type
),
82 upload_content_data_(upload_content_data
) {}
84 ~FakeMultipartUploadRequest() override
{}
86 bool GetContentData(std::string
* content_type
,
87 std::string
* content_data
) override
{
89 MultipartUploadRequestBase::GetContentData(content_type
, content_data
);
90 *upload_content_type_
= *content_type
;
91 *upload_content_data_
= *content_data
;
95 base::SequencedTaskRunner
* blocking_task_runner() const {
96 return MultipartUploadRequestBase::blocking_task_runner();
100 GURL
GetURL() const override
{ return url_
; }
104 std::string
* const upload_content_type_
;
105 std::string
* const upload_content_data_
;
110 class BaseRequestsTest
: public testing::Test
{
112 BaseRequestsTest() : response_code_(net::HTTP_OK
) {}
114 void SetUp() override
{
115 request_context_getter_
= new net::TestURLRequestContextGetter(
116 message_loop_
.message_loop_proxy());
118 sender_
.reset(new RequestSender(new DummyAuthService
,
119 request_context_getter_
.get(),
120 message_loop_
.message_loop_proxy(),
121 std::string() /* custom user agent */));
123 ASSERT_TRUE(test_server_
.InitializeAndWaitUntilReady());
124 test_server_
.RegisterRequestHandler(
125 base::Bind(&BaseRequestsTest::HandleRequest
, base::Unretained(this)));
128 scoped_ptr
<net::test_server::HttpResponse
> HandleRequest(
129 const net::test_server::HttpRequest
& request
) {
130 scoped_ptr
<net::test_server::BasicHttpResponse
> response(
131 new net::test_server::BasicHttpResponse
);
132 response
->set_code(response_code_
);
133 response
->set_content(response_body_
);
134 response
->set_content_type("application/json");
135 return response
.Pass();
138 base::MessageLoopForIO message_loop_
;
139 scoped_refptr
<net::TestURLRequestContextGetter
> request_context_getter_
;
140 scoped_ptr
<RequestSender
> sender_
;
141 net::test_server::EmbeddedTestServer test_server_
;
143 net::HttpStatusCode response_code_
;
144 std::string response_body_
;
147 typedef BaseRequestsTest MultipartUploadRequestBaseTest
;
149 TEST_F(BaseRequestsTest
, ParseValidJson
) {
150 scoped_ptr
<base::Value
> json(ParseJson(kValidJsonString
));
152 base::DictionaryValue
* root_dict
= NULL
;
154 ASSERT_TRUE(json
->GetAsDictionary(&root_dict
));
157 ASSERT_TRUE(root_dict
->GetInteger("test", &int_value
));
158 EXPECT_EQ(123, int_value
);
161 TEST_F(BaseRequestsTest
, ParseInvalidJson
) {
162 EXPECT_FALSE(ParseJson(kInvalidJsonString
));
165 TEST_F(BaseRequestsTest
, UrlFetchRequestBaseResponseCodeOverride
) {
166 response_code_
= net::HTTP_FORBIDDEN
;
171 " \"domain\": \"usageLimits\",\n"
172 " \"reason\": \"rateLimitExceeded\",\n"
173 " \"message\": \"Rate Limit Exceeded\"\n"
177 " \"message\": \"Rate Limit Exceeded\"\n"
181 GDataErrorCode error
= GDATA_OTHER_ERROR
;
182 base::RunLoop run_loop
;
183 sender_
->StartRequestWithRetry(
184 new FakeUrlFetchRequest(
186 test_util::CreateQuitCallback(
187 &run_loop
, test_util::CreateCopyResultCallback(&error
)),
188 test_server_
.base_url()));
191 // HTTP_FORBIDDEN (403) is overridden by the error reason.
192 EXPECT_EQ(HTTP_SERVICE_UNAVAILABLE
, error
);
195 TEST_F(MultipartUploadRequestBaseTest
, Basic
) {
196 response_code_
= net::HTTP_OK
;
197 response_body_
= "{\"kind\": \"drive#file\", \"id\": \"file_id\"}";
198 scoped_ptr
<google_apis::FileResource
> file
;
199 GDataErrorCode error
= GDATA_OTHER_ERROR
;
200 base::RunLoop run_loop
;
201 const base::FilePath source_path
=
202 google_apis::test_util::GetTestFilePath("chromeos/file_manager/text.txt");
203 std::string upload_content_type
;
204 std::string upload_content_data
;
205 scoped_ptr
<FakeMultipartUploadRequest
> request(new FakeMultipartUploadRequest(
206 sender_
.get(), "test.txt", "parent_id", "text/plain", 10, base::Time(),
207 base::Time(), source_path
,
208 test_util::CreateQuitCallback(
209 &run_loop
, test_util::CreateCopyResultCallback(&error
, &file
)),
210 ProgressCallback(), test_server_
.base_url(), &upload_content_type
,
211 &upload_content_data
));
212 request
->SetBoundaryForTesting("TESTBOUNDARY");
213 sender_
->StartRequestWithRetry(request
.release());
215 EXPECT_EQ("multipart/related; boundary=TESTBOUNDARY", upload_content_type
);
218 "Content-Type: application/json\n"
220 "{\"parents\":[{\"id\":\"parent_id\",\"kind\":\"drive#fileLink\"}],"
221 "\"title\":\"test.txt\"}\n"
223 "Content-Type: text/plain\n"
225 "This is a sample file. I like chocolate and chips.\n"
228 upload_content_data
);
229 ASSERT_EQ(HTTP_SUCCESS
, error
);
230 EXPECT_EQ("file_id", file
->file_id());
233 } // Namespace google_apis