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