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 "google_apis/gaia/gaia_urls.h"
12 #include "google_apis/gaia/google_service_auth_error.h"
13 #include "google_apis/gaia/oauth2_access_token_consumer.h"
14 #include "google_apis/gaia/oauth2_access_token_fetcher_impl.h"
15 #include "net/http/http_status_code.h"
16 #include "net/url_request/test_url_fetcher_factory.h"
17 #include "net/url_request/url_fetcher.h"
18 #include "net/url_request/url_fetcher_delegate.h"
19 #include "net/url_request/url_fetcher_factory.h"
20 #include "net/url_request/url_request.h"
21 #include "net/url_request/url_request_status.h"
22 #include "net/url_request/url_request_test_util.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
27 using net::ResponseCookies
;
28 using net::ScopedURLFetcherFactory
;
29 using net::TestURLFetcher
;
30 using net::URLFetcher
;
31 using net::URLFetcherDelegate
;
32 using net::URLFetcherFactory
;
33 using net::URLRequestStatus
;
35 using testing::Return
;
39 typedef std::vector
<std::string
> ScopeList
;
41 static const char kValidTokenResponse
[] =
43 " \"access_token\": \"at1\","
44 " \"expires_in\": 3600,"
45 " \"token_type\": \"Bearer\""
47 static const char kTokenResponseNoAccessToken
[] =
49 " \"expires_in\": 3600,"
50 " \"token_type\": \"Bearer\""
53 static const char kValidFailureTokenResponse
[] =
55 " \"error\": \"invalid_grant\""
58 class MockUrlFetcherFactory
: public ScopedURLFetcherFactory
,
59 public URLFetcherFactory
{
61 MockUrlFetcherFactory() : ScopedURLFetcherFactory(this) {}
62 virtual ~MockUrlFetcherFactory() {}
64 MOCK_METHOD4(CreateURLFetcher
,
67 URLFetcher::RequestType request_type
,
68 URLFetcherDelegate
* d
));
71 class MockOAuth2AccessTokenConsumer
: public OAuth2AccessTokenConsumer
{
73 MockOAuth2AccessTokenConsumer() {}
74 ~MockOAuth2AccessTokenConsumer() {}
76 MOCK_METHOD2(OnGetTokenSuccess
,
77 void(const std::string
& access_token
,
78 const base::Time
& expiration_time
));
79 MOCK_METHOD1(OnGetTokenFailure
, void(const GoogleServiceAuthError
& error
));
84 class OAuth2AccessTokenFetcherImplTest
: public testing::Test
{
86 OAuth2AccessTokenFetcherImplTest()
87 : request_context_getter_(new net::TestURLRequestContextGetter(
88 base::MessageLoopProxy::current())),
89 fetcher_(&consumer_
, request_context_getter_
, "refresh_token") {
90 base::RunLoop().RunUntilIdle();
93 virtual ~OAuth2AccessTokenFetcherImplTest() {}
95 virtual TestURLFetcher
* SetupGetAccessToken(bool fetch_succeeds
,
97 const std::string
& body
) {
98 GURL
url(GaiaUrls::GetInstance()->oauth2_token_url());
99 TestURLFetcher
* url_fetcher
= new TestURLFetcher(0, url
, &fetcher_
);
100 URLRequestStatus::Status status
=
101 fetch_succeeds
? URLRequestStatus::SUCCESS
: URLRequestStatus::FAILED
;
102 url_fetcher
->set_status(URLRequestStatus(status
, 0));
104 if (response_code
!= 0)
105 url_fetcher
->set_response_code(response_code
);
108 url_fetcher
->SetResponseString(body
);
110 EXPECT_CALL(factory_
, CreateURLFetcher(_
, url
, _
, _
))
111 .WillOnce(Return(url_fetcher
));
116 base::MessageLoop message_loop_
;
117 MockUrlFetcherFactory factory_
;
118 MockOAuth2AccessTokenConsumer consumer_
;
119 scoped_refptr
<net::TestURLRequestContextGetter
> request_context_getter_
;
120 OAuth2AccessTokenFetcherImpl fetcher_
;
123 // These four tests time out, see http://crbug.com/113446.
124 TEST_F(OAuth2AccessTokenFetcherImplTest
,
125 DISABLED_GetAccessTokenRequestFailure
) {
126 TestURLFetcher
* url_fetcher
= SetupGetAccessToken(false, 0, std::string());
127 EXPECT_CALL(consumer_
, OnGetTokenFailure(_
)).Times(1);
128 fetcher_
.Start("client_id", "client_secret", ScopeList());
129 fetcher_
.OnURLFetchComplete(url_fetcher
);
132 TEST_F(OAuth2AccessTokenFetcherImplTest
,
133 DISABLED_GetAccessTokenResponseCodeFailure
) {
134 TestURLFetcher
* url_fetcher
=
135 SetupGetAccessToken(true, net::HTTP_FORBIDDEN
, 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
, DISABLED_Success
) {
142 TestURLFetcher
* url_fetcher
=
143 SetupGetAccessToken(true, net::HTTP_OK
, kValidTokenResponse
);
144 EXPECT_CALL(consumer_
, OnGetTokenSuccess("at1", _
)).Times(1);
145 fetcher_
.Start("client_id", "client_secret", ScopeList());
146 fetcher_
.OnURLFetchComplete(url_fetcher
);
149 TEST_F(OAuth2AccessTokenFetcherImplTest
, DISABLED_MakeGetAccessTokenBody
) {
154 "grant_type=refresh_token&"
157 OAuth2AccessTokenFetcherImpl::MakeGetAccessTokenBody(
158 "cid1", "cs1", "rt1", ScopeList()));
165 "grant_type=refresh_token&"
167 "scope=https://www.googleapis.com/foo";
169 scopes
.push_back("https://www.googleapis.com/foo");
171 OAuth2AccessTokenFetcherImpl::MakeGetAccessTokenBody(
172 "cid1", "cs1", "rt1", scopes
));
175 { // Multiple scopes.
179 "grant_type=refresh_token&"
181 "scope=https://www.googleapis.com/foo+"
182 "https://www.googleapis.com/bar+"
183 "https://www.googleapis.com/baz";
185 scopes
.push_back("https://www.googleapis.com/foo");
186 scopes
.push_back("https://www.googleapis.com/bar");
187 scopes
.push_back("https://www.googleapis.com/baz");
189 OAuth2AccessTokenFetcherImpl::MakeGetAccessTokenBody(
190 "cid1", "cs1", "rt1", scopes
));
194 // http://crbug.com/114215
196 #define MAYBE_ParseGetAccessTokenResponse DISABLED_ParseGetAccessTokenResponse
198 #define MAYBE_ParseGetAccessTokenResponse ParseGetAccessTokenResponse
199 #endif // defined(OS_WIN)
200 TEST_F(OAuth2AccessTokenFetcherImplTest
, MAYBE_ParseGetAccessTokenResponse
) {
202 TestURLFetcher
url_fetcher(0, GURL("www.google.com"), NULL
);
207 OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenSuccessResponse(
208 &url_fetcher
, &at
, &expires_in
));
209 EXPECT_TRUE(at
.empty());
212 TestURLFetcher
url_fetcher(0, GURL("www.google.com"), NULL
);
213 url_fetcher
.SetResponseString("foo");
218 OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenSuccessResponse(
219 &url_fetcher
, &at
, &expires_in
));
220 EXPECT_TRUE(at
.empty());
222 { // Valid json: access token missing.
223 TestURLFetcher
url_fetcher(0, GURL("www.google.com"), NULL
);
224 url_fetcher
.SetResponseString(kTokenResponseNoAccessToken
);
229 OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenSuccessResponse(
230 &url_fetcher
, &at
, &expires_in
));
231 EXPECT_TRUE(at
.empty());
233 { // Valid json: all good.
234 TestURLFetcher
url_fetcher(0, GURL("www.google.com"), NULL
);
235 url_fetcher
.SetResponseString(kValidTokenResponse
);
240 OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenSuccessResponse(
241 &url_fetcher
, &at
, &expires_in
));
242 EXPECT_EQ("at1", at
);
243 EXPECT_EQ(3600, expires_in
);
245 { // Valid json: invalid error response.
246 TestURLFetcher
url_fetcher(0, GURL("www.google.com"), NULL
);
247 url_fetcher
.SetResponseString(kTokenResponseNoAccessToken
);
251 OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenFailureResponse(
252 &url_fetcher
, &error
));
253 EXPECT_TRUE(error
.empty());
255 { // Valid json: error response.
256 TestURLFetcher
url_fetcher(0, GURL("www.google.com"), NULL
);
257 url_fetcher
.SetResponseString(kValidFailureTokenResponse
);
261 OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenFailureResponse(
262 &url_fetcher
, &error
));
263 EXPECT_EQ("invalid_grant", error
);