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. 4 5 #include "google_apis/drive/base_requests.h" 6 7 #include "base/bind.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/dummy_auth_service.h" 13 #include "google_apis/drive/request_sender.h" 14 #include "google_apis/drive/test_util.h" 15 #include "net/test/embedded_test_server/embedded_test_server.h" 16 #include "net/test/embedded_test_server/http_request.h" 17 #include "net/test/embedded_test_server/http_response.h" 18 #include "net/url_request/url_request_test_util.h" 19 #include "testing/gtest/include/gtest/gtest.h" 20 21 namespace google_apis { 22 23 namespace { 24 25 const char kValidJsonString[] = "{ \"test\": 123 }"; 26 const char kInvalidJsonString[] = "$$$"; 27 28 class FakeUrlFetchRequest : public UrlFetchRequestBase { 29 public: 30 explicit FakeUrlFetchRequest(RequestSender* sender, 31 const EntryActionCallback& callback, 32 const GURL& url) 33 : UrlFetchRequestBase(sender), 34 callback_(callback), 35 url_(url) { 36 } 37 38 virtual ~FakeUrlFetchRequest() { 39 } 40 41 protected: 42 virtual GURL GetURL() const OVERRIDE { return url_; } 43 virtual void ProcessURLFetchResults(const net::URLFetcher* source) OVERRIDE { 44 callback_.Run(GetErrorCode()); 45 } 46 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) OVERRIDE { 47 callback_.Run(code); 48 } 49 50 EntryActionCallback callback_; 51 GURL url_; 52 }; 53 54 class FakeGetDataRequest : public GetDataRequest { 55 public: 56 explicit FakeGetDataRequest(RequestSender* sender, 57 const GetDataCallback& callback, 58 const GURL& url) 59 : GetDataRequest(sender, callback), 60 url_(url) { 61 } 62 63 virtual ~FakeGetDataRequest() { 64 } 65 66 protected: 67 virtual GURL GetURL() const OVERRIDE { return url_; } 68 69 GURL url_; 70 }; 71 72 } // namespace 73 74 class BaseRequestsTest : public testing::Test { 75 public: 76 BaseRequestsTest() : response_code_(net::HTTP_OK) {} 77 78 virtual void SetUp() OVERRIDE { 79 request_context_getter_ = new net::TestURLRequestContextGetter( 80 message_loop_.message_loop_proxy()); 81 82 sender_.reset(new RequestSender(new DummyAuthService, 83 request_context_getter_.get(), 84 message_loop_.message_loop_proxy(), 85 std::string() /* custom user agent */)); 86 87 ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady()); 88 test_server_.RegisterRequestHandler( 89 base::Bind(&BaseRequestsTest::HandleRequest, base::Unretained(this))); 90 } 91 92 scoped_ptr<net::test_server::HttpResponse> HandleRequest( 93 const net::test_server::HttpRequest& request) { 94 scoped_ptr<net::test_server::BasicHttpResponse> response( 95 new net::test_server::BasicHttpResponse); 96 response->set_code(response_code_); 97 response->set_content(response_body_); 98 response->set_content_type("application/json"); 99 return response.PassAs<net::test_server::HttpResponse>(); 100 } 101 102 base::MessageLoopForIO message_loop_; 103 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_; 104 scoped_ptr<RequestSender> sender_; 105 net::test_server::EmbeddedTestServer test_server_; 106 107 net::HttpStatusCode response_code_; 108 std::string response_body_; 109 }; 110 111 TEST_F(BaseRequestsTest, ParseValidJson) { 112 scoped_ptr<base::Value> json; 113 ParseJson(message_loop_.message_loop_proxy(), 114 kValidJsonString, 115 base::Bind(test_util::CreateCopyResultCallback(&json))); 116 base::RunLoop().RunUntilIdle(); 117 118 base::DictionaryValue* root_dict = NULL; 119 ASSERT_TRUE(json); 120 ASSERT_TRUE(json->GetAsDictionary(&root_dict)); 121 122 int int_value = 0; 123 ASSERT_TRUE(root_dict->GetInteger("test", &int_value)); 124 EXPECT_EQ(123, int_value); 125 } 126 127 TEST_F(BaseRequestsTest, ParseInvalidJson) { 128 // Initialize with a valid pointer to verify that null is indeed assigned. 129 scoped_ptr<base::Value> json(base::Value::CreateNullValue()); 130 ParseJson(message_loop_.message_loop_proxy(), 131 kInvalidJsonString, 132 base::Bind(test_util::CreateCopyResultCallback(&json))); 133 base::RunLoop().RunUntilIdle(); 134 135 EXPECT_FALSE(json); 136 } 137 138 TEST_F(BaseRequestsTest, UrlFetchRequestBaseResponseCodeOverride) { 139 response_code_ = net::HTTP_FORBIDDEN; 140 response_body_ = 141 "{\"error\": {\n" 142 " \"errors\": [\n" 143 " {\n" 144 " \"domain\": \"usageLimits\",\n" 145 " \"reason\": \"rateLimitExceeded\",\n" 146 " \"message\": \"Rate Limit Exceeded\"\n" 147 " }\n" 148 " ],\n" 149 " \"code\": 403,\n" 150 " \"message\": \"Rate Limit Exceeded\"\n" 151 " }\n" 152 "}\n"; 153 154 GDataErrorCode error = GDATA_OTHER_ERROR; 155 base::RunLoop run_loop; 156 sender_->StartRequestWithRetry( 157 new FakeUrlFetchRequest( 158 sender_.get(), 159 test_util::CreateQuitCallback( 160 &run_loop, test_util::CreateCopyResultCallback(&error)), 161 test_server_.base_url())); 162 run_loop.Run(); 163 164 // HTTP_FORBIDDEN (403) is overridden by the error reason. 165 EXPECT_EQ(HTTP_SERVICE_UNAVAILABLE, error); 166 } 167 168 TEST_F(BaseRequestsTest, GetDataRequestParseValidResponse) { 169 response_body_ = kValidJsonString; 170 171 GDataErrorCode error = GDATA_OTHER_ERROR; 172 scoped_ptr<base::Value> value; 173 base::RunLoop run_loop; 174 sender_->StartRequestWithRetry( 175 new FakeGetDataRequest( 176 sender_.get(), 177 test_util::CreateQuitCallback( 178 &run_loop, test_util::CreateCopyResultCallback(&error, &value)), 179 test_server_.base_url())); 180 run_loop.Run(); 181 182 EXPECT_EQ(HTTP_SUCCESS, error); 183 EXPECT_TRUE(value); 184 } 185 186 TEST_F(BaseRequestsTest, GetDataRequestParseInvalidResponse) { 187 response_body_ = kInvalidJsonString; 188 189 GDataErrorCode error = GDATA_OTHER_ERROR; 190 scoped_ptr<base::Value> value; 191 base::RunLoop run_loop; 192 sender_->StartRequestWithRetry( 193 new FakeGetDataRequest( 194 sender_.get(), 195 test_util::CreateQuitCallback( 196 &run_loop, test_util::CreateCopyResultCallback(&error, &value)), 197 test_server_.base_url())); 198 run_loop.Run(); 199 200 EXPECT_EQ(GDATA_PARSE_ERROR, error); 201 EXPECT_FALSE(value); 202 } 203 204 } // namespace google_apis 205