Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6153)

Unified Diff: chrome/browser/managed_mode/managed_user_refresh_token_fetcher_unittest.cc

Issue 16173008: Reland 203015 "Add ManagedUserTokenFetcher to fetch scoped-down ..." (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/managed_mode/managed_user_refresh_token_fetcher_unittest.cc
diff --git a/chrome/browser/managed_mode/managed_user_refresh_token_fetcher_unittest.cc b/chrome/browser/managed_mode/managed_user_refresh_token_fetcher_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..83c828586a6dc8f6823d42b1673d4fcb1412bb9a
--- /dev/null
+++ b/chrome/browser/managed_mode/managed_user_refresh_token_fetcher_unittest.cc
@@ -0,0 +1,426 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop.h"
+#include "base/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/managed_mode/managed_user_refresh_token_fetcher.h"
+#include "chrome/browser/signin/oauth2_token_service.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/test/test_browser_thread.h"
+#include "google_apis/gaia/gaia_urls.h"
+#include "google_apis/gaia/google_service_auth_error.h"
+#include "net/base/net_errors.h"
+#include "net/base/url_util.h"
+#include "net/http/http_request_headers.h"
+#include "net/http/http_status_code.h"
+#include "net/url_request/test_url_fetcher_factory.h"
+#include "net/url_request/url_fetcher_delegate.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const char kManagedUserId[] = "abcdef";
+const char kName[] = "Homestar";
+const char kDeviceName[] = "Compy";
+
+const char kAccessToken[] = "accesstoken";
+const char kAuthorizationCode[] = "authorizationcode";
+const char kManagedUserToken[] = "managedusertoken";
+
+const char kIssueTokenResponseFormat[] =
+ "{"
+ " \"code\": \"%s\""
+ "}";
+
+const char kGetRefreshTokenResponseFormat[] =
+ "{"
+ " \"access_token\": \"<ignored>\","
+ " \"expires_in\": 12345,"
+ " \"refresh_token\": \"%s\""
+ "}";
+
+// MockOAuth2TokenService ---------------------------------------------
+
+class MockOAuth2TokenService : public OAuth2TokenService {
+ public:
+ class Request : public OAuth2TokenService::Request {
+ public:
+ Request(const OAuth2TokenService::ScopeSet& scopes,
+ OAuth2TokenService::Consumer* consumer,
+ MockOAuth2TokenService* owner);
+ virtual ~Request();
+
+ void Succeed();
+ void Fail(GoogleServiceAuthError::State error);
+
+ const OAuth2TokenService::ScopeSet& scopes() const { return scopes_; }
+
+ private:
+ OAuth2TokenService::ScopeSet scopes_;
+
+ OAuth2TokenService::Consumer* consumer_;
+
+ MockOAuth2TokenService* owner_;
+ };
+
+ MockOAuth2TokenService();
+ virtual ~MockOAuth2TokenService();
+
+ Request* request() const { return request_; }
+
+ void ClearRequest(Request* request);
+
+ private:
+ // OAuth2TokenService overrides:
+ virtual scoped_ptr<OAuth2TokenService::Request> StartRequest(
+ const OAuth2TokenService::ScopeSet& scopes,
+ OAuth2TokenService::Consumer* consumer) OVERRIDE;
+ virtual std::string GetRefreshToken() OVERRIDE;
+
+ Request* request_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockOAuth2TokenService);
+};
+
+MockOAuth2TokenService::Request::Request(
+ const OAuth2TokenService::ScopeSet& scopes,
+ OAuth2TokenService::Consumer* consumer,
+ MockOAuth2TokenService* owner)
+ : scopes_(scopes),
+ consumer_(consumer),
+ owner_(owner) {}
+
+MockOAuth2TokenService::Request::~Request() {
+ owner_->ClearRequest(this);
+}
+
+void MockOAuth2TokenService::Request::Succeed() {
+ base::Time expiration_date = base::Time::Now() +
+ base::TimeDelta::FromHours(1);
+ consumer_->OnGetTokenSuccess(this, kAccessToken, expiration_date);
+}
+
+void MockOAuth2TokenService::Request::Fail(
+ GoogleServiceAuthError::State error) {
+ consumer_->OnGetTokenFailure(this, GoogleServiceAuthError(error));
+}
+
+MockOAuth2TokenService::MockOAuth2TokenService()
+ : OAuth2TokenService(NULL),
+ request_(NULL) {}
+
+MockOAuth2TokenService::~MockOAuth2TokenService() {
+ EXPECT_FALSE(request_);
+}
+
+void MockOAuth2TokenService::ClearRequest(
+ MockOAuth2TokenService::Request* request) {
+ if (request_ == request)
+ request_ = NULL;
+}
+
+scoped_ptr<OAuth2TokenService::Request> MockOAuth2TokenService::StartRequest(
+ const OAuth2TokenService::ScopeSet& scopes,
+ OAuth2TokenService::Consumer* consumer) {
+ scoped_ptr<Request> request(new Request(scopes, consumer, this));
+ request_ = request.get();
+ return request.PassAs<OAuth2TokenService::Request>();
+}
+
+std::string MockOAuth2TokenService::GetRefreshToken() {
+ NOTREACHED();
+ return std::string();
+}
+
+// Utility methods --------------------------------------------------
+
+// Slightly hacky way to extract a value from a URL-encoded POST request body.
+bool GetValueForKey(const std::string& encoded_string,
+ const std::string& key,
+ std::string* value) {
+ GURL url("http://example.com/?" + encoded_string);
+ return net::GetValueForKeyInQuery(url, key, value);
+}
+
+void SendResponse(net::TestURLFetcher* url_fetcher,
+ const std::string& response) {
+ url_fetcher->set_status(
+ net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0));
+ url_fetcher->set_response_code(net::HTTP_OK);
+ url_fetcher->SetResponseString(response);
+ url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
+}
+
+void SetNetworkError(net::TestURLFetcher* url_fetcher, int error) {
+ url_fetcher->set_status(
+ net::URLRequestStatus(net::URLRequestStatus::FAILED, error));
+ url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
+}
+
+void SetHttpError(net::TestURLFetcher* url_fetcher, int error) {
+ url_fetcher->set_status(net::URLRequestStatus());
+ url_fetcher->set_response_code(error);
+ url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
+}
+
+} // namespace
+
+class ManagedUserRefreshTokenFetcherTest : public testing::Test {
+ public:
+ ManagedUserRefreshTokenFetcherTest();
+ virtual ~ManagedUserRefreshTokenFetcherTest() {}
+
+ protected:
+ void StartFetching();
+
+ MockOAuth2TokenService::Request* GetOAuth2TokenServiceRequest();
+ net::TestURLFetcher* GetIssueTokenRequest();
+ net::TestURLFetcher* GetRefreshTokenRequest();
+
+ void MakeIssueTokenRequestSucceed();
+ void MakeRefreshTokenFetchSucceed();
+
+ void Reset();
+
+ const GoogleServiceAuthError& error() const { return error_; }
+ const std::string& token() const { return token_; }
+
+ private:
+ void OnTokenFetched(const GoogleServiceAuthError& error,
+ const std::string& token);
+
+ base::WeakPtrFactory<ManagedUserRefreshTokenFetcherTest> weak_ptr_factory_;
+ base::MessageLoop message_loop_;
+ content::TestBrowserThread ui_thread_;
+ TestingProfile profile_;
+ MockOAuth2TokenService oauth2_token_service_;
+ net::TestURLFetcherFactory url_fetcher_factory_;
+ scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher_;
+
+ GoogleServiceAuthError error_;
+ std::string token_;
+};
+
+ManagedUserRefreshTokenFetcherTest::ManagedUserRefreshTokenFetcherTest()
+ : weak_ptr_factory_(this),
+ ui_thread_(content::BrowserThread::UI, &message_loop_),
+ token_fetcher_(
+ ManagedUserRefreshTokenFetcher::Create(&oauth2_token_service_,
+ profile_.GetRequestContext())),
+ error_(GoogleServiceAuthError::NONE) {}
+
+void ManagedUserRefreshTokenFetcherTest::StartFetching() {
+ token_fetcher_->Start(kManagedUserId, UTF8ToUTF16(kName), kDeviceName,
+ base::Bind(
+ &ManagedUserRefreshTokenFetcherTest::OnTokenFetched,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+MockOAuth2TokenService::Request*
+ManagedUserRefreshTokenFetcherTest::GetOAuth2TokenServiceRequest() {
+ MockOAuth2TokenService::Request* request = oauth2_token_service_.request();
+
+ OAuth2TokenService::ScopeSet scopes = request->scopes();
+ EXPECT_EQ(1u, scopes.size());
+ EXPECT_EQ(1u, scopes.count(GaiaUrls::GetInstance()->oauth1_login_scope()));
+ return request;
+}
+
+net::TestURLFetcher*
+ManagedUserRefreshTokenFetcherTest::GetIssueTokenRequest() {
+ net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(1);
+ if (!url_fetcher)
+ return NULL;
+
+ EXPECT_EQ(GaiaUrls::GetInstance()->oauth2_issue_token_url(),
+ url_fetcher->GetOriginalURL().spec());
+ std::string access_token;
+ net::HttpRequestHeaders headers;
+ url_fetcher->GetExtraRequestHeaders(&headers);
+ EXPECT_TRUE(headers.GetHeader("Authorization", &access_token));
+ EXPECT_EQ(std::string("Bearer ") + kAccessToken, access_token);
+ const std::string upload_data = url_fetcher->upload_data();
+ std::string managed_user_id;
+ EXPECT_TRUE(GetValueForKey(upload_data, "profile_id", &managed_user_id));
+ EXPECT_EQ(kManagedUserId, managed_user_id);
+ std::string name;
+ EXPECT_TRUE(GetValueForKey(upload_data, "profile_name", &name));
+ EXPECT_EQ(kName, name);
+ std::string device_name;
+ EXPECT_TRUE(GetValueForKey(upload_data, "device_name", &device_name));
+ EXPECT_EQ(kDeviceName, device_name);
+ return url_fetcher;
+}
+
+net::TestURLFetcher*
+ManagedUserRefreshTokenFetcherTest::GetRefreshTokenRequest() {
+ net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(0);
+ if (!url_fetcher)
+ return NULL;
+
+ EXPECT_EQ(GaiaUrls::GetInstance()->oauth2_token_url(),
+ url_fetcher->GetOriginalURL().spec());
+ std::string auth_code;
+ EXPECT_TRUE(GetValueForKey(url_fetcher->upload_data(), "code", &auth_code));
+ EXPECT_EQ(kAuthorizationCode, auth_code);
+ return url_fetcher;
+}
+
+void ManagedUserRefreshTokenFetcherTest::MakeIssueTokenRequestSucceed() {
+ SendResponse(GetIssueTokenRequest(),
+ base::StringPrintf(kIssueTokenResponseFormat,
+ kAuthorizationCode));
+}
+
+void ManagedUserRefreshTokenFetcherTest::MakeRefreshTokenFetchSucceed() {
+ SendResponse(GetRefreshTokenRequest(),
+ base::StringPrintf(kGetRefreshTokenResponseFormat,
+ kManagedUserToken));
+}
+
+void ManagedUserRefreshTokenFetcherTest::Reset() {
+ token_fetcher_.reset();
+}
+
+void ManagedUserRefreshTokenFetcherTest::OnTokenFetched(
+ const GoogleServiceAuthError& error,
+ const std::string& token) {
+ error_ = error;
+ token_ = token;
+}
+
+// Tests --------------------------------------------------------
+
+TEST_F(ManagedUserRefreshTokenFetcherTest, Success) {
+ StartFetching();
+ GetOAuth2TokenServiceRequest()->Succeed();
+ MakeIssueTokenRequestSucceed();
+ MakeRefreshTokenFetchSucceed();
+
+ EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
+ EXPECT_EQ(kManagedUserToken, token());
+}
+
+TEST_F(ManagedUserRefreshTokenFetcherTest, ExpiredAccessToken) {
+ StartFetching();
+ GetOAuth2TokenServiceRequest()->Succeed();
+ SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED);
+ GetOAuth2TokenServiceRequest()->Succeed();
+ MakeIssueTokenRequestSucceed();
+ MakeRefreshTokenFetchSucceed();
+
+ EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
+ EXPECT_EQ(kManagedUserToken, token());
+}
+
+TEST_F(ManagedUserRefreshTokenFetcherTest, ExpiredAccessTokenRetry) {
+ // If we get a 401 error for the second time, we should give up instead of
+ // retrying again.
+ StartFetching();
+ GetOAuth2TokenServiceRequest()->Succeed();
+ SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED);
+ GetOAuth2TokenServiceRequest()->Succeed();
+ SetHttpError(GetIssueTokenRequest(), net::HTTP_UNAUTHORIZED);
+
+ EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
+ EXPECT_EQ(net::ERR_FAILED, error().network_error());
+ EXPECT_EQ(std::string(), token());
+}
+
+TEST_F(ManagedUserRefreshTokenFetcherTest, MalformedIssueTokenResponse) {
+ StartFetching();
+ GetOAuth2TokenServiceRequest()->Succeed();
+ SendResponse(GetIssueTokenRequest(), "choke");
+
+ EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
+ EXPECT_EQ(net::ERR_INVALID_RESPONSE, error().network_error());
+ EXPECT_EQ(std::string(), token());
+}
+
+TEST_F(ManagedUserRefreshTokenFetcherTest, FetchAccessTokenFailure) {
+ StartFetching();
+ GetOAuth2TokenServiceRequest()->Fail(
+ GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
+
+ EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, error().state());
+ EXPECT_EQ(std::string(), token());
+}
+
+TEST_F(ManagedUserRefreshTokenFetcherTest, IssueTokenNetworkError) {
+ StartFetching();
+ GetOAuth2TokenServiceRequest()->Succeed();
+ SetNetworkError(GetIssueTokenRequest(), net::ERR_SSL_PROTOCOL_ERROR);
+
+ EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
+ EXPECT_EQ(net::ERR_SSL_PROTOCOL_ERROR, error().network_error());
+ EXPECT_EQ(std::string(), token());
+}
+
+TEST_F(ManagedUserRefreshTokenFetcherTest, FetchRefreshTokenNetworkError) {
+ StartFetching();
+ GetOAuth2TokenServiceRequest()->Succeed();
+ MakeIssueTokenRequestSucceed();
+ SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
+ EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
+ SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
+
+ EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
+ EXPECT_EQ(net::ERR_FAILED, error().network_error());
+ EXPECT_EQ(std::string(), token());
+}
+
+TEST_F(ManagedUserRefreshTokenFetcherTest,
+ FetchRefreshTokenTransientNetworkError) {
+ StartFetching();
+ GetOAuth2TokenServiceRequest()->Succeed();
+ MakeIssueTokenRequestSucceed();
+ SetNetworkError(GetRefreshTokenRequest(), net::ERR_CONNECTION_REFUSED);
+
+ EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
+ MakeRefreshTokenFetchSucceed();
+
+ EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
+ EXPECT_EQ(kManagedUserToken, token());
+}
+
+TEST_F(ManagedUserRefreshTokenFetcherTest, FetchRefreshTokenBadRequest) {
+ StartFetching();
+ GetOAuth2TokenServiceRequest()->Succeed();
+ MakeIssueTokenRequestSucceed();
+ SetHttpError(GetRefreshTokenRequest(), net::HTTP_BAD_REQUEST);
+
+ EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error().state());
+ EXPECT_EQ(net::ERR_FAILED, error().network_error());
+ EXPECT_EQ(std::string(), token());
+}
+
+TEST_F(ManagedUserRefreshTokenFetcherTest, CancelWhileFetchingAccessToken) {
+ StartFetching();
+ Reset();
+
+ EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
+ EXPECT_EQ(std::string(), token());
+}
+
+TEST_F(ManagedUserRefreshTokenFetcherTest, CancelWhileCallingIssueToken) {
+ StartFetching();
+ GetOAuth2TokenServiceRequest()->Succeed();
+ Reset();
+
+ EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
+ EXPECT_EQ(std::string(), token());
+}
+
+TEST_F(ManagedUserRefreshTokenFetcherTest, CancelWhileFetchingRefreshToken) {
+ StartFetching();
+ GetOAuth2TokenServiceRequest()->Succeed();
+ MakeIssueTokenRequestSucceed();
+ Reset();
+
+ EXPECT_EQ(GoogleServiceAuthError::NONE, error().state());
+ EXPECT_EQ(std::string(), token());
+}

Powered by Google App Engine
This is Rietveld 408576698