// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include "base/bind.h" #include "base/memory/ref_counted.h" #include "base/run_loop.h" #include "chrome/browser/chromeos/login/auth_attempt_state.h" #include "chrome/browser/chromeos/login/mock_auth_attempt_state_resolver.h" #include "chrome/browser/chromeos/login/mock_url_fetchers.h" #include "chrome/browser/chromeos/login/online_attempt.h" #include "chrome/browser/chromeos/login/test_attempt_state.h" #include "chrome/browser/chromeos/login/user.h" #include "chrome/test/base/testing_profile.h" #include "content/public/browser/browser_thread.h" #include "content/public/test/test_browser_thread_bundle.h" #include "google_apis/gaia/gaia_auth_consumer.h" #include "google_apis/gaia/mock_url_fetcher_factory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" using ::testing::AnyNumber; using ::testing::Invoke; using ::testing::Return; using ::testing::_; using content::BrowserThread; namespace chromeos { class OnlineAttemptTest : public testing::Test { public: OnlineAttemptTest() : state_(UserContext(), "", "", User::USER_TYPE_REGULAR, false), attempt_(new OnlineAttempt(&state_, &resolver_)) { } void RunFailureTest(const GoogleServiceAuthError& error) { EXPECT_CALL(resolver_, Resolve()) .Times(1) .RetiresOnSaturation(); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&OnlineAttempt::OnClientLoginFailure, attempt_->weak_factory_.GetWeakPtr(), error)); // Force UI thread to finish tasks so I can verify |state_|. base::RunLoop().RunUntilIdle(); EXPECT_TRUE(error == state_.online_outcome().error()); } void CancelLogin(OnlineAttempt* auth) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&OnlineAttempt::CancelClientLogin, auth->weak_factory_.GetWeakPtr())); } content::TestBrowserThreadBundle thread_bundle_; TestAttemptState state_; MockAuthAttemptStateResolver resolver_; scoped_ptr attempt_; }; TEST_F(OnlineAttemptTest, LoginSuccess) { EXPECT_CALL(resolver_, Resolve()) .Times(1) .RetiresOnSaturation(); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&OnlineAttempt::OnClientLoginSuccess, attempt_->weak_factory_.GetWeakPtr(), GaiaAuthConsumer::ClientLoginResult())); // Force UI thread to finish tasks so I can verify |state_|. base::RunLoop().RunUntilIdle(); } TEST_F(OnlineAttemptTest, LoginCancelRetry) { GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED); TestingProfile profile; base::RunLoop run_loop; EXPECT_CALL(resolver_, Resolve()) .WillOnce(Invoke(&run_loop, &base::RunLoop::Quit)) .RetiresOnSaturation(); // This is how we inject fake URLFetcher objects, with a factory. // This factory creates fake URLFetchers that Start() a fake fetch attempt // and then come back on the UI thread saying they've been canceled. MockURLFetcherFactory factory; attempt_->Initiate(&profile); run_loop.Run(); EXPECT_TRUE(error == state_.online_outcome().error()); EXPECT_EQ(LoginFailure::NETWORK_AUTH_FAILED, state_.online_outcome().reason()); } TEST_F(OnlineAttemptTest, LoginTimeout) { LoginFailure error(LoginFailure::LOGIN_TIMED_OUT); TestingProfile profile; base::RunLoop run_loop; EXPECT_CALL(resolver_, Resolve()) .WillOnce(Invoke(&run_loop, &base::RunLoop::Quit)) .RetiresOnSaturation(); // This is how we inject fake URLFetcher objects, with a factory. // This factory creates fake URLFetchers that Start() a fake fetch attempt // and then come back on the UI thread saying they've been canceled. MockURLFetcherFactory factory; attempt_->Initiate(&profile); // Post a task to cancel the login attempt. CancelLogin(attempt_.get()); run_loop.Run(); EXPECT_EQ(LoginFailure::LOGIN_TIMED_OUT, state_.online_outcome().reason()); } TEST_F(OnlineAttemptTest, HostedLoginRejected) { LoginFailure error( LoginFailure::FromNetworkAuthFailure( GoogleServiceAuthError( GoogleServiceAuthError::HOSTED_NOT_ALLOWED))); TestingProfile profile; base::RunLoop run_loop; EXPECT_CALL(resolver_, Resolve()) .WillOnce(Invoke(&run_loop, &base::RunLoop::Quit)) .RetiresOnSaturation(); // This is how we inject fake URLFetcher objects, with a factory. MockURLFetcherFactory factory; TestAttemptState local_state(UserContext(), "", "", User::USER_TYPE_REGULAR, true); attempt_.reset(new OnlineAttempt(&local_state, &resolver_)); attempt_->Initiate(&profile); run_loop.Run(); EXPECT_EQ(error, local_state.online_outcome()); EXPECT_EQ(LoginFailure::NETWORK_AUTH_FAILED, local_state.online_outcome().reason()); } TEST_F(OnlineAttemptTest, FullLogin) { TestingProfile profile; base::RunLoop run_loop; EXPECT_CALL(resolver_, Resolve()) .WillOnce(Invoke(&run_loop, &base::RunLoop::Quit)) .RetiresOnSaturation(); // This is how we inject fake URLFetcher objects, with a factory. MockURLFetcherFactory factory; TestAttemptState local_state(UserContext(), "", "", User::USER_TYPE_REGULAR, true); attempt_.reset(new OnlineAttempt(&local_state, &resolver_)); attempt_->Initiate(&profile); run_loop.Run(); EXPECT_EQ(LoginFailure::LoginFailureNone(), local_state.online_outcome()); } TEST_F(OnlineAttemptTest, LoginNetFailure) { RunFailureTest( GoogleServiceAuthError::FromConnectionError(net::ERR_CONNECTION_RESET)); } TEST_F(OnlineAttemptTest, LoginDenied) { RunFailureTest( GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); } TEST_F(OnlineAttemptTest, LoginAccountDisabled) { RunFailureTest( GoogleServiceAuthError(GoogleServiceAuthError::ACCOUNT_DISABLED)); } TEST_F(OnlineAttemptTest, LoginAccountDeleted) { RunFailureTest( GoogleServiceAuthError(GoogleServiceAuthError::ACCOUNT_DELETED)); } TEST_F(OnlineAttemptTest, LoginServiceUnavailable) { RunFailureTest( GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE)); } TEST_F(OnlineAttemptTest, CaptchaErrorOutputted) { GoogleServiceAuthError auth_error = GoogleServiceAuthError::FromClientLoginCaptchaChallenge( "CCTOKEN", GURL("http://accounts.google.com/Captcha?ctoken=CCTOKEN"), GURL("http://www.google.com/login/captcha")); RunFailureTest(auth_error); } TEST_F(OnlineAttemptTest, TwoFactorSuccess) { EXPECT_CALL(resolver_, Resolve()) .Times(1) .RetiresOnSaturation(); GoogleServiceAuthError error(GoogleServiceAuthError::TWO_FACTOR); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&OnlineAttempt::OnClientLoginFailure, attempt_->weak_factory_.GetWeakPtr(), error)); // Force UI thread to finish tasks so I can verify |state_|. base::RunLoop().RunUntilIdle(); EXPECT_TRUE(GoogleServiceAuthError::AuthErrorNone() == state_.online_outcome().error()); } } // namespace chromeos