1 // Copyright 2014 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 // A complete set of unit tests for OAuth2AccessTokenFetcherImpl.
9 #include "base/memory/scoped_ptr.h"
10 #include "base/run_loop.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "google_apis/gaia/gaia_urls.h"
13 #include "google_apis/gaia/google_service_auth_error.h"
14 #include "google_apis/gaia/oauth2_access_token_consumer.h"
15 #include "google_apis/gaia/oauth2_access_token_fetcher_impl.h"
16 #include "net/http/http_status_code.h"
17 #include "net/url_request/test_url_fetcher_factory.h"
18 #include "net/url_request/url_fetcher.h"
19 #include "net/url_request/url_fetcher_delegate.h"
20 #include "net/url_request/url_fetcher_factory.h"
21 #include "net/url_request/url_request.h"
22 #include "net/url_request/url_request_status.h"
23 #include "net/url_request/url_request_test_util.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
28 using net::ResponseCookies
;
29 using net::ScopedURLFetcherFactory
;
30 using net::TestURLFetcher
;
31 using net::URLFetcher
;
32 using net::URLFetcherDelegate
;
33 using net::URLFetcherFactory
;
34 using net::URLRequestStatus
;
36 using testing::Return
;
40 typedef std::vector
<std::string
> ScopeList
;
42 static const char kValidTokenResponse
[] =
44 " \"access_token\": \"at1\","
45 " \"expires_in\": 3600,"
46 " \"token_type\": \"Bearer\""
48 static const char kTokenResponseNoAccessToken
[] =
50 " \"expires_in\": 3600,"
51 " \"token_type\": \"Bearer\""
54 static const char kValidFailureTokenResponse
[] =
56 " \"error\": \"invalid_grant\""
59 class MockUrlFetcherFactory
: public ScopedURLFetcherFactory
,
60 public URLFetcherFactory
{
62 MockUrlFetcherFactory() : ScopedURLFetcherFactory(this) {}
63 virtual ~MockUrlFetcherFactory() {}
65 MOCK_METHOD4(CreateURLFetcherMock
,
68 URLFetcher::RequestType request_type
,
69 URLFetcherDelegate
* d
));
71 scoped_ptr
<URLFetcher
> CreateURLFetcher(int id
,
73 URLFetcher::RequestType request_type
,
74 URLFetcherDelegate
* d
) override
{
75 return scoped_ptr
<URLFetcher
>(
76 CreateURLFetcherMock(id
, url
, request_type
, d
));
80 class MockOAuth2AccessTokenConsumer
: public OAuth2AccessTokenConsumer
{
82 MockOAuth2AccessTokenConsumer() {}
83 ~MockOAuth2AccessTokenConsumer() {}
85 MOCK_METHOD2(OnGetTokenSuccess
,
86 void(const std::string
& access_token
,
87 const base::Time
& expiration_time
));
88 MOCK_METHOD1(OnGetTokenFailure
, void(const GoogleServiceAuthError
& error
));
93 class OAuth2AccessTokenFetcherImplTest
: public testing::Test
{
95 OAuth2AccessTokenFetcherImplTest()
96 : request_context_getter_(new net::TestURLRequestContextGetter(
97 base::ThreadTaskRunnerHandle::Get())),
98 fetcher_(&consumer_
, request_context_getter_
.get(), "refresh_token") {
99 base::RunLoop().RunUntilIdle();
102 ~OAuth2AccessTokenFetcherImplTest() override
{}
104 virtual TestURLFetcher
* SetupGetAccessToken(bool fetch_succeeds
,
106 const std::string
& body
) {
107 GURL
url(GaiaUrls::GetInstance()->oauth2_token_url());
108 TestURLFetcher
* url_fetcher
= new TestURLFetcher(0, url
, &fetcher_
);
109 URLRequestStatus::Status status
=
110 fetch_succeeds
? URLRequestStatus::SUCCESS
: URLRequestStatus::FAILED
;
111 url_fetcher
->set_status(URLRequestStatus(status
, 0));
113 if (response_code
!= 0)
114 url_fetcher
->set_response_code(response_code
);
117 url_fetcher
->SetResponseString(body
);
119 EXPECT_CALL(factory_
, CreateURLFetcherMock(_
, url
, _
, _
))
120 .WillOnce(Return(url_fetcher
));
125 base::MessageLoop message_loop_
;
126 MockUrlFetcherFactory factory_
;
127 MockOAuth2AccessTokenConsumer consumer_
;
128 scoped_refptr
<net::TestURLRequestContextGetter
> request_context_getter_
;
129 OAuth2AccessTokenFetcherImpl fetcher_
;
132 // These four tests time out, see http://crbug.com/113446.
133 TEST_F(OAuth2AccessTokenFetcherImplTest
,
134 DISABLED_GetAccessTokenRequestFailure
) {
135 TestURLFetcher
* url_fetcher
= SetupGetAccessToken(false, 0, std::string());
136 EXPECT_CALL(consumer_
, OnGetTokenFailure(_
)).Times(1);
137 fetcher_
.Start("client_id", "client_secret", ScopeList());
138 fetcher_
.OnURLFetchComplete(url_fetcher
);
141 TEST_F(OAuth2AccessTokenFetcherImplTest
,
142 DISABLED_GetAccessTokenResponseCodeFailure
) {
143 TestURLFetcher
* url_fetcher
=
144 SetupGetAccessToken(true, net::HTTP_FORBIDDEN
, std::string());
145 EXPECT_CALL(consumer_
, OnGetTokenFailure(_
)).Times(1);
146 fetcher_
.Start("client_id", "client_secret", ScopeList());
147 fetcher_
.OnURLFetchComplete(url_fetcher
);
150 TEST_F(OAuth2AccessTokenFetcherImplTest
, DISABLED_Success
) {
151 TestURLFetcher
* url_fetcher
=
152 SetupGetAccessToken(true, net::HTTP_OK
, kValidTokenResponse
);
153 EXPECT_CALL(consumer_
, OnGetTokenSuccess("at1", _
)).Times(1);
154 fetcher_
.Start("client_id", "client_secret", ScopeList());
155 fetcher_
.OnURLFetchComplete(url_fetcher
);
158 TEST_F(OAuth2AccessTokenFetcherImplTest
, DISABLED_MakeGetAccessTokenBody
) {
163 "grant_type=refresh_token&"
166 OAuth2AccessTokenFetcherImpl::MakeGetAccessTokenBody(
167 "cid1", "cs1", "rt1", ScopeList()));
174 "grant_type=refresh_token&"
176 "scope=https://www.googleapis.com/foo";
178 scopes
.push_back("https://www.googleapis.com/foo");
180 OAuth2AccessTokenFetcherImpl::MakeGetAccessTokenBody(
181 "cid1", "cs1", "rt1", scopes
));
184 { // Multiple scopes.
188 "grant_type=refresh_token&"
190 "scope=https://www.googleapis.com/foo+"
191 "https://www.googleapis.com/bar+"
192 "https://www.googleapis.com/baz";
194 scopes
.push_back("https://www.googleapis.com/foo");
195 scopes
.push_back("https://www.googleapis.com/bar");
196 scopes
.push_back("https://www.googleapis.com/baz");
198 OAuth2AccessTokenFetcherImpl::MakeGetAccessTokenBody(
199 "cid1", "cs1", "rt1", scopes
));
203 // http://crbug.com/114215
205 #define MAYBE_ParseGetAccessTokenResponse DISABLED_ParseGetAccessTokenResponse
207 #define MAYBE_ParseGetAccessTokenResponse ParseGetAccessTokenResponse
208 #endif // defined(OS_WIN)
209 TEST_F(OAuth2AccessTokenFetcherImplTest
, MAYBE_ParseGetAccessTokenResponse
) {
211 TestURLFetcher
url_fetcher(0, GURL("http://www.google.com"), NULL
);
216 OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenSuccessResponse(
217 &url_fetcher
, &at
, &expires_in
));
218 EXPECT_TRUE(at
.empty());
221 TestURLFetcher
url_fetcher(0, GURL("http://www.google.com"), NULL
);
222 url_fetcher
.SetResponseString("foo");
227 OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenSuccessResponse(
228 &url_fetcher
, &at
, &expires_in
));
229 EXPECT_TRUE(at
.empty());
231 { // Valid json: access token missing.
232 TestURLFetcher
url_fetcher(0, GURL("http://www.google.com"), NULL
);
233 url_fetcher
.SetResponseString(kTokenResponseNoAccessToken
);
238 OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenSuccessResponse(
239 &url_fetcher
, &at
, &expires_in
));
240 EXPECT_TRUE(at
.empty());
242 { // Valid json: all good.
243 TestURLFetcher
url_fetcher(0, GURL("http://www.google.com"), NULL
);
244 url_fetcher
.SetResponseString(kValidTokenResponse
);
249 OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenSuccessResponse(
250 &url_fetcher
, &at
, &expires_in
));
251 EXPECT_EQ("at1", at
);
252 EXPECT_EQ(3600, expires_in
);
254 { // Valid json: invalid error response.
255 TestURLFetcher
url_fetcher(0, GURL("http://www.google.com"), NULL
);
256 url_fetcher
.SetResponseString(kTokenResponseNoAccessToken
);
260 OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenFailureResponse(
261 &url_fetcher
, &error
));
262 EXPECT_TRUE(error
.empty());
264 { // Valid json: error response.
265 TestURLFetcher
url_fetcher(0, GURL("http://www.google.com"), NULL
);
266 url_fetcher
.SetResponseString(kValidFailureTokenResponse
);
270 OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenFailureResponse(
271 &url_fetcher
, &error
));
272 EXPECT_EQ("invalid_grant", error
);