gaia_auth_fetcher_unittest.cc revision a3f7b4e666c476898878fa745f637129375cd889
1// Copyright (c) 2012 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 GaiaAuthFetcher.
6// Originally ported from GoogleAuthenticator tests.
7
8#include <string>
9
10#include "base/json/json_reader.h"
11#include "base/strings/stringprintf.h"
12#include "base/values.h"
13#include "google_apis/gaia/gaia_auth_consumer.h"
14#include "google_apis/gaia/gaia_auth_fetcher.h"
15#include "google_apis/gaia/gaia_urls.h"
16#include "google_apis/gaia/google_service_auth_error.h"
17#include "google_apis/gaia/mock_url_fetcher_factory.h"
18#include "google_apis/google_api_keys.h"
19#include "net/base/load_flags.h"
20#include "net/base/net_errors.h"
21#include "net/http/http_status_code.h"
22#include "net/url_request/test_url_fetcher_factory.h"
23#include "net/url_request/url_fetcher_delegate.h"
24#include "net/url_request/url_request_status.h"
25#include "net/url_request/url_request_test_util.h"
26#include "testing/gmock/include/gmock/gmock.h"
27#include "testing/gtest/include/gtest/gtest.h"
28#include "url/gurl.h"
29
30using ::testing::_;
31using ::testing::Invoke;
32
33namespace {
34static const char kGetAuthCodeValidCookie[] =
35    "oauth_code=test-code; Path=/test; Secure; HttpOnly";
36static const char kGetAuthCodeCookieNoSecure[] =
37    "oauth_code=test-code; Path=/test; HttpOnly";
38static const char kGetAuthCodeCookieNoHttpOnly[] =
39    "oauth_code=test-code; Path=/test; Secure";
40static const char kGetAuthCodeCookieNoOAuthCode[] =
41    "Path=/test; Secure; HttpOnly";
42static const char kGetTokenPairValidResponse[] =
43    "{"
44    "  \"refresh_token\": \"rt1\","
45    "  \"access_token\": \"at1\","
46    "  \"expires_in\": 3600,"
47    "  \"token_type\": \"Bearer\""
48    "}";
49static const char kClientOAuthValidResponse[] =
50    "{"
51    "  \"oauth2\": {"
52    "    \"refresh_token\": \"rt1\","
53    "    \"access_token\": \"at1\","
54    "    \"expires_in\": 3600,"
55    "    \"token_type\": \"Bearer\""
56    "  }"
57    "}";
58
59}  // namespace
60
61MockFetcher::MockFetcher(bool success,
62                         const GURL& url,
63                         const std::string& results,
64                         net::URLFetcher::RequestType request_type,
65                         net::URLFetcherDelegate* d)
66    : TestURLFetcher(0, url, d) {
67  set_url(url);
68  net::URLRequestStatus::Status code;
69
70  if (success) {
71    set_response_code(net::HTTP_OK);
72    code = net::URLRequestStatus::SUCCESS;
73  } else {
74    set_response_code(net::HTTP_FORBIDDEN);
75    code = net::URLRequestStatus::FAILED;
76  }
77
78  set_status(net::URLRequestStatus(code, 0));
79  SetResponseString(results);
80}
81
82MockFetcher::MockFetcher(const GURL& url,
83                         const net::URLRequestStatus& status,
84                         int response_code,
85                         const net::ResponseCookies& cookies,
86                         const std::string& results,
87                         net::URLFetcher::RequestType request_type,
88                         net::URLFetcherDelegate* d)
89    : TestURLFetcher(0, url, d) {
90  set_url(url);
91  set_status(status);
92  set_response_code(response_code);
93  set_cookies(cookies);
94  SetResponseString(results);
95}
96
97MockFetcher::~MockFetcher() {}
98
99void MockFetcher::Start() {
100  delegate()->OnURLFetchComplete(this);
101}
102
103class GaiaAuthFetcherTest : public testing::Test {
104 protected:
105  GaiaAuthFetcherTest()
106      : client_login_source_(GaiaUrls::GetInstance()->client_login_url()),
107        issue_auth_token_source_(
108            GaiaUrls::GetInstance()->issue_auth_token_url()),
109        client_login_to_oauth2_source_(
110            GaiaUrls::GetInstance()->client_login_to_oauth2_url()),
111        oauth2_token_source_(GaiaUrls::GetInstance()->oauth2_token_url()),
112        token_auth_source_(GaiaUrls::GetInstance()->token_auth_url()),
113        merge_session_source_(GaiaUrls::GetInstance()->merge_session_url()),
114        uberauth_token_source_(base::StringPrintf(
115            "%s?source=&issueuberauth=1",
116            GaiaUrls::GetInstance()->oauth1_login_url().c_str())),
117        oauth_login_gurl_(GaiaUrls::GetInstance()->oauth1_login_url()) {}
118
119  void RunParsingTest(const std::string& data,
120                      const std::string& sid,
121                      const std::string& lsid,
122                      const std::string& token) {
123    std::string out_sid;
124    std::string out_lsid;
125    std::string out_token;
126
127    GaiaAuthFetcher::ParseClientLoginResponse(data,
128                                              &out_sid,
129                                              &out_lsid,
130                                              &out_token);
131    EXPECT_EQ(lsid, out_lsid);
132    EXPECT_EQ(sid, out_sid);
133    EXPECT_EQ(token, out_token);
134  }
135
136  void RunErrorParsingTest(const std::string& data,
137                           const std::string& error,
138                           const std::string& error_url,
139                           const std::string& captcha_url,
140                           const std::string& captcha_token) {
141    std::string out_error;
142    std::string out_error_url;
143    std::string out_captcha_url;
144    std::string out_captcha_token;
145
146    GaiaAuthFetcher::ParseClientLoginFailure(data,
147                                             &out_error,
148                                             &out_error_url,
149                                             &out_captcha_url,
150                                             &out_captcha_token);
151    EXPECT_EQ(error, out_error);
152    EXPECT_EQ(error_url, out_error_url);
153    EXPECT_EQ(captcha_url, out_captcha_url);
154    EXPECT_EQ(captcha_token, out_captcha_token);
155  }
156
157  net::ResponseCookies cookies_;
158  GURL client_login_source_;
159  GURL issue_auth_token_source_;
160  GURL client_login_to_oauth2_source_;
161  GURL oauth2_token_source_;
162  GURL token_auth_source_;
163  GURL merge_session_source_;
164  GURL uberauth_token_source_;
165  GURL oauth_login_gurl_;
166
167 protected:
168  net::TestURLRequestContextGetter* GetRequestContext() {
169    if (!request_context_getter_) {
170      request_context_getter_ = new net::TestURLRequestContextGetter(
171          message_loop_.message_loop_proxy());
172    }
173    return request_context_getter_;
174  }
175
176  base::MessageLoop message_loop_;
177  scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
178};
179
180class MockGaiaConsumer : public GaiaAuthConsumer {
181 public:
182  MockGaiaConsumer() {}
183  ~MockGaiaConsumer() {}
184
185  MOCK_METHOD1(OnClientLoginSuccess, void(const ClientLoginResult& result));
186  MOCK_METHOD2(OnIssueAuthTokenSuccess, void(const std::string& service,
187      const std::string& token));
188  MOCK_METHOD1(OnClientOAuthSuccess,
189               void(const GaiaAuthConsumer::ClientOAuthResult& result));
190  MOCK_METHOD1(OnMergeSessionSuccess, void(const std::string& data));
191  MOCK_METHOD1(OnUberAuthTokenSuccess, void(const std::string& data));
192  MOCK_METHOD1(OnClientLoginFailure,
193      void(const GoogleServiceAuthError& error));
194  MOCK_METHOD2(OnIssueAuthTokenFailure, void(const std::string& service,
195      const GoogleServiceAuthError& error));
196  MOCK_METHOD1(OnClientOAuthFailure,
197      void(const GoogleServiceAuthError& error));
198  MOCK_METHOD1(OnMergeSessionFailure, void(
199      const GoogleServiceAuthError& error));
200  MOCK_METHOD1(OnUberAuthTokenFailure, void(
201      const GoogleServiceAuthError& error));
202};
203
204#if defined(OS_WIN)
205#define MAYBE_ErrorComparator DISABLED_ErrorComparator
206#else
207#define MAYBE_ErrorComparator ErrorComparator
208#endif
209
210TEST_F(GaiaAuthFetcherTest, MAYBE_ErrorComparator) {
211  GoogleServiceAuthError expected_error =
212      GoogleServiceAuthError::FromConnectionError(-101);
213
214  GoogleServiceAuthError matching_error =
215      GoogleServiceAuthError::FromConnectionError(-101);
216
217  EXPECT_TRUE(expected_error == matching_error);
218
219  expected_error = GoogleServiceAuthError::FromConnectionError(6);
220
221  EXPECT_FALSE(expected_error == matching_error);
222
223  expected_error = GoogleServiceAuthError(GoogleServiceAuthError::NONE);
224
225  EXPECT_FALSE(expected_error == matching_error);
226
227  matching_error = GoogleServiceAuthError(GoogleServiceAuthError::NONE);
228
229  EXPECT_TRUE(expected_error == matching_error);
230}
231
232TEST_F(GaiaAuthFetcherTest, LoginNetFailure) {
233  int error_no = net::ERR_CONNECTION_RESET;
234  net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no);
235
236  GoogleServiceAuthError expected_error =
237      GoogleServiceAuthError::FromConnectionError(error_no);
238
239  MockGaiaConsumer consumer;
240  EXPECT_CALL(consumer, OnClientLoginFailure(expected_error))
241      .Times(1);
242
243  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
244
245  MockFetcher mock_fetcher(
246      client_login_source_, status, 0, net::ResponseCookies(), std::string(),
247      net::URLFetcher::GET, &auth);
248  auth.OnURLFetchComplete(&mock_fetcher);
249}
250
251TEST_F(GaiaAuthFetcherTest, TokenNetFailure) {
252  int error_no = net::ERR_CONNECTION_RESET;
253  net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no);
254
255  GoogleServiceAuthError expected_error =
256      GoogleServiceAuthError::FromConnectionError(error_no);
257
258  MockGaiaConsumer consumer;
259  EXPECT_CALL(consumer, OnIssueAuthTokenFailure(_, expected_error))
260      .Times(1);
261
262  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
263
264  MockFetcher mock_fetcher(
265      issue_auth_token_source_, status, 0, cookies_, std::string(),
266      net::URLFetcher::GET, &auth);
267  auth.OnURLFetchComplete(&mock_fetcher);
268}
269
270
271TEST_F(GaiaAuthFetcherTest, LoginDenied) {
272  std::string data("Error=BadAuthentication");
273  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
274
275  GoogleServiceAuthError expected_error(
276      GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
277
278  MockGaiaConsumer consumer;
279  EXPECT_CALL(consumer, OnClientLoginFailure(expected_error))
280      .Times(1);
281
282  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
283
284  MockFetcher mock_fetcher(
285      client_login_source_, status, net::HTTP_FORBIDDEN, cookies_, data,
286      net::URLFetcher::GET, &auth);
287  auth.OnURLFetchComplete(&mock_fetcher);
288}
289
290TEST_F(GaiaAuthFetcherTest, ParseRequest) {
291  RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth\n", "sid", "lsid", "auth");
292  RunParsingTest("LSID=lsid\nSID=sid\nAuth=auth\n", "sid", "lsid", "auth");
293  RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth", "sid", "lsid", "auth");
294  RunParsingTest("SID=sid\nAuth=auth\n", "sid", std::string(), "auth");
295  RunParsingTest("LSID=lsid\nAuth=auth\n", std::string(), "lsid", "auth");
296  RunParsingTest("\nAuth=auth\n", std::string(), std::string(), "auth");
297  RunParsingTest("SID=sid", "sid", std::string(), std::string());
298}
299
300TEST_F(GaiaAuthFetcherTest, ParseErrorRequest) {
301  RunErrorParsingTest("Url=U\n"
302                      "Error=E\n"
303                      "CaptchaToken=T\n"
304                      "CaptchaUrl=C\n", "E", "U", "C", "T");
305  RunErrorParsingTest("CaptchaToken=T\n"
306                      "Error=E\n"
307                      "Url=U\n"
308                      "CaptchaUrl=C\n", "E", "U", "C", "T");
309  RunErrorParsingTest("\n\n\nCaptchaToken=T\n"
310                      "\nError=E\n"
311                      "\nUrl=U\n"
312                      "CaptchaUrl=C\n", "E", "U", "C", "T");
313}
314
315
316TEST_F(GaiaAuthFetcherTest, OnlineLogin) {
317  std::string data("SID=sid\nLSID=lsid\nAuth=auth\n");
318
319  GaiaAuthConsumer::ClientLoginResult result;
320  result.lsid = "lsid";
321  result.sid = "sid";
322  result.token = "auth";
323  result.data = data;
324
325  MockGaiaConsumer consumer;
326  EXPECT_CALL(consumer, OnClientLoginSuccess(result))
327      .Times(1);
328
329  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
330  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
331  MockFetcher mock_fetcher(
332      client_login_source_, status, net::HTTP_OK, cookies_, data,
333      net::URLFetcher::GET, &auth);
334  auth.OnURLFetchComplete(&mock_fetcher);
335}
336
337TEST_F(GaiaAuthFetcherTest, WorkingIssueAuthToken) {
338  MockGaiaConsumer consumer;
339  EXPECT_CALL(consumer, OnIssueAuthTokenSuccess(_, "token"))
340      .Times(1);
341
342  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
343  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
344  MockFetcher mock_fetcher(
345      issue_auth_token_source_, status, net::HTTP_OK, cookies_, "token",
346      net::URLFetcher::GET, &auth);
347  auth.OnURLFetchComplete(&mock_fetcher);
348}
349
350TEST_F(GaiaAuthFetcherTest, CheckTwoFactorResponse) {
351  std::string response =
352      base::StringPrintf("Error=BadAuthentication\n%s\n",
353                         GaiaAuthFetcher::kSecondFactor);
354  EXPECT_TRUE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
355}
356
357TEST_F(GaiaAuthFetcherTest, CheckNormalErrorCode) {
358  std::string response = "Error=BadAuthentication\n";
359  EXPECT_FALSE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
360}
361
362TEST_F(GaiaAuthFetcherTest, TwoFactorLogin) {
363  std::string response = base::StringPrintf("Error=BadAuthentication\n%s\n",
364      GaiaAuthFetcher::kSecondFactor);
365
366  GoogleServiceAuthError error =
367      GoogleServiceAuthError(GoogleServiceAuthError::TWO_FACTOR);
368
369  MockGaiaConsumer consumer;
370  EXPECT_CALL(consumer, OnClientLoginFailure(error))
371      .Times(1);
372
373  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
374  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
375  MockFetcher mock_fetcher(
376      client_login_source_, status, net::HTTP_FORBIDDEN, cookies_, response,
377      net::URLFetcher::GET, &auth);
378  auth.OnURLFetchComplete(&mock_fetcher);
379}
380
381TEST_F(GaiaAuthFetcherTest, CaptchaParse) {
382  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
383  std::string data = "Url=http://www.google.com/login/captcha\n"
384                     "Error=CaptchaRequired\n"
385                     "CaptchaToken=CCTOKEN\n"
386                     "CaptchaUrl=Captcha?ctoken=CCTOKEN\n";
387  GoogleServiceAuthError error =
388      GaiaAuthFetcher::GenerateAuthError(data, status);
389
390  std::string token = "CCTOKEN";
391  GURL image_url("http://accounts.google.com/Captcha?ctoken=CCTOKEN");
392  GURL unlock_url("http://www.google.com/login/captcha");
393
394  EXPECT_EQ(error.state(), GoogleServiceAuthError::CAPTCHA_REQUIRED);
395  EXPECT_EQ(error.captcha().token, token);
396  EXPECT_EQ(error.captcha().image_url, image_url);
397  EXPECT_EQ(error.captcha().unlock_url, unlock_url);
398}
399
400TEST_F(GaiaAuthFetcherTest, AccountDeletedError) {
401  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
402  std::string data = "Error=AccountDeleted\n";
403  GoogleServiceAuthError error =
404      GaiaAuthFetcher::GenerateAuthError(data, status);
405  EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DELETED);
406}
407
408TEST_F(GaiaAuthFetcherTest, AccountDisabledError) {
409  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
410  std::string data = "Error=AccountDisabled\n";
411  GoogleServiceAuthError error =
412      GaiaAuthFetcher::GenerateAuthError(data, status);
413  EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DISABLED);
414}
415
416TEST_F(GaiaAuthFetcherTest,BadAuthenticationError) {
417  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
418  std::string data = "Error=BadAuthentication\n";
419  GoogleServiceAuthError error =
420      GaiaAuthFetcher::GenerateAuthError(data, status);
421  EXPECT_EQ(error.state(), GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
422}
423
424TEST_F(GaiaAuthFetcherTest,IncomprehensibleError) {
425  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
426  std::string data = "Error=Gobbledygook\n";
427  GoogleServiceAuthError error =
428      GaiaAuthFetcher::GenerateAuthError(data, status);
429  EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
430}
431
432TEST_F(GaiaAuthFetcherTest,ServiceUnavailableError) {
433  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
434  std::string data = "Error=ServiceUnavailable\n";
435  GoogleServiceAuthError error =
436      GaiaAuthFetcher::GenerateOAuthLoginError(data, status);
437  EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
438}
439
440TEST_F(GaiaAuthFetcherTest, OAuthAccountDeletedError) {
441  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
442  std::string data = "Error=adel\n";
443  GoogleServiceAuthError error =
444      GaiaAuthFetcher::GenerateOAuthLoginError(data, status);
445  EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DELETED);
446}
447
448TEST_F(GaiaAuthFetcherTest, OAuthAccountDisabledError) {
449  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
450  std::string data = "Error=adis\n";
451  GoogleServiceAuthError error =
452      GaiaAuthFetcher::GenerateOAuthLoginError(data, status);
453  EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DISABLED);
454}
455
456TEST_F(GaiaAuthFetcherTest, OAuthBadAuthenticationError) {
457  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
458  std::string data = "Error=badauth\n";
459  GoogleServiceAuthError error =
460      GaiaAuthFetcher::GenerateOAuthLoginError(data, status);
461  EXPECT_EQ(error.state(), GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
462}
463
464TEST_F(GaiaAuthFetcherTest, OAuthServiceUnavailableError) {
465  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
466  std::string data = "Error=ire\n";
467  GoogleServiceAuthError error =
468      GaiaAuthFetcher::GenerateOAuthLoginError(data, status);
469  EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
470}
471
472TEST_F(GaiaAuthFetcherTest, FullLogin) {
473  MockGaiaConsumer consumer;
474  EXPECT_CALL(consumer, OnClientLoginSuccess(_))
475      .Times(1);
476
477  MockURLFetcherFactory<MockFetcher> factory;
478
479  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
480  auth.StartClientLogin("username",
481                        "password",
482                        "service",
483                        std::string(),
484                        std::string(),
485                        GaiaAuthFetcher::HostedAccountsAllowed);
486}
487
488TEST_F(GaiaAuthFetcherTest, FullLoginFailure) {
489  MockGaiaConsumer consumer;
490  EXPECT_CALL(consumer, OnClientLoginFailure(_))
491      .Times(1);
492
493  MockURLFetcherFactory<MockFetcher> factory;
494  factory.set_success(false);
495
496  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
497  auth.StartClientLogin("username",
498                        "password",
499                        "service",
500                        std::string(),
501                        std::string(),
502                        GaiaAuthFetcher::HostedAccountsAllowed);
503}
504
505TEST_F(GaiaAuthFetcherTest, ClientFetchPending) {
506  MockGaiaConsumer consumer;
507  EXPECT_CALL(consumer, OnClientLoginSuccess(_))
508      .Times(1);
509
510  net::TestURLFetcherFactory factory;
511
512  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
513  auth.StartClientLogin("username",
514                        "password",
515                        "service",
516                        std::string(),
517                        std::string(),
518                        GaiaAuthFetcher::HostedAccountsAllowed);
519
520  EXPECT_TRUE(auth.HasPendingFetch());
521  MockFetcher mock_fetcher(
522      client_login_source_,
523      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
524      net::HTTP_OK, cookies_, "SID=sid\nLSID=lsid\nAuth=auth\n",
525      net::URLFetcher::GET, &auth);
526  auth.OnURLFetchComplete(&mock_fetcher);
527  EXPECT_FALSE(auth.HasPendingFetch());
528}
529
530TEST_F(GaiaAuthFetcherTest, FullTokenSuccess) {
531  MockGaiaConsumer consumer;
532  EXPECT_CALL(consumer, OnIssueAuthTokenSuccess("service", "token"))
533      .Times(1);
534
535  net::TestURLFetcherFactory factory;
536  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
537  auth.StartIssueAuthToken("sid", "lsid", "service");
538
539  EXPECT_TRUE(auth.HasPendingFetch());
540  MockFetcher mock_fetcher(
541      issue_auth_token_source_,
542      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
543      net::HTTP_OK, cookies_, "token",
544      net::URLFetcher::GET, &auth);
545  auth.OnURLFetchComplete(&mock_fetcher);
546  EXPECT_FALSE(auth.HasPendingFetch());
547}
548
549TEST_F(GaiaAuthFetcherTest, FullTokenFailure) {
550  MockGaiaConsumer consumer;
551  EXPECT_CALL(consumer, OnIssueAuthTokenFailure("service", _))
552      .Times(1);
553
554  net::TestURLFetcherFactory factory;
555
556  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
557  auth.StartIssueAuthToken("sid", "lsid", "service");
558
559  EXPECT_TRUE(auth.HasPendingFetch());
560  MockFetcher mock_fetcher(
561      issue_auth_token_source_,
562      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
563      net::HTTP_FORBIDDEN,
564      cookies_,
565      std::string(),
566      net::URLFetcher::GET,
567      &auth);
568  auth.OnURLFetchComplete(&mock_fetcher);
569  EXPECT_FALSE(auth.HasPendingFetch());
570}
571
572TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenSuccess) {
573  MockGaiaConsumer consumer;
574  EXPECT_CALL(consumer, OnClientOAuthSuccess(
575      GaiaAuthConsumer::ClientOAuthResult("rt1", "at1", 3600))).Times(1);
576
577  net::TestURLFetcherFactory factory;
578  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
579  auth.StartLsoForOAuthLoginTokenExchange("lso_token");
580  net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
581  EXPECT_TRUE(NULL != fetcher);
582  EXPECT_EQ(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES,
583            fetcher->GetLoadFlags());
584
585  net::ResponseCookies cookies;
586  cookies.push_back(kGetAuthCodeValidCookie);
587  EXPECT_TRUE(auth.HasPendingFetch());
588  MockFetcher mock_fetcher1(
589      client_login_to_oauth2_source_,
590      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
591      net::HTTP_OK,
592      cookies,
593      std::string(),
594      net::URLFetcher::POST,
595      &auth);
596  auth.OnURLFetchComplete(&mock_fetcher1);
597  EXPECT_TRUE(auth.HasPendingFetch());
598  MockFetcher mock_fetcher2(
599      oauth2_token_source_,
600      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
601      net::HTTP_OK, cookies_, kGetTokenPairValidResponse,
602      net::URLFetcher::POST, &auth);
603  auth.OnURLFetchComplete(&mock_fetcher2);
604  EXPECT_FALSE(auth.HasPendingFetch());
605}
606
607TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenWithCookies) {
608  MockGaiaConsumer consumer;
609  net::TestURLFetcherFactory factory;
610  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
611  auth.StartCookieForOAuthLoginTokenExchange("0");
612  net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
613  EXPECT_TRUE(NULL != fetcher);
614  EXPECT_EQ(net::LOAD_NORMAL, fetcher->GetLoadFlags());
615}
616
617TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenClientLoginToOAuth2Failure) {
618  MockGaiaConsumer consumer;
619  EXPECT_CALL(consumer, OnClientOAuthFailure(_))
620      .Times(1);
621
622  net::TestURLFetcherFactory factory;
623  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
624  auth.StartLsoForOAuthLoginTokenExchange("lso_token");
625
626  net::ResponseCookies cookies;
627  EXPECT_TRUE(auth.HasPendingFetch());
628  MockFetcher mock_fetcher(
629      client_login_to_oauth2_source_,
630      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
631      net::HTTP_FORBIDDEN,
632      cookies,
633      std::string(),
634      net::URLFetcher::POST,
635      &auth);
636  auth.OnURLFetchComplete(&mock_fetcher);
637  EXPECT_FALSE(auth.HasPendingFetch());
638}
639
640TEST_F(GaiaAuthFetcherTest, OAuthLoginTokenOAuth2TokenPairFailure) {
641  MockGaiaConsumer consumer;
642  EXPECT_CALL(consumer, OnClientOAuthFailure(_))
643      .Times(1);
644
645  net::TestURLFetcherFactory factory;
646  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
647  auth.StartLsoForOAuthLoginTokenExchange("lso_token");
648
649  net::ResponseCookies cookies;
650  cookies.push_back(kGetAuthCodeValidCookie);
651  EXPECT_TRUE(auth.HasPendingFetch());
652  MockFetcher mock_fetcher1(
653      client_login_to_oauth2_source_,
654      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
655      net::HTTP_OK,
656      cookies,
657      std::string(),
658      net::URLFetcher::POST,
659      &auth);
660  auth.OnURLFetchComplete(&mock_fetcher1);
661  EXPECT_TRUE(auth.HasPendingFetch());
662  MockFetcher mock_fetcher2(
663      oauth2_token_source_,
664      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
665      net::HTTP_FORBIDDEN,
666      cookies_,
667      std::string(),
668      net::URLFetcher::POST,
669      &auth);
670  auth.OnURLFetchComplete(&mock_fetcher2);
671  EXPECT_FALSE(auth.HasPendingFetch());
672}
673
674TEST_F(GaiaAuthFetcherTest, MergeSessionSuccess) {
675  MockGaiaConsumer consumer;
676  EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>"))
677      .Times(1);
678
679  net::TestURLFetcherFactory factory;
680
681  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
682  auth.StartMergeSession("myubertoken");
683
684  EXPECT_TRUE(auth.HasPendingFetch());
685  MockFetcher mock_fetcher(
686      merge_session_source_,
687      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
688      net::HTTP_OK, cookies_, "<html></html>", net::URLFetcher::GET,
689      &auth);
690  auth.OnURLFetchComplete(&mock_fetcher);
691  EXPECT_FALSE(auth.HasPendingFetch());
692}
693
694TEST_F(GaiaAuthFetcherTest, MergeSessionSuccessRedirect) {
695  MockGaiaConsumer consumer;
696  EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>"))
697      .Times(1);
698
699  net::TestURLFetcherFactory factory;
700
701  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
702  auth.StartMergeSession("myubertoken");
703
704  // Make sure the fetcher created has the expected flags.  Set its url()
705  // properties to reflect a redirect.
706  net::TestURLFetcher* test_fetcher = factory.GetFetcherByID(0);
707  EXPECT_TRUE(test_fetcher != NULL);
708  EXPECT_TRUE(test_fetcher->GetLoadFlags() == net::LOAD_NORMAL);
709  EXPECT_TRUE(auth.HasPendingFetch());
710
711  GURL final_url("http://www.google.com/CheckCookie");
712  test_fetcher->set_url(final_url);
713  test_fetcher->set_status(
714      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0));
715  test_fetcher->set_response_code(net::HTTP_OK);
716  test_fetcher->set_cookies(cookies_);
717  test_fetcher->SetResponseString("<html></html>");
718
719  auth.OnURLFetchComplete(test_fetcher);
720  EXPECT_FALSE(auth.HasPendingFetch());
721}
722
723TEST_F(GaiaAuthFetcherTest, UberAuthTokenSuccess) {
724  MockGaiaConsumer consumer;
725  EXPECT_CALL(consumer, OnUberAuthTokenSuccess("uberToken"))
726      .Times(1);
727
728  net::TestURLFetcherFactory factory;
729
730  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
731  auth.StartTokenFetchForUberAuthExchange("myAccessToken");
732
733  EXPECT_TRUE(auth.HasPendingFetch());
734  MockFetcher mock_fetcher(
735      uberauth_token_source_,
736      net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0),
737      net::HTTP_OK, cookies_, "uberToken", net::URLFetcher::POST,
738      &auth);
739  auth.OnURLFetchComplete(&mock_fetcher);
740  EXPECT_FALSE(auth.HasPendingFetch());
741}
742
743TEST_F(GaiaAuthFetcherTest, ParseClientLoginToOAuth2Response) {
744  {  // No cookies.
745    std::string auth_code;
746    net::ResponseCookies cookies;
747    EXPECT_FALSE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
748        cookies, &auth_code));
749    EXPECT_EQ("", auth_code);
750  }
751  {  // Few cookies, nothing appropriate.
752    std::string auth_code;
753    net::ResponseCookies cookies;
754    cookies.push_back(kGetAuthCodeCookieNoSecure);
755    cookies.push_back(kGetAuthCodeCookieNoHttpOnly);
756    cookies.push_back(kGetAuthCodeCookieNoOAuthCode);
757    EXPECT_FALSE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
758        cookies, &auth_code));
759    EXPECT_EQ("", auth_code);
760  }
761  {  // Few cookies, one of them is valid.
762    std::string auth_code;
763    net::ResponseCookies cookies;
764    cookies.push_back(kGetAuthCodeCookieNoSecure);
765    cookies.push_back(kGetAuthCodeCookieNoHttpOnly);
766    cookies.push_back(kGetAuthCodeCookieNoOAuthCode);
767    cookies.push_back(kGetAuthCodeValidCookie);
768    EXPECT_TRUE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
769        cookies, &auth_code));
770    EXPECT_EQ("test-code", auth_code);
771  }
772  {  // Single valid cookie (like in real responses).
773    std::string auth_code;
774    net::ResponseCookies cookies;
775    cookies.push_back(kGetAuthCodeValidCookie);
776    EXPECT_TRUE(GaiaAuthFetcher::ParseClientLoginToOAuth2Response(
777        cookies, &auth_code));
778    EXPECT_EQ("test-code", auth_code);
779  }
780}
781
782TEST_F(GaiaAuthFetcherTest, StartOAuthLogin) {
783  // OAuthLogin returns the same as the ClientLogin endpoint, minus CAPTCHA
784  // responses.
785  std::string data("SID=sid\nLSID=lsid\nAuth=auth\n");
786
787  GaiaAuthConsumer::ClientLoginResult result;
788  result.lsid = "lsid";
789  result.sid = "sid";
790  result.token = "auth";
791  result.data = data;
792
793  MockGaiaConsumer consumer;
794  EXPECT_CALL(consumer, OnClientLoginSuccess(result))
795      .Times(1);
796
797  GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
798  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
799  MockFetcher mock_fetcher(
800      oauth_login_gurl_, status, net::HTTP_OK, cookies_, data,
801      net::URLFetcher::GET, &auth);
802  auth.OnURLFetchComplete(&mock_fetcher);
803}
804