Home | History | Annotate | Download | only in gaia
      1 // Copyright 2014 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 #include "google_apis/gaia/oauth2_token_service_request.h"
      6 
      7 #include <set>
      8 #include <string>
      9 #include <vector>
     10 #include "base/threading/thread.h"
     11 #include "google_apis/gaia/fake_oauth2_token_service.h"
     12 #include "google_apis/gaia/google_service_auth_error.h"
     13 #include "google_apis/gaia/oauth2_token_service.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 
     16 namespace {
     17 
     18 const char kAccessToken[] = "access_token";
     19 const char kAccountId[] = "test_user (at) gmail.com";
     20 const char kScope[] = "SCOPE";
     21 
     22 class TestingOAuth2TokenServiceConsumer : public OAuth2TokenService::Consumer {
     23  public:
     24   TestingOAuth2TokenServiceConsumer();
     25   virtual ~TestingOAuth2TokenServiceConsumer();
     26 
     27   virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
     28                                  const std::string& access_token,
     29                                  const base::Time& expiration_time) OVERRIDE;
     30   virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
     31                                  const GoogleServiceAuthError& error) OVERRIDE;
     32 
     33   int num_get_token_success_;
     34   int num_get_token_failure_;
     35   std::string last_token_;
     36   GoogleServiceAuthError last_error_;
     37 };
     38 
     39 TestingOAuth2TokenServiceConsumer::TestingOAuth2TokenServiceConsumer()
     40     : OAuth2TokenService::Consumer("test"),
     41       num_get_token_success_(0),
     42       num_get_token_failure_(0),
     43       last_error_(GoogleServiceAuthError::AuthErrorNone()) {
     44 }
     45 
     46 TestingOAuth2TokenServiceConsumer::~TestingOAuth2TokenServiceConsumer() {
     47 }
     48 
     49 void TestingOAuth2TokenServiceConsumer::OnGetTokenSuccess(
     50     const OAuth2TokenService::Request* request,
     51     const std::string& token,
     52     const base::Time& expiration_date) {
     53   last_token_ = token;
     54   ++num_get_token_success_;
     55 }
     56 
     57 void TestingOAuth2TokenServiceConsumer::OnGetTokenFailure(
     58     const OAuth2TokenService::Request* request,
     59     const GoogleServiceAuthError& error) {
     60   last_error_ = error;
     61   ++num_get_token_failure_;
     62 }
     63 
     64 // A mock implementation of an OAuth2TokenService.
     65 //
     66 // Use SetResponse to vary the response to token requests.
     67 class MockOAuth2TokenService : public FakeOAuth2TokenService {
     68  public:
     69   MockOAuth2TokenService();
     70   virtual ~MockOAuth2TokenService();
     71 
     72   void SetResponse(const GoogleServiceAuthError& error,
     73                    const std::string& access_token,
     74                    const base::Time& expiration);
     75 
     76   int num_invalidate_token() const { return num_invalidate_token_; }
     77 
     78   const std::string& last_token_invalidated() const {
     79     return last_token_invalidated_;
     80   }
     81 
     82  protected:
     83   virtual void FetchOAuth2Token(RequestImpl* request,
     84                                 const std::string& account_id,
     85                                 net::URLRequestContextGetter* getter,
     86                                 const std::string& client_id,
     87                                 const std::string& client_secret,
     88                                 const ScopeSet& scopes) OVERRIDE;
     89 
     90   virtual void InvalidateOAuth2Token(const std::string& account_id,
     91                                      const std::string& client_id,
     92                                      const ScopeSet& scopes,
     93                                      const std::string& access_token) OVERRIDE;
     94 
     95  private:
     96   GoogleServiceAuthError response_error_;
     97   std::string response_access_token_;
     98   base::Time response_expiration_;
     99   int num_invalidate_token_;
    100   std::string last_token_invalidated_;
    101 };
    102 
    103 MockOAuth2TokenService::MockOAuth2TokenService()
    104     : response_error_(GoogleServiceAuthError::AuthErrorNone()),
    105       response_access_token_(kAccessToken),
    106       response_expiration_(base::Time::Max()),
    107       num_invalidate_token_(0) {
    108 }
    109 
    110 MockOAuth2TokenService::~MockOAuth2TokenService() {
    111 }
    112 
    113 void MockOAuth2TokenService::SetResponse(const GoogleServiceAuthError& error,
    114                                          const std::string& access_token,
    115                                          const base::Time& expiration) {
    116   response_error_ = error;
    117   response_access_token_ = access_token;
    118   response_expiration_ = expiration;
    119 }
    120 
    121 void MockOAuth2TokenService::FetchOAuth2Token(
    122     RequestImpl* request,
    123     const std::string& account_id,
    124     net::URLRequestContextGetter* getter,
    125     const std::string& client_id,
    126     const std::string& client_secret,
    127     const ScopeSet& scopes) {
    128   base::MessageLoop::current()->PostTask(
    129       FROM_HERE,
    130       base::Bind(&OAuth2TokenService::RequestImpl::InformConsumer,
    131                  request->AsWeakPtr(),
    132                  response_error_,
    133                  response_access_token_,
    134                  response_expiration_));
    135 }
    136 
    137 void MockOAuth2TokenService::InvalidateOAuth2Token(
    138     const std::string& account_id,
    139     const std::string& client_id,
    140     const ScopeSet& scopes,
    141     const std::string& access_token) {
    142   ++num_invalidate_token_;
    143   last_token_invalidated_ = access_token;
    144 }
    145 
    146 class OAuth2TokenServiceRequestTest : public testing::Test {
    147  public:
    148   virtual void SetUp() OVERRIDE;
    149   virtual void TearDown() OVERRIDE;
    150 
    151  protected:
    152   class Provider : public OAuth2TokenServiceRequest::TokenServiceProvider {
    153    public:
    154     Provider(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
    155              OAuth2TokenService* token_service);
    156 
    157     virtual scoped_refptr<base::SingleThreadTaskRunner>
    158         GetTokenServiceTaskRunner() OVERRIDE;
    159     virtual OAuth2TokenService* GetTokenService() OVERRIDE;
    160 
    161    private:
    162     virtual ~Provider();
    163 
    164     scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
    165     OAuth2TokenService* token_service_;
    166   };
    167 
    168   base::MessageLoop ui_loop_;
    169   OAuth2TokenService::ScopeSet scopes_;
    170   scoped_ptr<MockOAuth2TokenService> oauth2_service_;
    171   scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider> provider_;
    172   TestingOAuth2TokenServiceConsumer consumer_;
    173 };
    174 
    175 void OAuth2TokenServiceRequestTest::SetUp() {
    176   scopes_.insert(kScope);
    177   oauth2_service_.reset(new MockOAuth2TokenService);
    178   oauth2_service_->AddAccount(kAccountId);
    179   provider_ =
    180       new Provider(base::MessageLoopProxy::current(), oauth2_service_.get());
    181 }
    182 
    183 void OAuth2TokenServiceRequestTest::TearDown() {
    184   // Run the loop to execute any pending tasks that may free resources.
    185   ui_loop_.RunUntilIdle();
    186 }
    187 
    188 OAuth2TokenServiceRequestTest::Provider::Provider(
    189     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
    190     OAuth2TokenService* token_service)
    191     : task_runner_(task_runner), token_service_(token_service) {
    192 }
    193 
    194 scoped_refptr<base::SingleThreadTaskRunner>
    195 OAuth2TokenServiceRequestTest::Provider::GetTokenServiceTaskRunner() {
    196   return task_runner_;
    197 }
    198 
    199 OAuth2TokenService* OAuth2TokenServiceRequestTest::Provider::GetTokenService() {
    200   return token_service_;
    201 }
    202 
    203 OAuth2TokenServiceRequestTest::Provider::~Provider() {
    204 }
    205 
    206 TEST_F(OAuth2TokenServiceRequestTest, CreateAndStart_Failure) {
    207   oauth2_service_->SetResponse(
    208       GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE),
    209       std::string(),
    210       base::Time());
    211   scoped_ptr<OAuth2TokenServiceRequest> request(
    212       OAuth2TokenServiceRequest::CreateAndStart(
    213           provider_.get(), kAccountId, scopes_, &consumer_));
    214   ui_loop_.RunUntilIdle();
    215   EXPECT_EQ(0, consumer_.num_get_token_success_);
    216   EXPECT_EQ(1, consumer_.num_get_token_failure_);
    217   EXPECT_EQ(GoogleServiceAuthError::SERVICE_UNAVAILABLE,
    218             consumer_.last_error_.state());
    219   EXPECT_EQ(0, oauth2_service_->num_invalidate_token());
    220 }
    221 
    222 TEST_F(OAuth2TokenServiceRequestTest, CreateAndStart_Success) {
    223   scoped_ptr<OAuth2TokenServiceRequest> request(
    224       OAuth2TokenServiceRequest::CreateAndStart(
    225           provider_.get(), kAccountId, scopes_, &consumer_));
    226   ui_loop_.RunUntilIdle();
    227   EXPECT_EQ(1, consumer_.num_get_token_success_);
    228   EXPECT_EQ(0, consumer_.num_get_token_failure_);
    229   EXPECT_EQ(kAccessToken, consumer_.last_token_);
    230   EXPECT_EQ(0, oauth2_service_->num_invalidate_token());
    231 }
    232 
    233 TEST_F(OAuth2TokenServiceRequestTest,
    234        CreateAndStart_DestroyRequestBeforeCompletes) {
    235   scoped_ptr<OAuth2TokenServiceRequest> request(
    236       OAuth2TokenServiceRequest::CreateAndStart(
    237           provider_.get(), kAccountId, scopes_, &consumer_));
    238   request.reset();
    239   ui_loop_.RunUntilIdle();
    240   EXPECT_EQ(0, consumer_.num_get_token_success_);
    241   EXPECT_EQ(0, consumer_.num_get_token_failure_);
    242   EXPECT_EQ(0, oauth2_service_->num_invalidate_token());
    243 }
    244 
    245 TEST_F(OAuth2TokenServiceRequestTest,
    246        CreateAndStart_DestroyRequestAfterCompletes) {
    247   scoped_ptr<OAuth2TokenServiceRequest> request(
    248       OAuth2TokenServiceRequest::CreateAndStart(
    249           provider_.get(), kAccountId, scopes_, &consumer_));
    250   ui_loop_.RunUntilIdle();
    251   request.reset();
    252   EXPECT_EQ(1, consumer_.num_get_token_success_);
    253   EXPECT_EQ(0, consumer_.num_get_token_failure_);
    254   EXPECT_EQ(kAccessToken, consumer_.last_token_);
    255   EXPECT_EQ(0, oauth2_service_->num_invalidate_token());
    256 }
    257 
    258 TEST_F(OAuth2TokenServiceRequestTest, InvalidateToken) {
    259   OAuth2TokenServiceRequest::InvalidateToken(
    260       provider_.get(), kAccountId, scopes_, kAccessToken);
    261   ui_loop_.RunUntilIdle();
    262   EXPECT_EQ(0, consumer_.num_get_token_success_);
    263   EXPECT_EQ(0, consumer_.num_get_token_failure_);
    264   EXPECT_EQ(kAccessToken, oauth2_service_->last_token_invalidated());
    265   EXPECT_EQ(1, oauth2_service_->num_invalidate_token());
    266 }
    267 
    268 }  // namespace
    269