blob: ef1c18b421d6203dd37640206be6937bd4e35992 [file] [log] [blame]
// 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/oauth2_token_service.h"
#include "chrome/browser/signin/profile_oauth2_token_service.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/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 "testing/gtest/include/gtest/gtest.h"
namespace {
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()
: 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 MockProfileOAuth2TokenService : public ProfileOAuth2TokenService {
public:
class Request : public OAuth2TokenService::Request,
public base::SupportsWeakPtr<Request> {
public:
Request(OAuth2TokenService::Consumer* consumer,
GoogleServiceAuthError error,
std::string access_token);
virtual ~Request();
void InformConsumer() const;
private:
OAuth2TokenService::Consumer* consumer_;
GoogleServiceAuthError error_;
std::string access_token_;
base::Time expiration_date_;
};
MockProfileOAuth2TokenService();
virtual ~MockProfileOAuth2TokenService();
virtual scoped_ptr<OAuth2TokenService::Request> StartRequest(
const std::set<std::string>& scopes,
OAuth2TokenService::Consumer* consumer) OVERRIDE;
void SetExpectation(bool success, std::string oauth2_access_token);
private:
static void InformConsumer(
base::WeakPtr<MockProfileOAuth2TokenService::Request> request);
bool success_;
std::string oauth2_access_token_;
};
MockProfileOAuth2TokenService::Request::Request(
OAuth2TokenService::Consumer* consumer,
GoogleServiceAuthError error,
std::string access_token)
: consumer_(consumer),
error_(error),
access_token_(access_token) {
}
MockProfileOAuth2TokenService::Request::~Request() {
}
void MockProfileOAuth2TokenService::Request::InformConsumer() const {
if (error_.state() == GoogleServiceAuthError::NONE)
consumer_->OnGetTokenSuccess(this, access_token_, expiration_date_);
else
consumer_->OnGetTokenFailure(this, error_);
}
MockProfileOAuth2TokenService::MockProfileOAuth2TokenService()
: success_(true),
oauth2_access_token_(std::string("success token")) {
}
MockProfileOAuth2TokenService::~MockProfileOAuth2TokenService() {
}
void MockProfileOAuth2TokenService::SetExpectation(bool success,
std::string oauth2_access_token) {
success_ = success;
oauth2_access_token_ = oauth2_access_token;
}
// static
void MockProfileOAuth2TokenService::InformConsumer(
base::WeakPtr<MockProfileOAuth2TokenService::Request> request) {
if (request.get())
request->InformConsumer();
}
scoped_ptr<OAuth2TokenService::Request>
MockProfileOAuth2TokenService::StartRequest(
const std::set<std::string>& scopes,
OAuth2TokenService::Consumer* consumer) {
scoped_ptr<Request> request;
if (success_) {
request.reset(new MockProfileOAuth2TokenService::Request(
consumer,
GoogleServiceAuthError(GoogleServiceAuthError::NONE),
oauth2_access_token_));
} else {
request.reset(new MockProfileOAuth2TokenService::Request(
consumer,
GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE),
std::string()));
}
base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&MockProfileOAuth2TokenService::InformConsumer, request->AsWeakPtr()));
return request.PassAs<OAuth2TokenService::Request>();
}
static BrowserContextKeyedService* CreateOAuth2TokenService(
content::BrowserContext* profile) {
MockProfileOAuth2TokenService* mock = new MockProfileOAuth2TokenService();
mock->Initialize(static_cast<Profile*>(profile));
return mock;
}
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_;
MockProfileOAuth2TokenService* oauth2_service_;
scoped_ptr<ProfileOAuth2TokenServiceRequest> request_;
};
void ProfileOAuth2TokenServiceRequestTest::SetUp() {
ui_thread_.reset(new content::TestBrowserThread(content::BrowserThread::UI,
&ui_loop_));
profile_.reset(new TestingProfile());
ProfileOAuth2TokenServiceFactory::GetInstance()->SetTestingFactory(
profile_.get(), &CreateOAuth2TokenService);
oauth2_service_ = (MockProfileOAuth2TokenService*)
ProfileOAuth2TokenServiceFactory::GetForProfile(profile_.get());
}
TEST_F(ProfileOAuth2TokenServiceRequestTest,
Failure) {
oauth2_service_->SetExpectation(false, std::string());
scoped_ptr<ProfileOAuth2TokenServiceRequest> request(
ProfileOAuth2TokenServiceRequest::CreateAndStart(
profile_.get(),
std::set<std::string>(),
&consumer_));
ui_loop_.RunUntilIdle();
EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
EXPECT_EQ(1, consumer_.number_of_errors_);
}
TEST_F(ProfileOAuth2TokenServiceRequestTest,
Success) {
scoped_ptr<ProfileOAuth2TokenServiceRequest> request(
ProfileOAuth2TokenServiceRequest::CreateAndStart(
profile_.get(),
std::set<std::string>(),
&consumer_));
ui_loop_.RunUntilIdle();
EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
EXPECT_EQ("success token", consumer_.last_token_);
EXPECT_EQ(0, consumer_.number_of_errors_);
}
TEST_F(ProfileOAuth2TokenServiceRequestTest,
RequestDeletionBeforeServiceComplete) {
scoped_ptr<ProfileOAuth2TokenServiceRequest> request(
ProfileOAuth2TokenServiceRequest::CreateAndStart(
profile_.get(),
std::set<std::string>(),
&consumer_));
request.reset();
ui_loop_.RunUntilIdle();
EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
EXPECT_EQ(0, consumer_.number_of_errors_);
}
TEST_F(ProfileOAuth2TokenServiceRequestTest,
RequestDeletionAfterServiceComplete) {
scoped_ptr<ProfileOAuth2TokenServiceRequest> request(
ProfileOAuth2TokenServiceRequest::CreateAndStart(
profile_.get(),
std::set<std::string>(),
&consumer_));
ui_loop_.RunUntilIdle();
request.reset();
EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
EXPECT_EQ(0, consumer_.number_of_errors_);
}
} // namespace