1// Copyright (c) 2011 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// A complete set of unit tests for GaiaOAuthClient.
6
7#include <string>
8
9#include "base/message_loop.h"
10#include "base/string_number_conversions.h"
11#include "base/string_util.h"
12#include "chrome/common/net/gaia/gaia_oauth_client.h"
13#include "chrome/common/net/http_return.h"
14#include "chrome/common/net/test_url_fetcher_factory.h"
15#include "chrome/common/net/url_fetcher.h"
16#include "chrome/test/testing_profile.h"
17#include "googleurl/src/gurl.h"
18#include "net/base/net_errors.h"
19#include "net/url_request/url_request_status.h"
20#include "testing/gmock/include/gmock/gmock.h"
21#include "testing/gtest/include/gtest/gtest.h"
22
23using ::testing::_;
24
25namespace {
26// Responds as though OAuth returned from the server.
27class MockOAuthFetcher : public URLFetcher {
28 public:
29  MockOAuthFetcher(int response_code,
30                   int max_failure_count,
31                   const GURL& url,
32                   const std::string& results,
33                   URLFetcher::RequestType request_type,
34                   URLFetcher::Delegate* d)
35    : URLFetcher(url, request_type, d),
36      response_code_(response_code),
37      max_failure_count_(max_failure_count),
38      current_failure_count_(0),
39      url_(url),
40      results_(results) { }
41  virtual ~MockOAuthFetcher() { }
42
43  virtual void Start() {
44    if ((response_code_ != RC_REQUEST_OK) && (max_failure_count_ != -1) &&
45        (current_failure_count_ == max_failure_count_)) {
46      response_code_ = RC_REQUEST_OK;
47    }
48
49    net::URLRequestStatus::Status code = net::URLRequestStatus::SUCCESS;
50    if (response_code_ != RC_REQUEST_OK) {
51      code = net::URLRequestStatus::FAILED;
52      current_failure_count_++;
53    }
54    net::URLRequestStatus status(code, 0);
55    delegate()->OnURLFetchComplete(this,
56                                   url_,
57                                   status,
58                                   response_code_,
59                                   ResponseCookies(),
60                                   results_);
61  }
62
63 private:
64  int response_code_;
65  int max_failure_count_;
66  int current_failure_count_;
67  GURL url_;
68  std::string results_;
69  DISALLOW_COPY_AND_ASSIGN(MockOAuthFetcher);
70};
71
72class MockOAuthFetcherFactory : public URLFetcher::Factory {
73 public:
74  MockOAuthFetcherFactory()
75      : response_code_(RC_REQUEST_OK) {}
76  ~MockOAuthFetcherFactory() {}
77  virtual URLFetcher* CreateURLFetcher(
78      int id,
79      const GURL& url,
80      URLFetcher::RequestType request_type,
81      URLFetcher::Delegate* d) {
82    return new MockOAuthFetcher(
83        response_code_,
84        max_failure_count_,
85        url,
86        results_,
87        request_type,
88        d);
89  }
90  void set_response_code(int response_code) {
91    response_code_ = response_code;
92  }
93  void set_max_failure_count(int count) {
94    max_failure_count_ = count;
95  }
96  void set_results(const std::string& results) {
97    results_ = results;
98  }
99 private:
100  int response_code_;
101  int max_failure_count_;
102  std::string results_;
103  DISALLOW_COPY_AND_ASSIGN(MockOAuthFetcherFactory);
104};
105
106const std::string kTestAccessToken = "1/fFAGRNJru1FTz70BzhT3Zg";
107const std::string kTestRefreshToken =
108    "1/6BMfW9j53gdGImsixUH6kU5RsR4zwI9lUVX-tqf8JXQ";
109const int kTestExpiresIn = 3920;
110
111const std::string kDummyGetTokensResult =
112  "{\"access_token\":\"" + kTestAccessToken + "\","
113  "\"expires_in\":" + base::IntToString(kTestExpiresIn) + ","
114  "\"refresh_token\":\"" + kTestRefreshToken + "\"}";
115
116const std::string kDummyRefreshTokenResult =
117  "{\"access_token\":\"" + kTestAccessToken + "\","
118  "\"expires_in\":" + base::IntToString(kTestExpiresIn) + "}";
119}
120
121namespace gaia {
122
123class GaiaOAuthClientTest : public testing::Test {
124 public:
125  GaiaOAuthClientTest() {}
126
127  TestingProfile profile_;
128 protected:
129  MessageLoop message_loop_;
130};
131
132class MockGaiaOAuthClientDelegate : public gaia::GaiaOAuthClient::Delegate {
133 public:
134  MockGaiaOAuthClientDelegate() {}
135  ~MockGaiaOAuthClientDelegate() {}
136
137  MOCK_METHOD3(OnGetTokensResponse, void(const std::string& refresh_token,
138      const std::string& access_token, int expires_in_seconds));
139  MOCK_METHOD2(OnRefreshTokenResponse, void(const std::string& access_token,
140      int expires_in_seconds));
141  MOCK_METHOD0(OnOAuthError, void());
142  MOCK_METHOD1(OnNetworkError, void(int response_code));
143};
144
145TEST_F(GaiaOAuthClientTest, NetworkFailure) {
146  int response_code = RC_INTERNAL_SERVER_ERROR;
147
148  MockGaiaOAuthClientDelegate delegate;
149  EXPECT_CALL(delegate, OnNetworkError(response_code))
150      .Times(1);
151
152  TestingProfile profile;
153
154  MockOAuthFetcherFactory factory;
155  URLFetcher::set_factory(&factory);
156  factory.set_response_code(response_code);
157  factory.set_max_failure_count(4);
158
159  OAuthClientInfo client_info;
160  client_info.client_id = "test_client_id";
161  client_info.client_secret = "test_client_secret";
162  GaiaOAuthClient auth(kGaiaOAuth2Url,
163                       profile_.GetRequestContext());
164  auth.GetTokensFromAuthCode(client_info, "auth_code", 2, &delegate);
165  URLFetcher::set_factory(NULL);
166}
167
168TEST_F(GaiaOAuthClientTest, NetworkFailureRecover) {
169  int response_code = RC_INTERNAL_SERVER_ERROR;
170
171  MockGaiaOAuthClientDelegate delegate;
172  EXPECT_CALL(delegate, OnGetTokensResponse(kTestRefreshToken, kTestAccessToken,
173      kTestExpiresIn)).Times(1);
174
175  TestingProfile profile;
176
177  MockOAuthFetcherFactory factory;
178  URLFetcher::set_factory(&factory);
179  factory.set_response_code(response_code);
180  factory.set_max_failure_count(4);
181  factory.set_results(kDummyGetTokensResult);
182
183  OAuthClientInfo client_info;
184  client_info.client_id = "test_client_id";
185  client_info.client_secret = "test_client_secret";
186  GaiaOAuthClient auth(kGaiaOAuth2Url,
187                       profile_.GetRequestContext());
188  auth.GetTokensFromAuthCode(client_info, "auth_code", -1, &delegate);
189  URLFetcher::set_factory(NULL);
190}
191
192TEST_F(GaiaOAuthClientTest, OAuthFailure) {
193  int response_code = RC_BAD_REQUEST;
194
195  MockGaiaOAuthClientDelegate delegate;
196  EXPECT_CALL(delegate, OnOAuthError()).Times(1);
197
198  TestingProfile profile;
199
200  MockOAuthFetcherFactory factory;
201  URLFetcher::set_factory(&factory);
202  factory.set_response_code(response_code);
203  factory.set_max_failure_count(-1);
204  factory.set_results(kDummyGetTokensResult);
205
206  OAuthClientInfo client_info;
207  client_info.client_id = "test_client_id";
208  client_info.client_secret = "test_client_secret";
209  GaiaOAuthClient auth(kGaiaOAuth2Url,
210                       profile_.GetRequestContext());
211  auth.GetTokensFromAuthCode(client_info, "auth_code", -1, &delegate);
212  URLFetcher::set_factory(NULL);
213}
214
215
216TEST_F(GaiaOAuthClientTest, GetTokensSuccess) {
217  MockGaiaOAuthClientDelegate delegate;
218  EXPECT_CALL(delegate, OnGetTokensResponse(kTestRefreshToken, kTestAccessToken,
219      kTestExpiresIn)).Times(1);
220
221  TestingProfile profile;
222
223  MockOAuthFetcherFactory factory;
224  URLFetcher::set_factory(&factory);
225  factory.set_results(kDummyGetTokensResult);
226
227  OAuthClientInfo client_info;
228  client_info.client_id = "test_client_id";
229  client_info.client_secret = "test_client_secret";
230  GaiaOAuthClient auth(kGaiaOAuth2Url,
231                       profile_.GetRequestContext());
232  auth.GetTokensFromAuthCode(client_info, "auth_code", -1, &delegate);
233  URLFetcher::set_factory(NULL);
234}
235
236TEST_F(GaiaOAuthClientTest, RefreshTokenSuccess) {
237  MockGaiaOAuthClientDelegate delegate;
238  EXPECT_CALL(delegate, OnRefreshTokenResponse(kTestAccessToken,
239      kTestExpiresIn)).Times(1);
240
241  TestingProfile profile;
242
243  MockOAuthFetcherFactory factory;
244  URLFetcher::set_factory(&factory);
245  factory.set_results(kDummyRefreshTokenResult);
246
247  OAuthClientInfo client_info;
248  client_info.client_id = "test_client_id";
249  client_info.client_secret = "test_client_secret";
250  GaiaOAuthClient auth(kGaiaOAuth2Url,
251                       profile_.GetRequestContext());
252  auth.GetTokensFromAuthCode(client_info, "auth_code", -1, &delegate);
253  URLFetcher::set_factory(NULL);
254}
255}  // namespace gaia
256