Commit 73df0e52 authored by Colin Blundell's avatar Colin Blundell Committed by Commit Bot

Remove OAuth2TokenServiceRequest

This class exists to enable making access token requests from threads
other than the UI thread. However, it is not used in the codebase, and
it has some amount of maintenance cost and confusion associated with it.
It can always be brought back if needed.

Bug: 967598
Change-Id: I2208d377f852e88f1cd8169202a07ce00d32d53f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1675648Reviewed-by: default avatarMihai Sardarescu <msarda@chromium.org>
Commit-Queue: Colin Blundell <blundell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#672057}
parent 6bd6806a
......@@ -26,8 +26,7 @@
//
// See |OAuth2TokenServiceDelegate| for usage details.
//
// Note: requests should be started from the UI thread. To start a
// request from other thread, please use OAuth2TokenServiceRequest.
// Note: requests should be started from the UI thread.
class OAuth2TokenServiceDelegateAndroid : public OAuth2TokenServiceDelegate {
public:
OAuth2TokenServiceDelegateAndroid(
......
......@@ -37,8 +37,7 @@ class PrefRegistrySimple;
// Consumer::OnGetTokenSuccess will be invoked, but the access token
// won't be cached.
//
// Note: requests should be started from the UI thread. To start a
// request from other thread, please use OAuth2TokenServiceRequest.
// Note: requests should be started from the UI thread.
class ProfileOAuth2TokenService : public OAuth2TokenService {
public:
typedef base::RepeatingCallback<void(const CoreAccountId& /* account_id */,
......
......@@ -124,8 +124,6 @@ template("google_apis_tmpl") {
"gaia/oauth2_token_service_delegate.cc",
"gaia/oauth2_token_service_delegate.h",
"gaia/oauth2_token_service_observer.h",
"gaia/oauth2_token_service_request.cc",
"gaia/oauth2_token_service_request.h",
"gaia/oauth_multilogin_result.cc",
"gaia/oauth_multilogin_result.h",
"gaia/oauth_request_signer.cc",
......@@ -222,7 +220,6 @@ test("google_apis_unittests") {
"gaia/oauth2_id_token_decoder_unittest.cc",
"gaia/oauth2_mint_token_flow_unittest.cc",
"gaia/oauth2_token_service_delegate_unittest.cc",
"gaia/oauth2_token_service_request_unittest.cc",
"gaia/oauth2_token_service_unittest.cc",
"gaia/oauth_multilogin_result_unittest.cc",
"gaia/oauth_request_signer_unittest.cc",
......
// 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 <memory>
#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ref_counted_delete_on_sequence.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "google_apis/gaia/oauth2_access_token_consumer.h"
OAuth2TokenServiceRequest::TokenServiceProvider::TokenServiceProvider() {
}
OAuth2TokenServiceRequest::TokenServiceProvider::~TokenServiceProvider() {
}
// Core serves as the base class for OAuth2TokenService operations. Each
// operation should be modeled as a derived type.
//
// Core is used like this:
//
// 1. Constructed on owner thread.
//
// 2. Start() is called on owner thread, which calls StartOnTokenServiceThread()
// on token service thread.
//
// 3. Request is executed.
//
// 4. Stop() is called on owner thread, which calls StopOnTokenServiceThread()
// on token service thread.
//
// 5. Core is destroyed on owner thread.
class OAuth2TokenServiceRequest::Core
: public base::RefCountedDeleteOnSequence<OAuth2TokenServiceRequest::Core> {
public:
// Note the thread where an instance of Core is constructed is referred to as
// the "owner thread" here.
Core(OAuth2TokenServiceRequest* owner,
const scoped_refptr<TokenServiceProvider>& provider);
// Starts the core. Must be called on the owner thread.
void Start();
// Stops the core. Must be called on the owner thread.
void Stop();
// Returns true if this object has been stopped. Must be called on the owner
// thread.
bool IsStopped() const;
protected:
// Core must be destroyed on the owner thread. If data members must be
// cleaned up or destroyed on the token service thread, do so in the
// StopOnTokenServiceThread method.
virtual ~Core();
// Called on the token service thread.
virtual void StartOnTokenServiceThread() = 0;
// Called on the token service thread.
virtual void StopOnTokenServiceThread() = 0;
const base::SingleThreadTaskRunner* token_service_task_runner() const {
return token_service_task_runner_.get();
}
OAuth2TokenService* token_service();
OAuth2TokenServiceRequest* owner();
SEQUENCE_CHECKER(sequence_checker_);
private:
friend class base::RefCountedDeleteOnSequence<
OAuth2TokenServiceRequest::Core>;
friend class base::DeleteHelper<OAuth2TokenServiceRequest::Core>;
scoped_refptr<base::SingleThreadTaskRunner> token_service_task_runner_;
OAuth2TokenServiceRequest* owner_;
// Clear on owner thread. OAuth2TokenServiceRequest promises to clear its
// last reference to TokenServiceProvider on the owner thread so the caller
// can ensure it is destroyed on the owner thread if desired.
scoped_refptr<TokenServiceProvider> provider_;
DISALLOW_COPY_AND_ASSIGN(Core);
};
OAuth2TokenServiceRequest::Core::Core(
OAuth2TokenServiceRequest* owner,
const scoped_refptr<TokenServiceProvider>& provider)
: RefCountedDeleteOnSequence<OAuth2TokenServiceRequest::Core>(
base::SequencedTaskRunnerHandle::Get()),
owner_(owner),
provider_(provider) {
DCHECK(owner_);
DCHECK(provider_.get());
token_service_task_runner_ = provider_->GetTokenServiceTaskRunner();
DCHECK(token_service_task_runner());
}
OAuth2TokenServiceRequest::Core::~Core() {
}
void OAuth2TokenServiceRequest::Core::Start() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
token_service_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&OAuth2TokenServiceRequest::Core::StartOnTokenServiceThread, this));
}
void OAuth2TokenServiceRequest::Core::Stop() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!IsStopped());
// Detaches |owner_| from this instance so |owner_| will be called back only
// if |Stop()| has never been called.
owner_ = nullptr;
// Stop on the token service thread. RefCountedDeleteOnSequence ensures we
// will be destroyed on the owner thread.
token_service_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&OAuth2TokenServiceRequest::Core::StopOnTokenServiceThread,
this));
}
bool OAuth2TokenServiceRequest::Core::IsStopped() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return owner_ == nullptr;
}
OAuth2TokenService* OAuth2TokenServiceRequest::Core::token_service() {
DCHECK(token_service_task_runner()->RunsTasksInCurrentSequence());
return provider_->GetTokenService();
}
OAuth2TokenServiceRequest* OAuth2TokenServiceRequest::Core::owner() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return owner_;
}
namespace {
// An implementation of Core for getting an access token.
class RequestCore : public OAuth2TokenServiceRequest::Core,
public OAuth2TokenService::Consumer {
public:
RequestCore(
OAuth2TokenServiceRequest* owner,
const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>&
provider,
OAuth2TokenService::Consumer* consumer,
const CoreAccountId& account_id,
const OAuth2TokenService::ScopeSet& scopes);
// OAuth2TokenService::Consumer. Must be called on the token service thread.
void OnGetTokenSuccess(
const OAuth2TokenService::Request* request,
const OAuth2AccessTokenConsumer::TokenResponse& token_response) override;
void OnGetTokenFailure(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) override;
private:
friend class base::RefCountedThreadSafe<RequestCore>;
// Must be destroyed on the owner thread.
~RequestCore() override;
// Core implementation.
void StartOnTokenServiceThread() override;
void StopOnTokenServiceThread() override;
void InformOwnerOnGetTokenSuccess(
const OAuth2AccessTokenConsumer::TokenResponse& token_response);
void InformOwnerOnGetTokenFailure(GoogleServiceAuthError error);
OAuth2TokenService::Consumer* const consumer_;
CoreAccountId account_id_;
OAuth2TokenService::ScopeSet scopes_;
// OAuth2TokenService request for fetching OAuth2 access token; it should be
// created, reset and accessed only on the token service thread.
std::unique_ptr<OAuth2TokenService::Request> request_;
DISALLOW_COPY_AND_ASSIGN(RequestCore);
};
RequestCore::RequestCore(
OAuth2TokenServiceRequest* owner,
const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>&
provider,
OAuth2TokenService::Consumer* consumer,
const CoreAccountId& account_id,
const OAuth2TokenService::ScopeSet& scopes)
: OAuth2TokenServiceRequest::Core(owner, provider),
OAuth2TokenService::Consumer("oauth2_token_service"),
consumer_(consumer),
account_id_(account_id),
scopes_(scopes) {
DCHECK(consumer_);
DCHECK(!account_id_.empty());
DCHECK(!scopes_.empty());
}
RequestCore::~RequestCore() {
}
void RequestCore::StartOnTokenServiceThread() {
DCHECK(token_service_task_runner()->RunsTasksInCurrentSequence());
request_ = token_service()->StartRequest(account_id_, scopes_, this);
}
void RequestCore::StopOnTokenServiceThread() {
DCHECK(token_service_task_runner()->RunsTasksInCurrentSequence());
request_.reset();
}
void RequestCore::OnGetTokenSuccess(
const OAuth2TokenService::Request* request,
const OAuth2AccessTokenConsumer::TokenResponse& token_response) {
DCHECK(token_service_task_runner()->RunsTasksInCurrentSequence());
DCHECK_EQ(request_.get(), request);
owning_task_runner()->PostTask(
FROM_HERE, base::BindOnce(&RequestCore::InformOwnerOnGetTokenSuccess,
this, token_response));
request_.reset();
}
void RequestCore::OnGetTokenFailure(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) {
DCHECK(token_service_task_runner()->RunsTasksInCurrentSequence());
DCHECK_EQ(request_.get(), request);
owning_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&RequestCore::InformOwnerOnGetTokenFailure, this, error));
request_.reset();
}
void RequestCore::InformOwnerOnGetTokenSuccess(
const OAuth2AccessTokenConsumer::TokenResponse& token_response) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!IsStopped()) {
consumer_->OnGetTokenSuccess(owner(), token_response);
}
}
void RequestCore::InformOwnerOnGetTokenFailure(GoogleServiceAuthError error) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!IsStopped()) {
consumer_->OnGetTokenFailure(owner(), error);
}
}
// An implementation of Core for invalidating an access token.
class InvalidateCore : public OAuth2TokenServiceRequest::Core {
public:
InvalidateCore(
OAuth2TokenServiceRequest* owner,
const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>&
provider,
const std::string& access_token,
const CoreAccountId& account_id,
const OAuth2TokenService::ScopeSet& scopes);
private:
friend class base::RefCountedThreadSafe<InvalidateCore>;
// Must be destroyed on the owner thread.
~InvalidateCore() override;
// Core implementation.
void StartOnTokenServiceThread() override;
void StopOnTokenServiceThread() override;
std::string access_token_;
CoreAccountId account_id_;
OAuth2TokenService::ScopeSet scopes_;
DISALLOW_COPY_AND_ASSIGN(InvalidateCore);
};
InvalidateCore::InvalidateCore(
OAuth2TokenServiceRequest* owner,
const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>&
provider,
const std::string& access_token,
const CoreAccountId& account_id,
const OAuth2TokenService::ScopeSet& scopes)
: OAuth2TokenServiceRequest::Core(owner, provider),
access_token_(access_token),
account_id_(account_id),
scopes_(scopes) {
DCHECK(!access_token_.empty());
DCHECK(!account_id_.empty());
DCHECK(!scopes.empty());
}
InvalidateCore::~InvalidateCore() {
}
void InvalidateCore::StartOnTokenServiceThread() {
DCHECK(token_service_task_runner()->RunsTasksInCurrentSequence());
token_service()->InvalidateAccessToken(account_id_, scopes_, access_token_);
}
void InvalidateCore::StopOnTokenServiceThread() {
DCHECK(token_service_task_runner()->RunsTasksInCurrentSequence());
// Nothing to do.
}
} // namespace
// static
std::unique_ptr<OAuth2TokenServiceRequest>
OAuth2TokenServiceRequest::CreateAndStart(
const scoped_refptr<TokenServiceProvider>& provider,
const CoreAccountId& account_id,
const OAuth2TokenService::ScopeSet& scopes,
OAuth2TokenService::Consumer* consumer) {
std::unique_ptr<OAuth2TokenServiceRequest> request(
new OAuth2TokenServiceRequest(account_id));
scoped_refptr<Core> core(
new RequestCore(request.get(), provider, consumer, account_id, scopes));
request->StartWithCore(core);
return request;
}
// static
void OAuth2TokenServiceRequest::InvalidateToken(
const scoped_refptr<TokenServiceProvider>& provider,
const CoreAccountId& account_id,
const OAuth2TokenService::ScopeSet& scopes,
const std::string& access_token) {
std::unique_ptr<OAuth2TokenServiceRequest> request(
new OAuth2TokenServiceRequest(account_id));
scoped_refptr<Core> core(new InvalidateCore(
request.get(), provider, access_token, account_id, scopes));
request->StartWithCore(core);
}
OAuth2TokenServiceRequest::~OAuth2TokenServiceRequest() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
core_->Stop();
}
CoreAccountId OAuth2TokenServiceRequest::GetAccountId() const {
return account_id_;
}
OAuth2TokenServiceRequest::OAuth2TokenServiceRequest(
const CoreAccountId& account_id)
: account_id_(account_id) {
DCHECK(!account_id_.empty());
}
void OAuth2TokenServiceRequest::StartWithCore(const scoped_refptr<Core>& core) {
DCHECK(core.get());
core_ = core;
core_->Start();
}
// 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 <memory>
#include <set>
#include <string>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/sequence_checker.h"
#include "base/single_thread_task_runner.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:
class Core;
// Interface for providing an OAuth2TokenService.
//
// Ref-counted so that OAuth2TokenServiceRequest can ensure this object isn't
// destroyed out from under the token service task runner thread. Because
// OAuth2TokenServiceRequest has a reference, implementations of
// TokenServiceProvider must be capable of being destroyed on the same thread
// on which the OAuth2TokenServiceRequest was created.
class TokenServiceProvider
: public base::RefCountedThreadSafe<TokenServiceProvider> {
public:
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;
protected:
friend class base::RefCountedThreadSafe<TokenServiceProvider>;
virtual ~TokenServiceProvider();
};
// Creates and starts an access token request for |account_id| and |scopes|.
//
// |provider| is used to get the OAuth2TokenService.
//
// |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 std::unique_ptr<OAuth2TokenServiceRequest> CreateAndStart(
const scoped_refptr<TokenServiceProvider>& provider,
const CoreAccountId& account_id,
const OAuth2TokenService::ScopeSet& scopes,
OAuth2TokenService::Consumer* consumer);
// Invalidates |access_token| for |account_id| and |scopes|.
//
// |provider| is used to get the OAuth2TokenService.
//
// |account_id| must not be empty.
//
// |scopes| must not be empty.
static void InvalidateToken(
const scoped_refptr<TokenServiceProvider>& provider,
const CoreAccountId& account_id,
const OAuth2TokenService::ScopeSet& scopes,
const std::string& access_token);
~OAuth2TokenServiceRequest() override;
// OAuth2TokenService::Request.
CoreAccountId GetAccountId() const override;
private:
OAuth2TokenServiceRequest(const CoreAccountId& account_id);
void StartWithCore(const scoped_refptr<Core>& core);
const CoreAccountId account_id_;
scoped_refptr<Core> core_;
SEQUENCE_CHECKER(sequence_checker_);
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/bind.h"
#include "base/location.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.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 kAccountIdString[] = "test_user@gmail.com";
const char kScope[] = "SCOPE";
class TestingOAuth2TokenServiceConsumer : public OAuth2TokenService::Consumer {
public:
TestingOAuth2TokenServiceConsumer();
~TestingOAuth2TokenServiceConsumer() override;
void OnGetTokenSuccess(
const OAuth2TokenService::Request* request,
const OAuth2AccessTokenConsumer::TokenResponse& token_response) override;
void OnGetTokenFailure(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) override;
int num_get_token_success_;
int num_get_token_failure_;
std::string last_token_;
std::string last_id_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 OAuth2AccessTokenConsumer::TokenResponse& token_response) {
last_token_ = token_response.access_token;
last_id_token_ = token_response.id_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();
~MockOAuth2TokenService() override;
void SetResponse(const GoogleServiceAuthError& error,
const std::string& access_token,
const base::Time& expiration,
const std::string& id_token);
int num_invalidate_token() const { return num_invalidate_token_; }
const std::string& last_token_invalidated() const {
return last_token_invalidated_;
}
protected:
void FetchOAuth2Token(
RequestImpl* request,
const CoreAccountId& account_id,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
const std::string& client_id,
const std::string& client_secret,
const ScopeSet& scopes) override;
void InvalidateAccessTokenImpl(const CoreAccountId& 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_;
std::string response_id_token_;
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,
const std::string& id_token) {
response_error_ = error;
response_access_token_ = access_token;
response_expiration_ = expiration;
response_id_token_ = id_token;
}
void MockOAuth2TokenService::FetchOAuth2Token(
RequestImpl* request,
const CoreAccountId& account_id,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
const std::string& client_id,
const std::string& client_secret,
const ScopeSet& scopes) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&OAuth2TokenService::RequestImpl::InformConsumer,
request->AsWeakPtr(), response_error_,
OAuth2AccessTokenConsumer::TokenResponse(
response_access_token_, response_expiration_,
response_id_token_)));
}
void MockOAuth2TokenService::InvalidateAccessTokenImpl(
const CoreAccountId& 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:
OAuth2TokenServiceRequestTest() : kAccountId_(kAccountIdString) {}
void SetUp() override;
void TearDown() override;
protected:
class Provider : public OAuth2TokenServiceRequest::TokenServiceProvider {
public:
Provider(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
OAuth2TokenService* token_service);
scoped_refptr<base::SingleThreadTaskRunner> GetTokenServiceTaskRunner()
override;
OAuth2TokenService* GetTokenService() override;
private:
~Provider() override;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
OAuth2TokenService* token_service_;
};
const CoreAccountId kAccountId_;
base::MessageLoop ui_loop_;
OAuth2TokenService::ScopeSet scopes_;
std::unique_ptr<MockOAuth2TokenService> oauth2_service_;
scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider> provider_;
TestingOAuth2TokenServiceConsumer consumer_;
};
void OAuth2TokenServiceRequestTest::SetUp() {
scopes_.insert(kScope);
oauth2_service_.reset(new MockOAuth2TokenService);
oauth2_service_->AddAccount(kAccountId_);
provider_ =
new Provider(base::ThreadTaskRunnerHandle::Get(), oauth2_service_.get());
}
void OAuth2TokenServiceRequestTest::TearDown() {
// Run the loop to execute any pending tasks that may free resources.
base::RunLoop().RunUntilIdle();
}
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_;
}
OAuth2TokenServiceRequestTest::Provider::~Provider() {
}
TEST_F(OAuth2TokenServiceRequestTest, CreateAndStart_Failure) {
oauth2_service_->SetResponse(
GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE),
std::string(), base::Time(), std::string());
std::unique_ptr<OAuth2TokenServiceRequest> request(
OAuth2TokenServiceRequest::CreateAndStart(provider_.get(), kAccountId_,
scopes_, &consumer_));
base::RunLoop().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) {
std::unique_ptr<OAuth2TokenServiceRequest> request(
OAuth2TokenServiceRequest::CreateAndStart(provider_.get(), kAccountId_,
scopes_, &consumer_));
base::RunLoop().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) {
std::unique_ptr<OAuth2TokenServiceRequest> request(
OAuth2TokenServiceRequest::CreateAndStart(provider_.get(), kAccountId_,
scopes_, &consumer_));
request.reset();
base::RunLoop().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) {
std::unique_ptr<OAuth2TokenServiceRequest> request(
OAuth2TokenServiceRequest::CreateAndStart(provider_.get(), kAccountId_,
scopes_, &consumer_));
base::RunLoop().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);
base::RunLoop().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
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