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_.get(), "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);