oauth2_token_service_request_unittest.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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
16namespace {
17
18const char kAccessToken[] = "access_token";
19const char kAccountId[] = "test_user@gmail.com";
20const char kScope[] = "SCOPE";
21
22class 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
39TestingOAuth2TokenServiceConsumer::TestingOAuth2TokenServiceConsumer()
40    : OAuth2TokenService::Consumer("test"),
41      num_get_token_success_(0),
42      num_get_token_failure_(0),
43      last_error_(GoogleServiceAuthError::AuthErrorNone()) {
44}
45
46TestingOAuth2TokenServiceConsumer::~TestingOAuth2TokenServiceConsumer() {
47}
48
49void 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
57void 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.
67class 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
103MockOAuth2TokenService::MockOAuth2TokenService()
104    : response_error_(GoogleServiceAuthError::AuthErrorNone()),
105      response_access_token_(kAccessToken),
106      response_expiration_(base::Time::Max()),
107      num_invalidate_token_(0) {
108}
109
110MockOAuth2TokenService::~MockOAuth2TokenService() {
111}
112
113void 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
121void 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
137void 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
146class 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    scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
163    OAuth2TokenService* token_service_;
164  };
165
166  base::MessageLoop ui_loop_;
167  OAuth2TokenService::ScopeSet scopes_;
168  scoped_ptr<MockOAuth2TokenService> oauth2_service_;
169  scoped_ptr<OAuth2TokenServiceRequest::TokenServiceProvider> provider_;
170  TestingOAuth2TokenServiceConsumer consumer_;
171};
172
173void OAuth2TokenServiceRequestTest::SetUp() {
174  scopes_.insert(kScope);
175  oauth2_service_.reset(new MockOAuth2TokenService);
176  oauth2_service_->AddAccount(kAccountId);
177  provider_.reset(
178      new Provider(base::MessageLoopProxy::current(), oauth2_service_.get()));
179}
180
181void OAuth2TokenServiceRequestTest::TearDown() {
182  // Run the loop to execute any pending tasks that may free resources.
183  ui_loop_.RunUntilIdle();
184}
185
186OAuth2TokenServiceRequestTest::Provider::Provider(
187    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
188    OAuth2TokenService* token_service)
189    : task_runner_(task_runner), token_service_(token_service) {
190}
191
192scoped_refptr<base::SingleThreadTaskRunner>
193OAuth2TokenServiceRequestTest::Provider::GetTokenServiceTaskRunner() {
194  return task_runner_;
195}
196
197OAuth2TokenService* OAuth2TokenServiceRequestTest::Provider::GetTokenService() {
198  return token_service_;
199}
200
201TEST_F(OAuth2TokenServiceRequestTest, CreateAndStart_Failure) {
202  oauth2_service_->SetResponse(
203      GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE),
204      std::string(),
205      base::Time());
206  scoped_ptr<OAuth2TokenServiceRequest> request(
207      OAuth2TokenServiceRequest::CreateAndStart(
208          provider_.get(), kAccountId, scopes_, &consumer_));
209  ui_loop_.RunUntilIdle();
210  EXPECT_EQ(0, consumer_.num_get_token_success_);
211  EXPECT_EQ(1, consumer_.num_get_token_failure_);
212  EXPECT_EQ(GoogleServiceAuthError::SERVICE_UNAVAILABLE,
213            consumer_.last_error_.state());
214  EXPECT_EQ(0, oauth2_service_->num_invalidate_token());
215}
216
217TEST_F(OAuth2TokenServiceRequestTest, CreateAndStart_Success) {
218  scoped_ptr<OAuth2TokenServiceRequest> request(
219      OAuth2TokenServiceRequest::CreateAndStart(
220          provider_.get(), kAccountId, scopes_, &consumer_));
221  ui_loop_.RunUntilIdle();
222  EXPECT_EQ(1, consumer_.num_get_token_success_);
223  EXPECT_EQ(0, consumer_.num_get_token_failure_);
224  EXPECT_EQ(kAccessToken, consumer_.last_token_);
225  EXPECT_EQ(0, oauth2_service_->num_invalidate_token());
226}
227
228TEST_F(OAuth2TokenServiceRequestTest,
229       CreateAndStart_DestroyRequestBeforeCompletes) {
230  scoped_ptr<OAuth2TokenServiceRequest> request(
231      OAuth2TokenServiceRequest::CreateAndStart(
232          provider_.get(), kAccountId, scopes_, &consumer_));
233  request.reset();
234  ui_loop_.RunUntilIdle();
235  EXPECT_EQ(0, consumer_.num_get_token_success_);
236  EXPECT_EQ(0, consumer_.num_get_token_failure_);
237  EXPECT_EQ(0, oauth2_service_->num_invalidate_token());
238}
239
240TEST_F(OAuth2TokenServiceRequestTest,
241       CreateAndStart_DestroyRequestAfterCompletes) {
242  scoped_ptr<OAuth2TokenServiceRequest> request(
243      OAuth2TokenServiceRequest::CreateAndStart(
244          provider_.get(), kAccountId, scopes_, &consumer_));
245  ui_loop_.RunUntilIdle();
246  request.reset();
247  EXPECT_EQ(1, consumer_.num_get_token_success_);
248  EXPECT_EQ(0, consumer_.num_get_token_failure_);
249  EXPECT_EQ(kAccessToken, consumer_.last_token_);
250  EXPECT_EQ(0, oauth2_service_->num_invalidate_token());
251}
252
253TEST_F(OAuth2TokenServiceRequestTest, InvalidateToken) {
254  OAuth2TokenServiceRequest::InvalidateToken(
255      provider_.get(), kAccountId, scopes_, kAccessToken);
256  ui_loop_.RunUntilIdle();
257  EXPECT_EQ(0, consumer_.num_get_token_success_);
258  EXPECT_EQ(0, consumer_.num_get_token_failure_);
259  EXPECT_EQ(kAccessToken, oauth2_service_->last_token_invalidated());
260  EXPECT_EQ(1, oauth2_service_->num_invalidate_token());
261}
262
263}  // namespace
264