Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / remoting / test / access_token_fetcher_unittest.cc
blob6ab9c8291fafcb1ce09e7c03b8a7afb44cab518a
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"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "google_apis/gaia/gaia_urls.h"
13 #include "net/url_request/test_url_fetcher_factory.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace {
17 const char kAuthCodeValue[] = "test_auth_code_value";
18 const char kAccessTokenValue[] = "test_access_token_value";
19 const char kRefreshTokenValue[] = "test_refresh_token_value";
20 const char kAuthCodeExchangeValidResponse[] =
21 "{"
22 " \"refresh_token\": \"test_refresh_token_value\","
23 " \"access_token\": \"test_access_token_value\","
24 " \"expires_in\": 3600,"
25 " \"token_type\": \"Bearer\""
26 "}";
27 const char kAuthCodeExchangeEmptyResponse[] = "{}";
28 const char kRefreshTokenExchangeValidResponse[] =
29 "{"
30 " \"access_token\": \"test_access_token_value\","
31 " \"expires_in\": 3600,"
32 " \"token_type\": \"Bearer\""
33 "}";
34 const char kRefreshTokenExchangeEmptyResponse[] = "{}";
35 const char kValidTokenInfoResponse[] =
36 "{"
37 " \"audience\": \"blah.apps.googleusercontent.blah.com\","
38 " \"used_id\": \"1234567890\","
39 " \"scope\": \"all the things\","
40 " \"expires_in\": \"1800\","
41 " \"token_type\": \"Bearer\""
42 "}";
43 const char kInvalidTokenInfoResponse[] =
44 "{"
45 " \"error\": \"invalid_token\""
46 "}";
47 } // namespace
49 namespace remoting {
50 namespace test {
52 // Provides base functionality for the AccessTokenFetcher Tests below. The
53 // FakeURLFetcherFactory allows us to override the response data and payload for
54 // specified URLs. We use this to stub out network calls made by the
55 // AccessTokenFetcher. This fixture also creates an IO MessageLoop, if
56 // necessary, for use by the AccessTokenFetcher.
57 class AccessTokenFetcherTest : public ::testing::Test {
58 public:
59 AccessTokenFetcherTest();
60 ~AccessTokenFetcherTest() override;
62 void OnAccessTokenRetrieved(base::Closure done_closure,
63 const std::string& access_token,
64 const std::string& refresh_token);
66 protected:
67 // Test interface.
68 void SetUp() override;
70 void SetFakeResponse(const GURL& url,
71 const std::string& data,
72 net::HttpStatusCode code,
73 net::URLRequestStatus::Status status);
75 // Used for result verification
76 std::string access_token_retrieved_;
77 std::string refresh_token_retrieved_;
79 private:
80 net::FakeURLFetcherFactory url_fetcher_factory_;
81 scoped_ptr<base::MessageLoopForIO> message_loop_;
83 DISALLOW_COPY_AND_ASSIGN(AccessTokenFetcherTest);
86 AccessTokenFetcherTest::AccessTokenFetcherTest()
87 : url_fetcher_factory_(nullptr) {
90 AccessTokenFetcherTest::~AccessTokenFetcherTest() {
93 void AccessTokenFetcherTest::OnAccessTokenRetrieved(
94 base::Closure done_closure,
95 const std::string& access_token,
96 const std::string& refresh_token) {
97 access_token_retrieved_ = access_token;
98 refresh_token_retrieved_ = refresh_token;
100 done_closure.Run();
103 void AccessTokenFetcherTest::SetUp() {
104 if (!base::MessageLoop::current()) {
105 // Create a temporary message loop if the current thread does not already
106 // have one so we can use its task runner to create a request object.
107 message_loop_.reset(new base::MessageLoopForIO);
111 void AccessTokenFetcherTest::SetFakeResponse(
112 const GURL& url,
113 const std::string& data,
114 net::HttpStatusCode code,
115 net::URLRequestStatus::Status status) {
116 url_fetcher_factory_.SetFakeResponse(url, data, code, status);
119 TEST_F(AccessTokenFetcherTest, ExchangeAuthCodeForAccessToken) {
120 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
121 kAuthCodeExchangeValidResponse, net::HTTP_OK,
122 net::URLRequestStatus::SUCCESS);
124 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_info_url(),
125 kValidTokenInfoResponse, net::HTTP_OK,
126 net::URLRequestStatus::SUCCESS);
128 base::RunLoop run_loop;
129 AccessTokenCallback access_token_callback =
130 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved,
131 base::Unretained(this), run_loop.QuitClosure());
133 AccessTokenFetcher access_token_fetcher;
134 access_token_fetcher.GetAccessTokenFromAuthCode(kAuthCodeValue,
135 access_token_callback);
137 run_loop.Run();
139 EXPECT_EQ(access_token_retrieved_.compare(kAccessTokenValue), 0);
140 EXPECT_EQ(refresh_token_retrieved_.compare(kRefreshTokenValue), 0);
143 TEST_F(AccessTokenFetcherTest, ExchangeRefreshTokenForAccessToken) {
144 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
145 kRefreshTokenExchangeValidResponse, net::HTTP_OK,
146 net::URLRequestStatus::SUCCESS);
148 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_info_url(),
149 kValidTokenInfoResponse, net::HTTP_OK,
150 net::URLRequestStatus::SUCCESS);
152 base::RunLoop run_loop;
153 AccessTokenCallback access_token_callback =
154 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved,
155 base::Unretained(this), run_loop.QuitClosure());
157 AccessTokenFetcher access_token_fetcher;
158 access_token_fetcher.GetAccessTokenFromRefreshToken(kRefreshTokenValue,
159 access_token_callback);
161 run_loop.Run();
163 EXPECT_EQ(access_token_retrieved_.compare(kAccessTokenValue), 0);
164 EXPECT_EQ(refresh_token_retrieved_.compare(kRefreshTokenValue), 0);
167 TEST_F(AccessTokenFetcherTest, MultipleAccessTokenCalls) {
168 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
169 kAuthCodeExchangeValidResponse, net::HTTP_OK,
170 net::URLRequestStatus::SUCCESS);
172 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_info_url(),
173 kValidTokenInfoResponse, net::HTTP_OK,
174 net::URLRequestStatus::SUCCESS);
176 scoped_ptr<base::RunLoop> run_loop;
177 run_loop.reset(new base::RunLoop());
178 AccessTokenCallback access_token_callback =
179 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved,
180 base::Unretained(this), run_loop->QuitClosure());
182 AccessTokenFetcher access_token_fetcher;
183 access_token_fetcher.GetAccessTokenFromAuthCode(kAuthCodeValue,
184 access_token_callback);
186 run_loop->Run();
188 EXPECT_EQ(access_token_retrieved_.compare(kAccessTokenValue), 0);
189 EXPECT_EQ(refresh_token_retrieved_.compare(kRefreshTokenValue), 0);
191 // Reset our token data for the next iteration.
192 access_token_retrieved_.clear();
193 refresh_token_retrieved_.clear();
195 // Update the response since we will call the refresh token method next.
196 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
197 kRefreshTokenExchangeValidResponse, net::HTTP_OK,
198 net::URLRequestStatus::SUCCESS);
200 run_loop.reset(new base::RunLoop());
201 access_token_callback =
202 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved,
203 base::Unretained(this), run_loop->QuitClosure());
205 access_token_fetcher.GetAccessTokenFromRefreshToken(kRefreshTokenValue,
206 access_token_callback);
208 run_loop->Run();
210 EXPECT_EQ(access_token_retrieved_.compare(kAccessTokenValue), 0);
211 EXPECT_EQ(refresh_token_retrieved_.compare(kRefreshTokenValue), 0);
213 run_loop.reset(new base::RunLoop());
214 access_token_callback =
215 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved,
216 base::Unretained(this), run_loop->QuitClosure());
218 // Reset our token data for the next iteration.
219 access_token_retrieved_.clear();
220 refresh_token_retrieved_.clear();
222 access_token_fetcher.GetAccessTokenFromRefreshToken(kRefreshTokenValue,
223 access_token_callback);
225 run_loop->Run();
227 EXPECT_EQ(access_token_retrieved_.compare(kAccessTokenValue), 0);
228 EXPECT_EQ(refresh_token_retrieved_.compare(kRefreshTokenValue), 0);
231 TEST_F(AccessTokenFetcherTest, ExchangeAuthCode_Unauthorized_Error) {
232 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
233 kAuthCodeExchangeValidResponse, net::HTTP_UNAUTHORIZED,
234 net::URLRequestStatus::FAILED);
236 base::RunLoop run_loop;
237 AccessTokenCallback access_token_callback =
238 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved,
239 base::Unretained(this), run_loop.QuitClosure());
241 AccessTokenFetcher access_token_fetcher;
242 access_token_fetcher.GetAccessTokenFromAuthCode(kAuthCodeValue,
243 access_token_callback);
245 run_loop.Run();
247 // Our callback should have been called with empty strings.
248 EXPECT_TRUE(access_token_retrieved_.empty());
249 EXPECT_TRUE(refresh_token_retrieved_.empty());
252 TEST_F(AccessTokenFetcherTest, ExchangeRefreshToken_Unauthorized_Error) {
253 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
254 kRefreshTokenExchangeValidResponse, net::HTTP_UNAUTHORIZED,
255 net::URLRequestStatus::FAILED);
257 base::RunLoop run_loop;
258 AccessTokenCallback access_token_callback =
259 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved,
260 base::Unretained(this), run_loop.QuitClosure());
262 AccessTokenFetcher access_token_fetcher;
263 access_token_fetcher.GetAccessTokenFromRefreshToken(kRefreshTokenValue,
264 access_token_callback);
266 run_loop.Run();
268 // Our callback should have been called with empty strings.
269 EXPECT_TRUE(access_token_retrieved_.empty());
270 EXPECT_TRUE(refresh_token_retrieved_.empty());
273 TEST_F(AccessTokenFetcherTest, ExchangeAuthCode_NetworkError) {
274 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
275 kAuthCodeExchangeValidResponse, net::HTTP_NOT_FOUND,
276 net::URLRequestStatus::FAILED);
278 base::RunLoop run_loop;
279 AccessTokenCallback access_token_callback =
280 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved,
281 base::Unretained(this), run_loop.QuitClosure());
283 AccessTokenFetcher access_token_fetcher;
284 access_token_fetcher.GetAccessTokenFromAuthCode(kAuthCodeValue,
285 access_token_callback);
287 run_loop.Run();
289 // Our callback should have been called with empty strings.
290 EXPECT_TRUE(access_token_retrieved_.empty());
291 EXPECT_TRUE(refresh_token_retrieved_.empty());
294 TEST_F(AccessTokenFetcherTest, ExchangeRefreshToken_NetworkError) {
295 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
296 kRefreshTokenExchangeValidResponse, net::HTTP_NOT_FOUND,
297 net::URLRequestStatus::FAILED);
299 base::RunLoop run_loop;
300 AccessTokenCallback access_token_callback =
301 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved,
302 base::Unretained(this), run_loop.QuitClosure());
304 AccessTokenFetcher access_token_fetcher;
305 access_token_fetcher.GetAccessTokenFromRefreshToken(kRefreshTokenValue,
306 access_token_callback);
308 run_loop.Run();
310 // Our callback should have been called with empty strings.
311 EXPECT_TRUE(access_token_retrieved_.empty());
312 EXPECT_TRUE(refresh_token_retrieved_.empty());
315 TEST_F(AccessTokenFetcherTest, AuthCode_GetTokenInfoResponse_InvalidToken) {
316 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
317 kAuthCodeExchangeValidResponse, net::HTTP_OK,
318 net::URLRequestStatus::SUCCESS);
320 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_info_url(),
321 kInvalidTokenInfoResponse, net::HTTP_OK,
322 net::URLRequestStatus::SUCCESS);
324 base::RunLoop run_loop;
325 AccessTokenCallback access_token_callback =
326 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved,
327 base::Unretained(this), run_loop.QuitClosure());
329 AccessTokenFetcher access_token_fetcher;
330 access_token_fetcher.GetAccessTokenFromAuthCode(kAuthCodeValue,
331 access_token_callback);
333 run_loop.Run();
335 // Our callback should have been called with empty strings.
336 EXPECT_TRUE(access_token_retrieved_.empty());
337 EXPECT_TRUE(refresh_token_retrieved_.empty());
340 TEST_F(AccessTokenFetcherTest, ExchangeAuthCodeForAccessToken_EmptyToken) {
341 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
342 kAuthCodeExchangeEmptyResponse, net::HTTP_OK,
343 net::URLRequestStatus::SUCCESS);
345 base::RunLoop run_loop;
346 AccessTokenCallback access_token_callback =
347 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved,
348 base::Unretained(this), run_loop.QuitClosure());
350 AccessTokenFetcher access_token_fetcher;
351 access_token_fetcher.GetAccessTokenFromAuthCode(kAuthCodeValue,
352 access_token_callback);
354 run_loop.Run();
356 // Our callback should have been called with empty strings.
357 EXPECT_TRUE(access_token_retrieved_.empty());
358 EXPECT_TRUE(refresh_token_retrieved_.empty());
361 TEST_F(AccessTokenFetcherTest, RefreshToken_GetTokenInfoResponse_InvalidToken) {
362 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
363 kRefreshTokenExchangeValidResponse, net::HTTP_OK,
364 net::URLRequestStatus::SUCCESS);
366 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_info_url(),
367 kInvalidTokenInfoResponse, net::HTTP_OK,
368 net::URLRequestStatus::SUCCESS);
370 base::RunLoop run_loop;
371 AccessTokenCallback access_token_callback =
372 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved,
373 base::Unretained(this), run_loop.QuitClosure());
375 AccessTokenFetcher access_token_fetcher;
376 access_token_fetcher.GetAccessTokenFromRefreshToken(kRefreshTokenValue,
377 access_token_callback);
379 run_loop.Run();
381 // Our callback should have been called with empty strings.
382 EXPECT_TRUE(access_token_retrieved_.empty());
383 EXPECT_TRUE(refresh_token_retrieved_.empty());
386 TEST_F(AccessTokenFetcherTest, ExchangeRefreshTokenForAccessToken_EmptyToken) {
387 SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
388 kRefreshTokenExchangeEmptyResponse, net::HTTP_OK,
389 net::URLRequestStatus::SUCCESS);
391 base::RunLoop run_loop;
392 AccessTokenCallback access_token_callback =
393 base::Bind(&AccessTokenFetcherTest::OnAccessTokenRetrieved,
394 base::Unretained(this), run_loop.QuitClosure());
396 AccessTokenFetcher access_token_fetcher;
397 access_token_fetcher.GetAccessTokenFromRefreshToken(kRefreshTokenValue,
398 access_token_callback);
400 run_loop.Run();
402 // Our callback should have been called with empty strings.
403 EXPECT_TRUE(access_token_retrieved_.empty());
404 EXPECT_TRUE(refresh_token_retrieved_.empty());
407 } // namespace test
408 } // namespace remoting