1 // Copyright 2015 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 "remoting/test/access_token_fetcher.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "google_apis/gaia/gaia_urls.h"
11 #include "net/url_request/test_url_fetcher_factory.h"
12 #include "testing/gtest/include/gtest/gtest.h"
15 const char kAuthCodeValue
[] = "test_auth_code_value";
16 const char kAccessTokenValue
[] = "test_access_token_value";
17 const char kRefreshTokenValue
[] = "test_refresh_token_value";
18 const char kAuthCodeExchangeValidResponse
[] =
20 " \"refresh_token\": \"test_refresh_token_value\","
21 " \"access_token\": \"test_access_token_value\","
22 " \"expires_in\": 3600,"
23 " \"token_type\": \"Bearer\""
25 const char kAuthCodeExchangeEmptyResponse
[] = "{}";
26 const char kRefreshTokenExchangeValidResponse
[] =
28 " \"access_token\": \"test_access_token_value\","
29 " \"expires_in\": 3600,"
30 " \"token_type\": \"Bearer\""
32 const char kRefreshTokenExchangeEmptyResponse
[] = "{}";
33 const char kValidTokenInfoResponse
[] =
35 " \"audience\": \"blah.apps.googleusercontent.blah.com\","
36 " \"used_id\": \"1234567890\","
37 " \"scope\": \"all the things\","
38 " \"expires_in\": \"1800\","
39 " \"token_type\": \"Bearer\""
41 const char kInvalidTokenInfoResponse
[] =
43 " \"error\": \"invalid_token\""
50 // Provides base functionality for the AccessTokenFetcher Tests below. The
51 // FakeURLFetcherFactory allows us to override the response data and payload for
52 // specified URLs. We use this to stub out network calls made by the
53 // AccessTokenFetcher. This fixture also creates an IO MessageLoop, if
54 // necessary, for use by the AccessTokenFetcher.
55 class AccessTokenFetcherTest
: public ::testing::Test
{
57 AccessTokenFetcherTest() :
58 url_fetcher_factory_(nullptr) {}
59 ~AccessTokenFetcherTest() override
{}
61 void OnAccessTokenRetrieved(
62 base::Closure done_closure
,
63 const std::string
& access_token
,
64 const std::string
& refresh_token
) {
65 access_token_retrieved_
= access_token
;
66 refresh_token_retrieved_
= refresh_token
;
73 void SetUp() override
{
74 if (!base::MessageLoop::current()) {
75 // Create a temporary message loop if the current thread does not already
76 // have one so we can use its task runner to create a request object.
77 message_loop_
.reset(new base::MessageLoopForIO
);
81 void SetFakeResponse(const GURL
& url
,
82 const std::string
& data
,
83 net::HttpStatusCode code
,
84 net::URLRequestStatus::Status status
) {
85 url_fetcher_factory_
.SetFakeResponse(url
, data
, code
, status
);
88 // Used for result verification
89 std::string access_token_retrieved_
;
90 std::string refresh_token_retrieved_
;
93 net::FakeURLFetcherFactory url_fetcher_factory_
;
94 scoped_ptr
<base::MessageLoopForIO
> message_loop_
;
96 DISALLOW_COPY_AND_ASSIGN(AccessTokenFetcherTest
);
99 TEST_F(AccessTokenFetcherTest
, ExchangeAuthCodeForAccessToken
) {
101 GaiaUrls::GetInstance()->oauth2_token_url(),
102 kAuthCodeExchangeValidResponse
,
104 net::URLRequestStatus::SUCCESS
);
107 GaiaUrls::GetInstance()->oauth2_token_info_url(),
108 kValidTokenInfoResponse
,
110 net::URLRequestStatus::SUCCESS
);
112 base::RunLoop run_loop
;
113 AccessTokenCallback access_token_callback
=
114 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved
,
115 base::Unretained(this),
116 run_loop
.QuitClosure());
118 AccessTokenFetcher access_token_fetcher
;
119 access_token_fetcher
.GetAccessTokenFromAuthCode(
121 access_token_callback
);
125 EXPECT_STREQ(kAccessTokenValue
, access_token_retrieved_
.c_str());
126 EXPECT_STREQ(kRefreshTokenValue
, refresh_token_retrieved_
.c_str());
129 TEST_F(AccessTokenFetcherTest
, ExchangeRefreshTokenForAccessToken
) {
131 GaiaUrls::GetInstance()->oauth2_token_url(),
132 kRefreshTokenExchangeValidResponse
,
134 net::URLRequestStatus::SUCCESS
);
137 GaiaUrls::GetInstance()->oauth2_token_info_url(),
138 kValidTokenInfoResponse
,
140 net::URLRequestStatus::SUCCESS
);
142 base::RunLoop run_loop
;
143 AccessTokenCallback access_token_callback
=
144 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved
,
145 base::Unretained(this),
146 run_loop
.QuitClosure());
148 AccessTokenFetcher access_token_fetcher
;
149 access_token_fetcher
.GetAccessTokenFromRefreshToken(
151 access_token_callback
);
155 EXPECT_STREQ(kAccessTokenValue
, access_token_retrieved_
.c_str());
156 EXPECT_STREQ(kRefreshTokenValue
, refresh_token_retrieved_
.c_str());
159 TEST_F(AccessTokenFetcherTest
, MultipleAccessTokenCalls
) {
161 GaiaUrls::GetInstance()->oauth2_token_url(),
162 kAuthCodeExchangeValidResponse
,
164 net::URLRequestStatus::SUCCESS
);
167 GaiaUrls::GetInstance()->oauth2_token_info_url(),
168 kValidTokenInfoResponse
,
170 net::URLRequestStatus::SUCCESS
);
172 scoped_ptr
<base::RunLoop
> run_loop
;
173 run_loop
.reset(new base::RunLoop());
174 AccessTokenCallback access_token_callback
=
175 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved
,
176 base::Unretained(this),
177 run_loop
->QuitClosure());
179 AccessTokenFetcher access_token_fetcher
;
180 access_token_fetcher
.GetAccessTokenFromAuthCode(
182 access_token_callback
);
186 EXPECT_STREQ(kAccessTokenValue
, access_token_retrieved_
.c_str());
187 EXPECT_STREQ(kRefreshTokenValue
, refresh_token_retrieved_
.c_str());
189 // Reset our token data for the next iteration.
190 access_token_retrieved_
.clear();
191 refresh_token_retrieved_
.clear();
193 // Update the response since we will call the refresh token method next.
195 GaiaUrls::GetInstance()->oauth2_token_url(),
196 kRefreshTokenExchangeValidResponse
,
198 net::URLRequestStatus::SUCCESS
);
200 run_loop
.reset(new base::RunLoop());
201 access_token_callback
=
202 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved
,
203 base::Unretained(this),
204 run_loop
->QuitClosure());
206 access_token_fetcher
.GetAccessTokenFromRefreshToken(
208 access_token_callback
);
212 EXPECT_STREQ(kAccessTokenValue
,
213 access_token_retrieved_
.c_str());
214 EXPECT_STREQ(kRefreshTokenValue
,
215 refresh_token_retrieved_
.c_str());
217 run_loop
.reset(new base::RunLoop());
218 access_token_callback
=
219 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved
,
220 base::Unretained(this),
221 run_loop
->QuitClosure());
223 // Reset our token data for the next iteration.
224 access_token_retrieved_
.clear();
225 refresh_token_retrieved_
.clear();
227 access_token_fetcher
.GetAccessTokenFromRefreshToken(
229 access_token_callback
);
233 EXPECT_STREQ(kAccessTokenValue
,
234 access_token_retrieved_
.c_str());
235 EXPECT_STREQ(kRefreshTokenValue
,
236 refresh_token_retrieved_
.c_str());
239 TEST_F(AccessTokenFetcherTest
, ExchangeAuthCode_Unauthorized_Error
) {
241 GaiaUrls::GetInstance()->oauth2_token_url(),
242 kAuthCodeExchangeValidResponse
,
243 net::HTTP_UNAUTHORIZED
,
244 net::URLRequestStatus::FAILED
);
246 base::RunLoop run_loop
;
247 AccessTokenCallback access_token_callback
=
248 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved
,
249 base::Unretained(this),
250 run_loop
.QuitClosure());
252 AccessTokenFetcher access_token_fetcher
;
253 access_token_fetcher
.GetAccessTokenFromAuthCode(
255 access_token_callback
);
259 EXPECT_STREQ("", access_token_retrieved_
.c_str());
260 EXPECT_STREQ("", refresh_token_retrieved_
.c_str());
263 TEST_F(AccessTokenFetcherTest
, ExchangeRefreshToken_Unauthorized_Error
) {
265 GaiaUrls::GetInstance()->oauth2_token_url(),
266 kRefreshTokenExchangeValidResponse
,
267 net::HTTP_UNAUTHORIZED
,
268 net::URLRequestStatus::FAILED
);
270 base::RunLoop run_loop
;
271 AccessTokenCallback access_token_callback
=
272 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved
,
273 base::Unretained(this),
274 run_loop
.QuitClosure());
276 AccessTokenFetcher access_token_fetcher
;
277 access_token_fetcher
.GetAccessTokenFromRefreshToken(
279 access_token_callback
);
283 EXPECT_STREQ("", access_token_retrieved_
.c_str());
284 EXPECT_STREQ("", refresh_token_retrieved_
.c_str());
287 TEST_F(AccessTokenFetcherTest
, ExchangeAuthCode_NetworkError
) {
289 GaiaUrls::GetInstance()->oauth2_token_url(),
290 kAuthCodeExchangeValidResponse
,
292 net::URLRequestStatus::FAILED
);
294 base::RunLoop run_loop
;
295 AccessTokenCallback access_token_callback
=
296 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved
,
297 base::Unretained(this),
298 run_loop
.QuitClosure());
300 AccessTokenFetcher access_token_fetcher
;
301 access_token_fetcher
.GetAccessTokenFromAuthCode(
303 access_token_callback
);
307 EXPECT_STREQ("", access_token_retrieved_
.c_str());
308 EXPECT_STREQ("", refresh_token_retrieved_
.c_str());
311 TEST_F(AccessTokenFetcherTest
, ExchangeRefreshToken_NetworkError
) {
313 GaiaUrls::GetInstance()->oauth2_token_url(),
314 kRefreshTokenExchangeValidResponse
,
316 net::URLRequestStatus::FAILED
);
318 base::RunLoop run_loop
;
319 AccessTokenCallback access_token_callback
=
320 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved
,
321 base::Unretained(this),
322 run_loop
.QuitClosure());
324 AccessTokenFetcher access_token_fetcher
;
325 access_token_fetcher
.GetAccessTokenFromRefreshToken(
327 access_token_callback
);
331 EXPECT_STREQ("", access_token_retrieved_
.c_str());
332 EXPECT_STREQ("", refresh_token_retrieved_
.c_str());
335 TEST_F(AccessTokenFetcherTest
, AuthCode_GetTokenInfoResponse_InvalidToken
) {
337 GaiaUrls::GetInstance()->oauth2_token_url(),
338 kAuthCodeExchangeValidResponse
,
340 net::URLRequestStatus::SUCCESS
);
343 GaiaUrls::GetInstance()->oauth2_token_info_url(),
344 kInvalidTokenInfoResponse
,
346 net::URLRequestStatus::SUCCESS
);
348 base::RunLoop run_loop
;
349 AccessTokenCallback access_token_callback
=
350 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved
,
351 base::Unretained(this),
352 run_loop
.QuitClosure());
354 AccessTokenFetcher access_token_fetcher
;
355 access_token_fetcher
.GetAccessTokenFromAuthCode(
357 access_token_callback
);
361 // Our callback should have been called with empty strings.
362 EXPECT_STREQ("", access_token_retrieved_
.c_str());
363 EXPECT_STREQ("", refresh_token_retrieved_
.c_str());
366 TEST_F(AccessTokenFetcherTest
, ExchangeAuthCodeForAccessToken_EmptyToken
) {
368 GaiaUrls::GetInstance()->oauth2_token_url(),
369 kAuthCodeExchangeEmptyResponse
,
371 net::URLRequestStatus::SUCCESS
);
373 base::RunLoop run_loop
;
374 AccessTokenCallback access_token_callback
=
375 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved
,
376 base::Unretained(this),
377 run_loop
.QuitClosure());
379 AccessTokenFetcher access_token_fetcher
;
380 access_token_fetcher
.GetAccessTokenFromAuthCode(
382 access_token_callback
);
386 // Our callback should have been called with empty strings.
387 EXPECT_STREQ("", access_token_retrieved_
.c_str());
388 EXPECT_STREQ("", refresh_token_retrieved_
.c_str());
391 TEST_F(AccessTokenFetcherTest
, RefreshToken_GetTokenInfoResponse_InvalidToken
) {
393 GaiaUrls::GetInstance()->oauth2_token_url(),
394 kRefreshTokenExchangeValidResponse
,
396 net::URLRequestStatus::SUCCESS
);
399 GaiaUrls::GetInstance()->oauth2_token_info_url(),
400 kInvalidTokenInfoResponse
,
402 net::URLRequestStatus::SUCCESS
);
404 base::RunLoop run_loop
;
405 AccessTokenCallback access_token_callback
=
406 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved
,
407 base::Unretained(this),
408 run_loop
.QuitClosure());
410 AccessTokenFetcher access_token_fetcher
;
411 access_token_fetcher
.GetAccessTokenFromRefreshToken(
413 access_token_callback
);
417 // Our callback should have been called with empty strings.
418 EXPECT_STREQ("", access_token_retrieved_
.c_str());
419 EXPECT_STREQ("", refresh_token_retrieved_
.c_str());
422 TEST_F(AccessTokenFetcherTest
, ExchangeRefreshTokenForAccessToken_EmptyToken
) {
424 GaiaUrls::GetInstance()->oauth2_token_url(),
425 kRefreshTokenExchangeEmptyResponse
,
427 net::URLRequestStatus::SUCCESS
);
429 base::RunLoop run_loop
;
430 AccessTokenCallback access_token_callback
=
431 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved
,
432 base::Unretained(this),
433 run_loop
.QuitClosure());
435 AccessTokenFetcher access_token_fetcher
;
436 access_token_fetcher
.GetAccessTokenFromRefreshToken(
438 access_token_callback
);
442 // Our callback should have been called with empty strings.
443 EXPECT_STREQ("", access_token_retrieved_
.c_str());
444 EXPECT_STREQ("", refresh_token_retrieved_
.c_str());
448 } // namespace remoting