blob: b0ffec6a3c995e2828ecabd8028851037866f6b6 [file] [log] [blame]
// 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 <string>
#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<OnlineAttempt> 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<GotCanceledFetcher> 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<ExpectCanceledFetcher> 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<HostedFetcher> 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<SuccessFetcher> 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