| OLD | NEW |
| (Empty) |
| 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/common/net/gaia/gaia_urls.h" | |
| 13 #include "chrome/common/net/gaia/google_service_auth_error.h" | |
| 14 #include "chrome/common/net/gaia/oauth2_access_token_consumer.h" | |
| 15 #include "chrome/common/net/gaia/oauth2_access_token_fetcher.h" | |
| 16 #include "chrome/common/net/gaia/oauth2_api_call_flow.h" | |
| 17 #include "chrome/test/base/testing_profile.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 | |
| 29 using net::HttpRequestHeaders; | |
| 30 using net::ScopedURLFetcherFactory; | |
| 31 using net::TestURLFetcher; | |
| 32 using net::URLFetcher; | |
| 33 using net::URLFetcherDelegate; | |
| 34 using net::URLFetcherFactory; | |
| 35 using net::URLRequestStatus; | |
| 36 using testing::_; | |
| 37 using testing::Return; | |
| 38 | |
| 39 namespace { | |
| 40 | |
| 41 static std::string CreateBody() { | |
| 42 return "some body"; | |
| 43 } | |
| 44 | |
| 45 static GURL CreateApiUrl() { | |
| 46 return GURL("https://www.googleapis.com/someapi"); | |
| 47 } | |
| 48 | |
| 49 static 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 | |
| 56 class 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 | |
| 72 class 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 | |
| 86 class 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 | |
| 110 class 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 | |
| 174 TEST_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 | |
| 186 TEST_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 | |
| 204 TEST_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 | |
| 222 TEST_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 | |
| 238 TEST_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 | |
| 254 TEST_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 | |
| 270 TEST_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 | |
| 284 TEST_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 } | |
| OLD | NEW |