Componentize and rename ProfileOAuth2TokenServiceRequest.

The purpose of this change is to move ProfileOAuth2TokenServiceRequest
into google_apis/gaia and drop any browser dependencies.

ProfileOAuth2TokenServiceRequest becomes OAuth2TokenServiceRequest.

Add support for invalidating tokens.

Review URL: https://codereview.chromium.org/299943003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@274255 0039d316-1c4b-4281-b951-d872f2087c98
parent a4205207
......@@ -22,7 +22,7 @@
// See |ProfileOAuth2TokenService| for usage details.
//
// Note: requests should be started from the UI thread. To start a
// request from other thread, please use ProfileOAuth2TokenServiceRequest.
// request from other thread, please use OAuth2TokenServiceRequest.
class AndroidProfileOAuth2TokenService : public ProfileOAuth2TokenService {
public:
// Registers the AndroidProfileOAuth2TokenService's native methods through
......
// Copyright 2012 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 "chrome/browser/signin/profile_oauth2_token_service_request.h"
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_manager.h"
#include "content/public/browser/browser_thread.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "google_apis/gaia/oauth2_access_token_consumer.h"
class ProfileOAuth2TokenServiceRequest::Core
: public base::RefCountedThreadSafe<ProfileOAuth2TokenServiceRequest::Core>,
public OAuth2TokenService::Consumer {
public:
// Note the thread where an instance of Core is constructed is referred to as
// the "owner thread" here. This will be the thread of |owner_task_runner_|.
Core(Profile* profile,
ProfileOAuth2TokenServiceRequest* owner);
// Starts fetching an OAuth2 access token for |account_id| and |scopes|. It
// should be called on the owner thread.
void Start(
const std::string& account_id,
const OAuth2TokenService::ScopeSet& scopes);
// Stops the OAuth2 access token fetching. It should be called on the owner
// thread.
void Stop();
OAuth2TokenService::Request* request();
// OAuth2TokenService::Consumer. It should be called on the UI thread.
virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) OVERRIDE;
virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) OVERRIDE;
private:
friend class
base::RefCountedThreadSafe<ProfileOAuth2TokenServiceRequest::Core>;
// Note this can be destructed on the owner thread or on the UI thread,
// depending on the reference count.
virtual ~Core();
// Starts an OAuth2TokenService::Request on the UI thread.
void StartOnUIThread(
const std::string& account_id,
const OAuth2TokenService::ScopeSet& scopes);
// Stops the OAuth2TokenService::Request on the UI thread.
void StopOnUIThread();
// Method posted to the owner thread to call back |owner_|. Note when this
// posted task is actually running on the owner thread, it is possible that
// |owner_| has been reset NULL.
void InformOwnerOnGetTokenSuccess(std::string access_token,
base::Time expiration_time);
void InformOwnerOnGetTokenFailure(GoogleServiceAuthError error);
// The profile with which this instance was initialized.
Profile* const profile_;
// The object to call back when fetching completes. |owner_| should be
// called back only on the owner thread.
ProfileOAuth2TokenServiceRequest* owner_;
// Task runner on which |owner_| should be called back.
scoped_refptr<base::SingleThreadTaskRunner> owner_task_runner_;
// OAuth2TokenService request for fetching OAuth2 access token; it should be
// created, reset and accessed only on the UI thread.
scoped_ptr<OAuth2TokenService::Request> request_;
DISALLOW_COPY_AND_ASSIGN(Core);
};
ProfileOAuth2TokenServiceRequest::Core::Core(
Profile* profile,
ProfileOAuth2TokenServiceRequest* owner)
: OAuth2TokenService::Consumer("oauth2_token_service"),
profile_(profile),
owner_(owner),
owner_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
DCHECK(profile);
DCHECK(owner);
}
ProfileOAuth2TokenServiceRequest::Core::~Core() {
}
void ProfileOAuth2TokenServiceRequest::Core::Start(
const std::string& account_id,
const OAuth2TokenService::ScopeSet& scopes) {
DCHECK(owner_task_runner_->BelongsToCurrentThread());
if (content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
StartOnUIThread(account_id, scopes);
} else {
content::BrowserThread::PostTask(
content::BrowserThread::UI,
FROM_HERE,
base::Bind(&ProfileOAuth2TokenServiceRequest::Core::StartOnUIThread,
this, account_id, scopes));
}
}
void ProfileOAuth2TokenServiceRequest::Core::Stop() {
DCHECK(owner_task_runner_->BelongsToCurrentThread());
// Detaches |owner_| from this instance so |owner_| will be called back only
// if |Stop()| has never been called.
owner_ = NULL;
if (content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
StopOnUIThread();
} else {
content::BrowserThread::PostTask(
content::BrowserThread::UI,
FROM_HERE,
base::Bind(&ProfileOAuth2TokenServiceRequest::Core::StopOnUIThread,
this));
}
}
OAuth2TokenService::Request* ProfileOAuth2TokenServiceRequest::Core::request() {
return request_.get();
}
void ProfileOAuth2TokenServiceRequest::Core::StopOnUIThread() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
request_.reset();
}
void ProfileOAuth2TokenServiceRequest::Core::StartOnUIThread(
const std::string& account_id,
const OAuth2TokenService::ScopeSet& scopes) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
ProfileOAuth2TokenService* service =
ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
DCHECK(service);
SigninManagerBase* signin_manager =
SigninManagerFactory::GetForProfile(profile_);
DCHECK(signin_manager);
std::string account_id_to_use =
account_id.empty() ? signin_manager->GetAuthenticatedAccountId()
: account_id;
request_.reset(
service->StartRequest(account_id_to_use, scopes, this).release());
}
void ProfileOAuth2TokenServiceRequest::Core::OnGetTokenSuccess(
const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
DCHECK_EQ(request_.get(), request);
owner_task_runner_->PostTask(FROM_HERE, base::Bind(
&ProfileOAuth2TokenServiceRequest::Core::InformOwnerOnGetTokenSuccess,
this,
access_token,
expiration_time));
request_.reset();
}
void ProfileOAuth2TokenServiceRequest::Core::OnGetTokenFailure(
const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
DCHECK_EQ(request_.get(), request);
owner_task_runner_->PostTask(FROM_HERE, base::Bind(
&ProfileOAuth2TokenServiceRequest::Core::InformOwnerOnGetTokenFailure,
this,
error));
request_.reset();
}
void ProfileOAuth2TokenServiceRequest::Core::InformOwnerOnGetTokenSuccess(
std::string access_token,
base::Time expiration_time) {
DCHECK(owner_task_runner_->BelongsToCurrentThread());
if (owner_)
owner_->consumer_->OnGetTokenSuccess(owner_, access_token, expiration_time);
}
void ProfileOAuth2TokenServiceRequest::Core::InformOwnerOnGetTokenFailure(
GoogleServiceAuthError error) {
DCHECK(owner_task_runner_->BelongsToCurrentThread());
if (owner_)
owner_->consumer_->OnGetTokenFailure(owner_, error);
}
// static
ProfileOAuth2TokenServiceRequest*
ProfileOAuth2TokenServiceRequest::CreateAndStart(
Profile* profile,
const std::string& account_id,
const OAuth2TokenService::ScopeSet& scopes,
OAuth2TokenService::Consumer* consumer) {
return new ProfileOAuth2TokenServiceRequest(profile, account_id, scopes,
consumer);
}
ProfileOAuth2TokenServiceRequest::ProfileOAuth2TokenServiceRequest(
Profile* profile,
const std::string& account_id,
const OAuth2TokenService::ScopeSet& scopes,
OAuth2TokenService::Consumer* consumer)
: consumer_(consumer),
core_(new Core(profile, this)) {
core_->Start(account_id, scopes);
}
ProfileOAuth2TokenServiceRequest::~ProfileOAuth2TokenServiceRequest() {
DCHECK(CalledOnValidThread());
core_->Stop();
}
std::string ProfileOAuth2TokenServiceRequest::GetAccountId() const {
return core_->request()->GetAccountId();
}
// Copyright 2012 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.
#ifndef CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_REQUEST_H_
#define CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_REQUEST_H_
#include <set>
#include <string>
#include "base/threading/non_thread_safe.h"
#include "google_apis/gaia/oauth2_token_service.h"
class Profile;
// ProfileOAuth2TokenServiceRequest represents a request to fetch an
// OAuth2 access token for a given set of |scopes| by calling |profile|'s
// ProfileOAuth2TokenService. A request can be created and started from
// any thread with an object |consumer| that will be called back on the
// same thread when fetching completes. If the request is destructed
// before |consumer| is called, |consumer| will never be called back. (Note
// the actual network activities are not canceled and the cache in
// ProfileOAuth2TokenService will be populated with the fetched results.)
class ProfileOAuth2TokenServiceRequest : public OAuth2TokenService::Request,
public base::NonThreadSafe {
public:
// Creates and starts a request for |account_id| and |scopes|.
// Uses the primary account id if |account_id| is the empty string.
static ProfileOAuth2TokenServiceRequest* CreateAndStart(
Profile* profile,
const std::string& account_id,
const OAuth2TokenService::ScopeSet& scopes,
OAuth2TokenService::Consumer* consumer);
virtual ~ProfileOAuth2TokenServiceRequest();
// Overridden from Request:
virtual std::string GetAccountId() const OVERRIDE;
private:
class Core;
friend class Core;
ProfileOAuth2TokenServiceRequest(Profile* profile,
const std::string& account_id,
const OAuth2TokenService::ScopeSet& scopes,
OAuth2TokenService::Consumer* consumer);
OAuth2TokenService::Consumer* const consumer_;
scoped_refptr<Core> core_;
DISALLOW_COPY_AND_ASSIGN(ProfileOAuth2TokenServiceRequest);
};
#endif // CHROME_BROWSER_SIGNIN_PROFILE_OAUTH2_TOKEN_SERVICE_REQUEST_H_
// Copyright 2012 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 "chrome/browser/signin/profile_oauth2_token_service_request.h"
#include <set>
#include <string>
#include <vector>
#include "base/threading/thread.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/test_browser_thread.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "google_apis/gaia/oauth2_token_service.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
const char kAccessToken[] = "access_token";
const char kAccountId[] = "test_user@gmail.com";
const char kRefreshToken[] = "refresh_token";
class TestingOAuth2TokenServiceConsumer : public OAuth2TokenService::Consumer {
public:
TestingOAuth2TokenServiceConsumer();
virtual ~TestingOAuth2TokenServiceConsumer();
virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) OVERRIDE;
virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) OVERRIDE;
std::string last_token_;
int number_of_successful_tokens_;
GoogleServiceAuthError last_error_;
int number_of_errors_;
};
TestingOAuth2TokenServiceConsumer::TestingOAuth2TokenServiceConsumer()
: OAuth2TokenService::Consumer("test"),
number_of_successful_tokens_(0),
last_error_(GoogleServiceAuthError::AuthErrorNone()),
number_of_errors_(0) {
}
TestingOAuth2TokenServiceConsumer::~TestingOAuth2TokenServiceConsumer() {
}
void TestingOAuth2TokenServiceConsumer::OnGetTokenSuccess(
const OAuth2TokenService::Request* request,
const std::string& token,
const base::Time& expiration_date) {
last_token_ = token;
++number_of_successful_tokens_;
}
void TestingOAuth2TokenServiceConsumer::OnGetTokenFailure(
const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) {
last_error_ = error;
++number_of_errors_;
}
class ProfileOAuth2TokenServiceRequestTest : public testing::Test {
public:
virtual void SetUp() OVERRIDE;
protected:
base::MessageLoop ui_loop_;
scoped_ptr<content::TestBrowserThread> ui_thread_;
scoped_ptr<Profile> profile_;
TestingOAuth2TokenServiceConsumer consumer_;
FakeProfileOAuth2TokenService* oauth2_service_;
scoped_ptr<ProfileOAuth2TokenServiceRequest> request_;
};
void ProfileOAuth2TokenServiceRequestTest::SetUp() {
ui_thread_.reset(new content::TestBrowserThread(content::BrowserThread::UI,
&ui_loop_));
TestingProfile::Builder builder;
builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
&BuildFakeProfileOAuth2TokenService);
profile_ = builder.Build();
oauth2_service_ = (FakeProfileOAuth2TokenService*)
ProfileOAuth2TokenServiceFactory::GetForProfile(profile_.get());
}
TEST_F(ProfileOAuth2TokenServiceRequestTest,
Failure) {
scoped_ptr<ProfileOAuth2TokenServiceRequest> request(
ProfileOAuth2TokenServiceRequest::CreateAndStart(
profile_.get(),
std::string(),
OAuth2TokenService::ScopeSet(),
&consumer_));
oauth2_service_->IssueErrorForAllPendingRequests(
GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE));
ui_loop_.RunUntilIdle();
EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
EXPECT_EQ(1, consumer_.number_of_errors_);
}
TEST_F(ProfileOAuth2TokenServiceRequestTest, Success) {
oauth2_service_->UpdateCredentials(kAccountId, kRefreshToken);
scoped_ptr<ProfileOAuth2TokenServiceRequest> request(
ProfileOAuth2TokenServiceRequest::CreateAndStart(
profile_.get(),
kAccountId,
OAuth2TokenService::ScopeSet(),
&consumer_));
oauth2_service_->IssueTokenForAllPendingRequests(kAccessToken,
base::Time::Max());
ui_loop_.RunUntilIdle();
EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
EXPECT_EQ(kAccessToken, consumer_.last_token_);
EXPECT_EQ(0, consumer_.number_of_errors_);
}
TEST_F(ProfileOAuth2TokenServiceRequestTest,
RequestDeletionBeforeServiceComplete) {
oauth2_service_->UpdateCredentials(kAccountId, kRefreshToken);
scoped_ptr<ProfileOAuth2TokenServiceRequest> request(
ProfileOAuth2TokenServiceRequest::CreateAndStart(
profile_.get(),
kAccountId,
OAuth2TokenService::ScopeSet(),
&consumer_));
request.reset();
oauth2_service_->IssueTokenForAllPendingRequests(kAccessToken,
base::Time::Max());
ui_loop_.RunUntilIdle();
EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
EXPECT_EQ(0, consumer_.number_of_errors_);
}
TEST_F(ProfileOAuth2TokenServiceRequestTest,
RequestDeletionAfterServiceComplete) {
oauth2_service_->UpdateCredentials(kAccountId, kRefreshToken);
scoped_ptr<ProfileOAuth2TokenServiceRequest> request(
ProfileOAuth2TokenServiceRequest::CreateAndStart(
profile_.get(),
kAccountId,
OAuth2TokenService::ScopeSet(),
&consumer_));
oauth2_service_->IssueTokenForAllPendingRequests(kAccessToken,
base::Time::Max());
ui_loop_.RunUntilIdle();
request.reset();
EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
EXPECT_EQ(0, consumer_.number_of_errors_);
}
} // namespace
......@@ -2087,8 +2087,6 @@
'browser/signin/profile_identity_provider.h',
'browser/signin/profile_oauth2_token_service_factory.cc',
'browser/signin/profile_oauth2_token_service_factory.h',
'browser/signin/profile_oauth2_token_service_request.cc',
'browser/signin/profile_oauth2_token_service_request.h',
'browser/signin/screenlock_bridge.cc',
'browser/signin/screenlock_bridge.h',
'browser/signin/signin_error_notifier_ash.cc',
......
......@@ -1295,7 +1295,6 @@
'browser/shell_integration_win_unittest.cc',
'browser/signin/account_reconcilor_unittest.cc',
'browser/signin/local_auth_unittest.cc',
'browser/signin/profile_oauth2_token_service_request_unittest.cc',
'browser/signin/signin_error_notifier_ash_unittest.cc',
'browser/signin/signin_global_error_unittest.cc',
'browser/signin/signin_manager_unittest.cc',
......
......@@ -33,7 +33,7 @@ class SigninClient;
// won't be cached.
//
// Note: requests should be started from the UI thread. To start a
// request from other thread, please use ProfileOAuth2TokenServiceRequest.
// request from other thread, please use OAuth2TokenServiceRequest.
class ProfileOAuth2TokenService : public OAuth2TokenService,
public KeyedService {
public:
......
......@@ -23,7 +23,7 @@ class ProfileOAuth2TokenServiceIOSProvider;
// See |ProfileOAuth2TokenService| for usage details.
//
// Note: Requests should be started from the UI thread. To start a
// request from aother thread, please use ProfileOAuth2TokenServiceRequest.
// request from aother thread, please use OAuth2TokenServiceRequest.
class ProfileOAuth2TokenServiceIOS : public MutableProfileOAuth2TokenService {
public:
ProfileOAuth2TokenServiceIOS();
......
This diff is collapsed.
// Copyright 2014 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.
#ifndef GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_REQUEST_H_
#define GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_REQUEST_H_
#include <set>
#include <string>
#include "base/memory/scoped_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/non_thread_safe.h"
#include "google_apis/gaia/oauth2_token_service.h"
// OAuth2TokenServiceRequest represents an asynchronous request to an
// OAuth2TokenService that may live in another thread.
//
// An OAuth2TokenServiceRequest can be created and started from any thread.
class OAuth2TokenServiceRequest : public OAuth2TokenService::Request,
public base::NonThreadSafe {
public:
class Core;
// Interface for providing an OAuth2TokenService.
class TokenServiceProvider {
public:
TokenServiceProvider();
virtual ~TokenServiceProvider();
// Returns the task runner on which the token service lives.
//
// This method may be called from any thread.
virtual scoped_refptr<base::SingleThreadTaskRunner>
GetTokenServiceTaskRunner() = 0;
// Returns a pointer to a token service.
//
// Caller does not own the token service and must not delete it. The token
// service must outlive all instances of OAuth2TokenServiceRequest.
//
// This method may only be called from the task runner returned by
// |GetTokenServiceTaskRunner|.
virtual OAuth2TokenService* GetTokenService() = 0;
};
// Creates and starts an access token request for |account_id| and |scopes|.
//
// |provider| is used to get the OAuth2TokenService and must outlive the
// returned request object.
//
// |account_id| must not be empty.
//
// |scopes| must not be empty.
//
// |consumer| will be invoked in the same thread that invoked CreateAndStart
// and must outlive the returned request object. Destroying the request
// object ensure that |consumer| will not be called. However, the actual
// network activities may not be canceled and the cache in OAuth2TokenService
// may be populated with the fetched results.
static scoped_ptr<OAuth2TokenServiceRequest> CreateAndStart(
TokenServiceProvider* provider,
const std::string& account_id,
const OAuth2TokenService::ScopeSet& scopes,
OAuth2TokenService::Consumer* consumer);
// Invalidates |access_token| for |account_id| and |scopes|.
//
// |provider| is used to get the OAuth2TokenService and must outlive the
// returned request object.
//
// |account_id| must not be empty.
//
// |scopes| must not be empty.
static void InvalidateToken(TokenServiceProvider* provider,
const std::string& account_id,
const OAuth2TokenService::ScopeSet& scopes,
const std::string& access_token);
virtual ~OAuth2TokenServiceRequest();
// OAuth2TokenService::Request.
virtual std::string GetAccountId() const OVERRIDE;
private:
OAuth2TokenServiceRequest(const std::string& account_id);
void StartWithCore(const scoped_refptr<Core>& core);
const std::string account_id_;
scoped_refptr<Core> core_;
DISALLOW_COPY_AND_ASSIGN(OAuth2TokenServiceRequest);
};
#endif // GOOGLE_APIS_GAIA_OAUTH2_TOKEN_SERVICE_REQUEST_H_
// Copyright 2014 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 "google_apis/gaia/oauth2_token_service_request.h"
#include <set>
#include <string>
#include <vector>
#include "base/threading/thread.h"
#include "google_apis/gaia/fake_oauth2_token_service.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "google_apis/gaia/oauth2_token_service.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
const char kAccessToken[] = "access_token";
const char kAccountId[] = "test_user@gmail.com";
const char kScope[] = "SCOPE";
class TestingOAuth2TokenServiceConsumer : public OAuth2TokenService::Consumer {
public:
TestingOAuth2TokenServiceConsumer();
virtual ~TestingOAuth2TokenServiceConsumer();
virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) OVERRIDE;
virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) OVERRIDE;
int num_get_token_success_;
int num_get_token_failure_;
std::string last_token_;
GoogleServiceAuthError last_error_;
};
TestingOAuth2TokenServiceConsumer::TestingOAuth2TokenServiceConsumer()
: OAuth2TokenService::Consumer("test"),
num_get_token_success_(0),
num_get_token_failure_(0),
last_error_(GoogleServiceAuthError::AuthErrorNone()) {
}
TestingOAuth2TokenServiceConsumer::~TestingOAuth2TokenServiceConsumer() {
}
void TestingOAuth2TokenServiceConsumer::OnGetTokenSuccess(
const OAuth2TokenService::Request* request,
const std::string& token,
const base::Time& expiration_date) {
last_token_ = token;
++num_get_token_success_;
}
void TestingOAuth2TokenServiceConsumer::OnGetTokenFailure(
const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) {
last_error_ = error;
++num_get_token_failure_;
}
// A mock implementation of an OAuth2TokenService.
//
// Use SetResponse to vary the response to token requests.
class MockOAuth2TokenService : public FakeOAuth2TokenService {
public:
MockOAuth2TokenService();
virtual ~MockOAuth2TokenService();
void SetResponse(const GoogleServiceAuthError& error,
const std::string& access_token,
const base::Time& expiration);
int num_invalidate_token() const { return num_invalidate_token_; }
const std::string& last_token_invalidated() const {
return last_token_invalidated_;
}
protected:
virtual void FetchOAuth2Token(RequestImpl* request,
const std::string& account_id,
net::URLRequestContextGetter* getter,
const std::string& client_id,
const std::string& client_secret,
const ScopeSet& scopes) OVERRIDE;
virtual void InvalidateOAuth2Token(const std::string& account_id,
const std::string& client_id,
const ScopeSet& scopes,
const std::string& access_token) OVERRIDE;
private:
GoogleServiceAuthError response_error_;
std::string response_access_token_;
base::Time response_expiration_;
int num_invalidate_token_;
std::string last_token_invalidated_;
};
MockOAuth2TokenService::MockOAuth2TokenService()
: response_error_(GoogleServiceAuthError::AuthErrorNone()),
response_access_token_(kAccessToken),
response_expiration_(base::Time::Max()),
num_invalidate_token_(0) {
}
MockOAuth2TokenService::~MockOAuth2TokenService() {
}
void MockOAuth2TokenService::SetResponse(const GoogleServiceAuthError& error,
const std::string& access_token,
const base::Time& expiration) {
response_error_ = error;
response_access_token_ = access_token;
response_expiration_ = expiration;
}
void MockOAuth2TokenService::FetchOAuth2Token(
RequestImpl* request,
const std::string& account_id,
net::URLRequestContextGetter* getter,
const std::string& client_id,
const std::string& client_secret,
const ScopeSet& scopes) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&OAuth2TokenService::RequestImpl::InformConsumer,
request->AsWeakPtr(),
response_error_,
response_access_token_,
response_expiration_));
}
void MockOAuth2TokenService::InvalidateOAuth2Token(
const std::string& account_id,
const std::string& client_id,
const ScopeSet& scopes,
const std::string& access_token) {
++num_invalidate_token_;
last_token_invalidated_ = access_token;
}
class OAuth2TokenServiceRequestTest : public testing::Test {
public:
virtual void SetUp() OVERRIDE;
protected:
class Provider : public OAuth2TokenServiceRequest::TokenServiceProvider {
public:
Provider(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
OAuth2TokenService* token_service);
virtual scoped_refptr<base::SingleThreadTaskRunner>
GetTokenServiceTaskRunner() OVERRIDE;
virtual OAuth2TokenService* GetTokenService() OVERRIDE;
private:
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
OAuth2TokenService* token_service_;
};
base::MessageLoop ui_loop_;
OAuth2TokenService::ScopeSet scopes_;
scoped_ptr<MockOAuth2TokenService> oauth2_service_;
scoped_ptr<OAuth2TokenServiceRequest::TokenServiceProvider> provider_;
TestingOAuth2TokenServiceConsumer consumer_;
};
void OAuth2TokenServiceRequestTest::SetUp() {
scopes_.insert(kScope);
oauth2_service_.reset(new MockOAuth2TokenService);
oauth2_service_->AddAccount(kAccountId);
provider_.reset(
new Provider(base::MessageLoopProxy::current(), oauth2_service_.get()));
}
OAuth2TokenServiceRequestTest::Provider::Provider(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
OAuth2TokenService* token_service)
: task_runner_(task_runner), token_service_(token_service) {
}
scoped_refptr<base::SingleThreadTaskRunner>
OAuth2TokenServiceRequestTest::Provider::GetTokenServiceTaskRunner() {
return task_runner_;
}
OAuth2TokenService* OAuth2TokenServiceRequestTest::Provider::GetTokenService() {
return token_service_;
}
TEST_F(OAuth2TokenServiceRequestTest, CreateAndStart_Failure) {
oauth2_service_->SetResponse(
GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE),
std::string(),
base::Time());
scoped_ptr<OAuth2TokenServiceRequest> request(
OAuth2TokenServiceRequest::CreateAndStart(
provider_.get(), kAccountId, scopes_, &consumer_));
ui_loop_.RunUntilIdle();
EXPECT_EQ(0, consumer_.num_get_token_success_);
EXPECT_EQ(1, consumer_.num_get_token_failure_);
EXPECT_EQ(GoogleServiceAuthError::SERVICE_UNAVAILABLE,
consumer_.last_error_.state());
EXPECT_EQ(0, oauth2_service_->num_invalidate_token());
}
TEST_F(OAuth2TokenServiceRequestTest, CreateAndStart_Success) {
scoped_ptr<OAuth2TokenServiceRequest> request(
OAuth2TokenServiceRequest::CreateAndStart(
provider_.get(), kAccountId, scopes_, &consumer_));
ui_loop_.RunUntilIdle();
EXPECT_EQ(1, consumer_.num_get_token_success_);
EXPECT_EQ(0, consumer_.num_get_token_failure_);
EXPECT_EQ(kAccessToken, consumer_.last_token_);
EXPECT_EQ(0, oauth2_service_->num_invalidate_token());
}
TEST_F(OAuth2TokenServiceRequestTest,
CreateAndStart_DestroyRequestBeforeCompletes) {
scoped_ptr<OAuth2TokenServiceRequest> request(
OAuth2TokenServiceRequest::CreateAndStart(
provider_.get(), kAccountId, scopes_, &consumer_));
request.reset();
ui_loop_.RunUntilIdle();
EXPECT_EQ(0, consumer_.num_get_token_success_);
EXPECT_EQ(0, consumer_.num_get_token_failure_);
EXPECT_EQ(0, oauth2_service_->num_invalidate_token());
}
TEST_F(OAuth2TokenServiceRequestTest,
CreateAndStart_DestroyRequestAfterCompletes) {
scoped_ptr<OAuth2TokenServiceRequest> request(
OAuth2TokenServiceRequest::CreateAndStart(
provider_.get(), kAccountId, scopes_, &consumer_));
ui_loop_.RunUntilIdle();
request.reset();
EXPECT_EQ(1, consumer_.num_get_token_success_);
EXPECT_EQ(0, consumer_.num_get_token_failure_);
EXPECT_EQ(kAccessToken, consumer_.last_token_);
EXPECT_EQ(0, oauth2_service_->num_invalidate_token());
}
TEST_F(OAuth2TokenServiceRequestTest, InvalidateToken) {
OAuth2TokenServiceRequest::InvalidateToken(
provider_.get(), kAccountId, scopes_, kAccessToken);
ui_loop_.RunUntilIdle();
EXPECT_EQ(0, consumer_.num_get_token_success_);
EXPECT_EQ(0, consumer_.num_get_token_failure_);
EXPECT_EQ(kAccessToken, oauth2_service_->last_token_invalidated());
EXPECT_EQ(1, oauth2_service_->num_invalidate_token());
}
} // namespace
......@@ -128,6 +128,8 @@
'gaia/oauth2_mint_token_flow.h',
'gaia/oauth2_token_service.cc',
'gaia/oauth2_token_service.h',
'gaia/oauth2_token_service_request.cc',
'gaia/oauth2_token_service_request.h',
'gaia/ubertoken_fetcher.cc',
'gaia/ubertoken_fetcher.h',
'google_api_keys.cc',
......@@ -175,6 +177,7 @@
'gaia/oauth2_access_token_fetcher_impl_unittest.cc',
'gaia/oauth2_api_call_flow_unittest.cc',
'gaia/oauth2_mint_token_flow_unittest.cc',
'gaia/oauth2_token_service_request_unittest.cc',
'gaia/oauth2_token_service_unittest.cc',
'gaia/ubertoken_fetcher_unittest.cc',
],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment