oauth2_api_call_flow_unittest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 2012 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. 4// 5// A complete set of unit tests for OAuth2MintTokenFlow. 6 7#include <string> 8#include <vector> 9 10#include "base/memory/scoped_ptr.h" 11#include "base/time.h" 12#include "chrome/test/base/testing_profile.h" 13#include "google_apis/gaia/gaia_urls.h" 14#include "google_apis/gaia/google_service_auth_error.h" 15#include "google_apis/gaia/oauth2_access_token_consumer.h" 16#include "google_apis/gaia/oauth2_access_token_fetcher.h" 17#include "google_apis/gaia/oauth2_api_call_flow.h" 18#include "net/http/http_request_headers.h" 19#include "net/http/http_status_code.h" 20#include "net/url_request/test_url_fetcher_factory.h" 21#include "net/url_request/url_fetcher.h" 22#include "net/url_request/url_fetcher_delegate.h" 23#include "net/url_request/url_fetcher_factory.h" 24#include "net/url_request/url_request.h" 25#include "net/url_request/url_request_status.h" 26#include "testing/gmock/include/gmock/gmock.h" 27#include "testing/gtest/include/gtest/gtest.h" 28 29using net::HttpRequestHeaders; 30using net::ScopedURLFetcherFactory; 31using net::TestURLFetcher; 32using net::URLFetcher; 33using net::URLFetcherDelegate; 34using net::URLFetcherFactory; 35using net::URLRequestStatus; 36using testing::_; 37using testing::Return; 38 39namespace { 40 41static std::string CreateBody() { 42 return "some body"; 43} 44 45static GURL CreateApiUrl() { 46 return GURL("https://www.googleapis.com/someapi"); 47} 48 49static std::vector<std::string> CreateTestScopes() { 50 std::vector<std::string> scopes; 51 scopes.push_back("scope1"); 52 scopes.push_back("scope2"); 53 return scopes; 54} 55 56class MockUrlFetcherFactory : public ScopedURLFetcherFactory, 57 public URLFetcherFactory { 58 public: 59 MockUrlFetcherFactory() 60 : ScopedURLFetcherFactory(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { 61 } 62 virtual ~MockUrlFetcherFactory() {} 63 64 MOCK_METHOD4( 65 CreateURLFetcher, 66 URLFetcher* (int id, 67 const GURL& url, 68 URLFetcher::RequestType request_type, 69 URLFetcherDelegate* d)); 70}; 71 72class MockAccessTokenFetcher : public OAuth2AccessTokenFetcher { 73 public: 74 MockAccessTokenFetcher(OAuth2AccessTokenConsumer* consumer, 75 net::URLRequestContextGetter* getter) 76 : OAuth2AccessTokenFetcher(consumer, getter) {} 77 ~MockAccessTokenFetcher() {} 78 79 MOCK_METHOD4(Start, 80 void (const std::string& client_id, 81 const std::string& client_secret, 82 const std::string& refresh_token, 83 const std::vector<std::string>& scopes)); 84}; 85 86class MockApiCallFlow : public OAuth2ApiCallFlow { 87 public: 88 MockApiCallFlow(net::URLRequestContextGetter* context, 89 const std::string& refresh_token, 90 const std::string& access_token, 91 const std::vector<std::string>& scopes) 92 : OAuth2ApiCallFlow(context, refresh_token, access_token, scopes) {} 93 ~MockApiCallFlow() {} 94 95 MOCK_METHOD0(CreateApiCallUrl, GURL ()); 96 MOCK_METHOD0(CreateApiCallBody, std::string ()); 97 MOCK_METHOD1(ProcessApiCallSuccess, 98 void (const URLFetcher* source)); 99 MOCK_METHOD1(ProcessApiCallFailure, 100 void (const URLFetcher* source)); 101 MOCK_METHOD1(ProcessNewAccessToken, 102 void (const std::string& access_token)); 103 MOCK_METHOD1(ProcessMintAccessTokenFailure, 104 void (const GoogleServiceAuthError& error)); 105 MOCK_METHOD0(CreateAccessTokenFetcher, OAuth2AccessTokenFetcher* ()); 106}; 107 108} // namespace 109 110class OAuth2ApiCallFlowTest : public testing::Test { 111 public: 112 OAuth2ApiCallFlowTest() {} 113 virtual ~OAuth2ApiCallFlowTest() {} 114 115 protected: 116 void SetupAccessTokenFetcher( 117 const std::string& rt, const std::vector<std::string>& scopes) { 118 EXPECT_CALL(*access_token_fetcher_, 119 Start(GaiaUrls::GetInstance()->oauth2_chrome_client_id(), 120 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), 121 rt, scopes)) 122 .Times(1); 123 EXPECT_CALL(*flow_, CreateAccessTokenFetcher()) 124 .WillOnce(Return(access_token_fetcher_.release())); 125 } 126 127 TestURLFetcher* CreateURLFetcher( 128 const GURL& url, bool fetch_succeeds, 129 int response_code, const std::string& body) { 130 TestURLFetcher* url_fetcher = new TestURLFetcher(0, url, flow_.get()); 131 URLRequestStatus::Status status = 132 fetch_succeeds ? URLRequestStatus::SUCCESS : URLRequestStatus::FAILED; 133 url_fetcher->set_status(URLRequestStatus(status, 0)); 134 135 if (response_code != 0) 136 url_fetcher->set_response_code(response_code); 137 138 if (!body.empty()) 139 url_fetcher->SetResponseString(body); 140 141 return url_fetcher; 142 } 143 144 void CreateFlow(const std::string& refresh_token, 145 const std::string& access_token, 146 const std::vector<std::string>& scopes) { 147 flow_.reset(new MockApiCallFlow( 148 profile_.GetRequestContext(), 149 refresh_token, 150 access_token, 151 scopes)); 152 access_token_fetcher_.reset(new MockAccessTokenFetcher( 153 flow_.get(), profile_.GetRequestContext())); 154 } 155 156 TestURLFetcher* SetupApiCall(bool succeeds, net::HttpStatusCode status) { 157 std::string body(CreateBody()); 158 GURL url(CreateApiUrl()); 159 EXPECT_CALL(*flow_, CreateApiCallBody()).WillOnce(Return(body)); 160 EXPECT_CALL(*flow_, CreateApiCallUrl()).WillOnce(Return(url)); 161 TestURLFetcher* url_fetcher = CreateURLFetcher( 162 url, succeeds, status, ""); 163 EXPECT_CALL(factory_, CreateURLFetcher(_, url, _, _)) 164 .WillOnce(Return(url_fetcher)); 165 return url_fetcher; 166 } 167 168 MockUrlFetcherFactory factory_; 169 scoped_ptr<MockApiCallFlow> flow_; 170 scoped_ptr<MockAccessTokenFetcher> access_token_fetcher_; 171 TestingProfile profile_; 172}; 173 174TEST_F(OAuth2ApiCallFlowTest, FirstApiCallSucceeds) { 175 std::string rt = "refresh_token"; 176 std::string at = "access_token"; 177 std::vector<std::string> scopes(CreateTestScopes()); 178 179 CreateFlow(rt, at, scopes); 180 TestURLFetcher* url_fetcher = SetupApiCall(true, net::HTTP_OK); 181 EXPECT_CALL(*flow_, ProcessApiCallSuccess(url_fetcher)); 182 flow_->Start(); 183 flow_->OnURLFetchComplete(url_fetcher); 184} 185 186TEST_F(OAuth2ApiCallFlowTest, SecondApiCallSucceeds) { 187 std::string rt = "refresh_token"; 188 std::string at = "access_token"; 189 std::vector<std::string> scopes(CreateTestScopes()); 190 191 CreateFlow(rt, at, scopes); 192 TestURLFetcher* url_fetcher1 = SetupApiCall(true, net::HTTP_UNAUTHORIZED); 193 flow_->Start(); 194 SetupAccessTokenFetcher(rt, scopes); 195 flow_->OnURLFetchComplete(url_fetcher1); 196 TestURLFetcher* url_fetcher2 = SetupApiCall(true, net::HTTP_OK); 197 EXPECT_CALL(*flow_, ProcessApiCallSuccess(url_fetcher2)); 198 flow_->OnGetTokenSuccess( 199 at, 200 base::Time::Now() + base::TimeDelta::FromMinutes(3600)); 201 flow_->OnURLFetchComplete(url_fetcher2); 202} 203 204TEST_F(OAuth2ApiCallFlowTest, SecondApiCallFails) { 205 std::string rt = "refresh_token"; 206 std::string at = "access_token"; 207 std::vector<std::string> scopes(CreateTestScopes()); 208 209 CreateFlow(rt, at, scopes); 210 TestURLFetcher* url_fetcher1 = SetupApiCall(true, net::HTTP_UNAUTHORIZED); 211 flow_->Start(); 212 SetupAccessTokenFetcher(rt, scopes); 213 flow_->OnURLFetchComplete(url_fetcher1); 214 TestURLFetcher* url_fetcher2 = SetupApiCall(false, net::HTTP_UNAUTHORIZED); 215 EXPECT_CALL(*flow_, ProcessApiCallFailure(url_fetcher2)); 216 flow_->OnGetTokenSuccess( 217 at, 218 base::Time::Now() + base::TimeDelta::FromMinutes(3600)); 219 flow_->OnURLFetchComplete(url_fetcher2); 220} 221 222TEST_F(OAuth2ApiCallFlowTest, NewTokenGenerationFails) { 223 std::string rt = "refresh_token"; 224 std::string at = "access_token"; 225 std::vector<std::string> scopes(CreateTestScopes()); 226 227 CreateFlow(rt, at, scopes); 228 TestURLFetcher* url_fetcher = SetupApiCall(true, net::HTTP_UNAUTHORIZED); 229 flow_->Start(); 230 SetupAccessTokenFetcher(rt, scopes); 231 flow_->OnURLFetchComplete(url_fetcher); 232 GoogleServiceAuthError error( 233 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); 234 EXPECT_CALL(*flow_, ProcessMintAccessTokenFailure(error)); 235 flow_->OnGetTokenFailure(error); 236} 237 238TEST_F(OAuth2ApiCallFlowTest, EmptyAccessTokenFirstApiCallSucceeds) { 239 std::string rt = "refresh_token"; 240 std::string at = "access_token"; 241 std::vector<std::string> scopes(CreateTestScopes()); 242 243 CreateFlow(rt, "", scopes); 244 SetupAccessTokenFetcher(rt, scopes); 245 TestURLFetcher* url_fetcher = SetupApiCall(true, net::HTTP_OK); 246 EXPECT_CALL(*flow_, ProcessApiCallSuccess(url_fetcher)); 247 flow_->Start(); 248 flow_->OnGetTokenSuccess( 249 at, 250 base::Time::Now() + base::TimeDelta::FromMinutes(3600)); 251 flow_->OnURLFetchComplete(url_fetcher); 252} 253 254TEST_F(OAuth2ApiCallFlowTest, EmptyAccessTokenApiCallFails) { 255 std::string rt = "refresh_token"; 256 std::string at = "access_token"; 257 std::vector<std::string> scopes(CreateTestScopes()); 258 259 CreateFlow(rt, "", scopes); 260 SetupAccessTokenFetcher(rt, scopes); 261 TestURLFetcher* url_fetcher = SetupApiCall(false, net::HTTP_BAD_GATEWAY); 262 EXPECT_CALL(*flow_, ProcessApiCallFailure(url_fetcher)); 263 flow_->Start(); 264 flow_->OnGetTokenSuccess( 265 at, 266 base::Time::Now() + base::TimeDelta::FromMinutes(3600)); 267 flow_->OnURLFetchComplete(url_fetcher); 268} 269 270TEST_F(OAuth2ApiCallFlowTest, EmptyAccessTokenNewTokenGenerationFails) { 271 std::string rt = "refresh_token"; 272 std::string at = "access_token"; 273 std::vector<std::string> scopes(CreateTestScopes()); 274 275 CreateFlow(rt, "", scopes); 276 SetupAccessTokenFetcher(rt, scopes); 277 GoogleServiceAuthError error( 278 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); 279 EXPECT_CALL(*flow_, ProcessMintAccessTokenFailure(error)); 280 flow_->Start(); 281 flow_->OnGetTokenFailure(error); 282} 283 284TEST_F(OAuth2ApiCallFlowTest, CreateURLFetcher) { 285 std::string rt = "refresh_token"; 286 std::string at = "access_token"; 287 std::vector<std::string> scopes(CreateTestScopes()); 288 std::string body = CreateBody(); 289 GURL url(CreateApiUrl()); 290 291 CreateFlow(rt, at, scopes); 292 scoped_ptr<TestURLFetcher> url_fetcher(SetupApiCall(true, net::HTTP_OK)); 293 flow_->CreateURLFetcher(); 294 HttpRequestHeaders headers; 295 url_fetcher->GetExtraRequestHeaders(&headers); 296 std::string auth_header; 297 EXPECT_TRUE(headers.GetHeader("Authorization", &auth_header)); 298 EXPECT_EQ("Bearer access_token", auth_header); 299 EXPECT_EQ(url, url_fetcher->GetOriginalURL()); 300 EXPECT_EQ(body, url_fetcher->upload_data()); 301} 302