[Cleanup] Used scoped pointers in KeyedServiceFactory's SetTestingFactory functions.
[chromium-blink-merge.git] / chrome / browser / signin / signin_manager_unittest.cc
blobbd5fb3e7953c699c59c55bb0064a7c77216ead3f
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.
5 #include "components/signin/core/browser/signin_manager.h"
7 #include <vector>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/compiler_specific.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/prefs/testing_pref_service.h"
15 #include "base/run_loop.h"
16 #include "base/strings/stringprintf.h"
17 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/chrome_notification_types.h"
19 #include "chrome/browser/prefs/browser_prefs.h"
20 #include "chrome/browser/signin/account_tracker_service_factory.h"
21 #include "chrome/browser/signin/chrome_signin_client_factory.h"
22 #include "chrome/browser/signin/fake_account_tracker_service.h"
23 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
24 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
25 #include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
26 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
27 #include "chrome/browser/signin/signin_manager_factory.h"
28 #include "chrome/browser/signin/test_signin_client_builder.h"
29 #include "chrome/common/pref_names.h"
30 #include "chrome/common/url_constants.h"
31 #include "chrome/test/base/testing_browser_process.h"
32 #include "chrome/test/base/testing_profile.h"
33 #include "components/signin/core/browser/account_tracker_service.h"
34 #include "components/signin/core/browser/profile_oauth2_token_service.h"
35 #include "components/signin/core/browser/test_signin_client.h"
36 #include "content/public/browser/child_process_security_policy.h"
37 #include "content/public/browser/notification_source.h"
38 #include "content/public/test/test_browser_thread_bundle.h"
39 #include "google_apis/gaia/gaia_constants.h"
40 #include "google_apis/gaia/gaia_urls.h"
41 #include "net/cookies/cookie_monster.h"
42 #include "net/url_request/test_url_fetcher_factory.h"
43 #include "net/url_request/url_request.h"
44 #include "net/url_request/url_request_context_getter.h"
45 #include "net/url_request/url_request_status.h"
47 #include "testing/gmock/include/gmock/gmock.h"
48 #include "testing/gtest/include/gtest/gtest.h"
50 namespace {
52 scoped_ptr<KeyedService> SigninManagerBuild(content::BrowserContext* context) {
53 Profile* profile = static_cast<Profile*>(context);
54 scoped_ptr<SigninManager> service(new SigninManager(
55 ChromeSigninClientFactory::GetInstance()->GetForProfile(profile),
56 ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
57 AccountTrackerServiceFactory::GetForProfile(profile),
58 GaiaCookieManagerServiceFactory::GetForProfile(profile)));
59 service->Initialize(NULL);
60 return service.Pass();
63 class TestSigninManagerObserver : public SigninManagerBase::Observer {
64 public:
65 TestSigninManagerObserver() : num_failed_signins_(0),
66 num_successful_signins_(0),
67 num_signouts_(0) {
70 ~TestSigninManagerObserver() override {}
72 int num_failed_signins_;
73 int num_successful_signins_;
74 int num_signouts_;
76 private:
77 // SigninManagerBase::Observer:
78 void GoogleSigninFailed(const GoogleServiceAuthError& error) override {
79 num_failed_signins_++;
82 void GoogleSigninSucceeded(const std::string& account_id,
83 const std::string& username,
84 const std::string& password) override {
85 num_successful_signins_++;
88 void GoogleSignedOut(const std::string& account_id,
89 const std::string& username) override {
90 num_signouts_++;
94 } // namespace
97 class SigninManagerTest : public testing::Test {
98 public:
99 SigninManagerTest() : manager_(NULL) {}
100 ~SigninManagerTest() override {}
102 void SetUp() override {
103 manager_ = NULL;
104 prefs_.reset(new TestingPrefServiceSimple);
105 chrome::RegisterLocalState(prefs_->registry());
106 TestingBrowserProcess::GetGlobal()->SetLocalState(
107 prefs_.get());
108 TestingProfile::Builder builder;
109 builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
110 BuildFakeProfileOAuth2TokenService);
111 builder.AddTestingFactory(ChromeSigninClientFactory::GetInstance(),
112 signin::BuildTestSigninClient);
113 builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
114 SigninManagerBuild);
115 builder.AddTestingFactory(AccountTrackerServiceFactory::GetInstance(),
116 FakeAccountTrackerService::Build);
117 profile_ = builder.Build();
119 TestSigninClient* client =
120 static_cast<TestSigninClient*>(
121 ChromeSigninClientFactory::GetForProfile(profile()));
122 client->SetURLRequestContext(profile_->GetRequestContext());
125 void TearDown() override {
126 if (manager_)
127 manager_->RemoveObserver(&test_observer_);
129 // Destroy the SigninManager here, because it relies on profile() which is
130 // freed in the base class.
131 if (naked_manager_) {
132 naked_manager_->Shutdown();
133 naked_manager_.reset(NULL);
135 TestingBrowserProcess::GetGlobal()->SetLocalState(NULL);
137 // Manually destroy PrefService and Profile so that they are shutdown
138 // in the correct order. Both need to be destroyed before the
139 // |thread_bundle_| member.
140 profile_.reset();
141 prefs_.reset(); // LocalState needs to outlive the profile.
144 TestingProfile* profile() { return profile_.get(); }
146 TestSigninClient* signin_client() {
147 return static_cast<TestSigninClient*>(
148 ChromeSigninClientFactory::GetInstance()->GetForProfile(profile()));
151 // Seed the account tracker with information from logged in user. Normally
152 // this is done by UI code before calling SigninManager. Returns the string
153 // to use as the account_id.
154 std::string AddToAccountTracker(const std::string& gaia_id,
155 const std::string& email) {
156 AccountTrackerService* service =
157 AccountTrackerServiceFactory::GetForProfile(profile());
158 service->SeedAccountInfo(gaia_id, email);
159 return service->PickAccountIdForAccount(gaia_id, email);
162 // Sets up the signin manager as a service if other code will try to get it as
163 // a PKS.
164 void SetUpSigninManagerAsService() {
165 DCHECK(!manager_);
166 DCHECK(!naked_manager_);
167 manager_ = static_cast<SigninManager*>(
168 SigninManagerFactory::GetForProfile(profile()));
169 manager_->AddObserver(&test_observer_);
172 // Create a naked signin manager if integration with PKSs is not needed.
173 void CreateNakedSigninManager() {
174 DCHECK(!manager_);
175 naked_manager_.reset(new SigninManager(
176 ChromeSigninClientFactory::GetInstance()->GetForProfile(profile()),
177 ProfileOAuth2TokenServiceFactory::GetForProfile(profile()),
178 AccountTrackerServiceFactory::GetForProfile(profile()),
179 GaiaCookieManagerServiceFactory::GetForProfile(profile())));
181 manager_ = naked_manager_.get();
182 manager_->AddObserver(&test_observer_);
185 // Shuts down |manager_|.
186 void ShutDownManager() {
187 DCHECK(manager_);
188 manager_->RemoveObserver(&test_observer_);
189 manager_->Shutdown();
190 if (naked_manager_)
191 naked_manager_.reset(NULL);
192 manager_ = NULL;
195 void ExpectSignInWithRefreshTokenSuccess() {
196 EXPECT_TRUE(manager_->IsAuthenticated());
197 EXPECT_FALSE(manager_->GetAuthenticatedAccountId().empty());
198 EXPECT_FALSE(manager_->GetAuthenticatedUsername().empty());
200 ProfileOAuth2TokenService* token_service =
201 ProfileOAuth2TokenServiceFactory::GetForProfile(profile());
202 EXPECT_TRUE(token_service->RefreshTokenIsAvailable(
203 manager_->GetAuthenticatedAccountId()));
205 // Should go into token service and stop.
206 EXPECT_EQ(1, test_observer_.num_successful_signins_);
207 EXPECT_EQ(0, test_observer_.num_failed_signins_);
210 void CompleteSigninCallback(const std::string& oauth_token) {
211 oauth_tokens_fetched_.push_back(oauth_token);
212 manager_->CompletePendingSignin();
215 content::TestBrowserThreadBundle thread_bundle_;
216 net::TestURLFetcherFactory factory_;
217 scoped_ptr<SigninManager> naked_manager_;
218 SigninManager* manager_;
219 TestSigninManagerObserver test_observer_;
220 scoped_ptr<TestingProfile> profile_;
221 std::vector<std::string> oauth_tokens_fetched_;
222 scoped_ptr<TestingPrefServiceSimple> prefs_;
223 std::vector<std::string> cookies_;
226 TEST_F(SigninManagerTest, SignInWithRefreshToken) {
227 SetUpSigninManagerAsService();
228 EXPECT_FALSE(manager_->IsAuthenticated());
230 std::string account_id = AddToAccountTracker("gaia_id", "user@gmail.com");
231 manager_->StartSignInWithRefreshToken(
232 "rt",
233 "gaia_id",
234 "user@gmail.com",
235 "password",
236 SigninManager::OAuthTokenFetchedCallback());
238 ExpectSignInWithRefreshTokenSuccess();
240 // Should persist across resets.
241 ShutDownManager();
242 CreateNakedSigninManager();
243 manager_->Initialize(NULL);
244 EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId());
247 TEST_F(SigninManagerTest, SignInWithRefreshTokenCallbackComplete) {
248 SetUpSigninManagerAsService();
249 EXPECT_FALSE(manager_->IsAuthenticated());
251 // Since the password is empty, must verify the gaia cookies first.
252 SigninManager::OAuthTokenFetchedCallback callback =
253 base::Bind(&SigninManagerTest::CompleteSigninCallback,
254 base::Unretained(this));
255 manager_->StartSignInWithRefreshToken(
256 "rt",
257 "gaia_id",
258 "user@gmail.com",
259 "password",
260 callback);
262 ExpectSignInWithRefreshTokenSuccess();
263 ASSERT_EQ(1U, oauth_tokens_fetched_.size());
264 EXPECT_EQ(oauth_tokens_fetched_[0], "rt");
267 TEST_F(SigninManagerTest, SignInWithRefreshTokenCallsPostSignout) {
268 SetUpSigninManagerAsService();
269 EXPECT_FALSE(manager_->IsAuthenticated());
271 std::string gaia_id = "12345";
272 std::string email = "user@google.com";
274 FakeAccountTrackerService* account_tracker_service =
275 static_cast<FakeAccountTrackerService*>(
276 AccountTrackerServiceFactory::GetForProfile(profile()));
277 account_tracker_service->SeedAccountInfo(gaia_id, email);
278 account_tracker_service->EnableNetworkFetches();
280 ASSERT_TRUE(signin_client()->get_signed_in_password().empty());
282 manager_->StartSignInWithRefreshToken(
283 "rt1",
284 gaia_id,
285 email,
286 "password",
287 SigninManager::OAuthTokenFetchedCallback());
289 // PostSignedIn is not called until the AccountTrackerService returns.
290 ASSERT_EQ("", signin_client()->get_signed_in_password());
292 account_tracker_service->FakeUserInfoFetchSuccess(email,
293 gaia_id,
294 "google.com",
295 "full_name",
296 "given_name",
297 "locale",
298 "http://www.google.com");
300 // AccountTracker and SigninManager are both done and PostSignedIn was called.
301 ASSERT_EQ("password", signin_client()->get_signed_in_password());
303 ExpectSignInWithRefreshTokenSuccess();
307 TEST_F(SigninManagerTest, SignOut) {
308 SetUpSigninManagerAsService();
309 manager_->StartSignInWithRefreshToken(
310 "rt",
311 "gaia_id",
312 "user@gmail.com",
313 "password",
314 SigninManager::OAuthTokenFetchedCallback());
315 manager_->SignOut(signin_metrics::SIGNOUT_TEST);
316 EXPECT_FALSE(manager_->IsAuthenticated());
317 EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty());
318 EXPECT_TRUE(manager_->GetAuthenticatedAccountId().empty());
319 // Should not be persisted anymore
320 ShutDownManager();
321 CreateNakedSigninManager();
322 manager_->Initialize(NULL);
323 EXPECT_FALSE(manager_->IsAuthenticated());
324 EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty());
325 EXPECT_TRUE(manager_->GetAuthenticatedAccountId().empty());
328 TEST_F(SigninManagerTest, SignOutWhileProhibited) {
329 SetUpSigninManagerAsService();
330 EXPECT_FALSE(manager_->IsAuthenticated());
331 EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty());
332 EXPECT_TRUE(manager_->GetAuthenticatedAccountId().empty());
334 manager_->SetAuthenticatedAccountInfo("gaia_id", "user@gmail.com");
335 manager_->ProhibitSignout(true);
336 manager_->SignOut(signin_metrics::SIGNOUT_TEST);
337 EXPECT_TRUE(manager_->IsAuthenticated());
338 manager_->ProhibitSignout(false);
339 manager_->SignOut(signin_metrics::SIGNOUT_TEST);
340 EXPECT_FALSE(manager_->IsAuthenticated());
343 TEST_F(SigninManagerTest, Prohibited) {
344 g_browser_process->local_state()->SetString(
345 prefs::kGoogleServicesUsernamePattern, ".*@google.com");
346 CreateNakedSigninManager();
347 manager_->Initialize(g_browser_process->local_state());
348 EXPECT_TRUE(manager_->IsAllowedUsername("test@google.com"));
349 EXPECT_TRUE(manager_->IsAllowedUsername("happy@google.com"));
350 EXPECT_FALSE(manager_->IsAllowedUsername("test@invalid.com"));
351 EXPECT_FALSE(manager_->IsAllowedUsername("test@notgoogle.com"));
352 EXPECT_FALSE(manager_->IsAllowedUsername(std::string()));
355 TEST_F(SigninManagerTest, TestAlternateWildcard) {
356 // Test to make sure we accept "*@google.com" as a pattern (treat it as if
357 // the admin entered ".*@google.com").
358 g_browser_process->local_state()->SetString(
359 prefs::kGoogleServicesUsernamePattern, "*@google.com");
360 CreateNakedSigninManager();
361 manager_->Initialize(g_browser_process->local_state());
362 EXPECT_TRUE(manager_->IsAllowedUsername("test@google.com"));
363 EXPECT_TRUE(manager_->IsAllowedUsername("happy@google.com"));
364 EXPECT_FALSE(manager_->IsAllowedUsername("test@invalid.com"));
365 EXPECT_FALSE(manager_->IsAllowedUsername("test@notgoogle.com"));
366 EXPECT_FALSE(manager_->IsAllowedUsername(std::string()));
369 TEST_F(SigninManagerTest, ProhibitedAtStartup) {
370 std::string account_id = AddToAccountTracker("gaia_id", "user@gmail.com");
371 profile()->GetPrefs()->SetString(prefs::kGoogleServicesAccountId, account_id);
372 g_browser_process->local_state()->SetString(
373 prefs::kGoogleServicesUsernamePattern, ".*@google.com");
374 CreateNakedSigninManager();
375 manager_->Initialize(g_browser_process->local_state());
376 // Currently signed in user is prohibited by policy, so should be signed out.
377 EXPECT_EQ("", manager_->GetAuthenticatedUsername());
378 EXPECT_EQ("", manager_->GetAuthenticatedAccountId());
381 TEST_F(SigninManagerTest, ProhibitedAfterStartup) {
382 std::string account_id = AddToAccountTracker("gaia_id", "user@gmail.com");
383 profile()->GetPrefs()->SetString(prefs::kGoogleServicesAccountId, account_id);
384 CreateNakedSigninManager();
385 manager_->Initialize(g_browser_process->local_state());
386 EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedUsername());
387 EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId());
388 // Update the profile - user should be signed out.
389 g_browser_process->local_state()->SetString(
390 prefs::kGoogleServicesUsernamePattern, ".*@google.com");
391 EXPECT_EQ("", manager_->GetAuthenticatedUsername());
392 EXPECT_EQ("", manager_->GetAuthenticatedAccountId());
395 TEST_F(SigninManagerTest, ExternalSignIn) {
396 CreateNakedSigninManager();
397 manager_->Initialize(g_browser_process->local_state());
398 EXPECT_EQ("", manager_->GetAuthenticatedUsername());
399 EXPECT_EQ("", manager_->GetAuthenticatedAccountId());
400 EXPECT_EQ(0, test_observer_.num_successful_signins_);
402 std::string account_id = AddToAccountTracker("gaia_id", "user@gmail.com");
403 manager_->OnExternalSigninCompleted(account_id);
404 EXPECT_EQ(1, test_observer_.num_successful_signins_);
405 EXPECT_EQ(0, test_observer_.num_failed_signins_);
406 EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedUsername());
407 EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId());
410 TEST_F(SigninManagerTest, SigninNotAllowed) {
411 std::string user("user@google.com");
412 profile()->GetPrefs()->SetString(prefs::kGoogleServicesAccountId, user);
413 profile()->GetPrefs()->SetBoolean(prefs::kSigninAllowed, false);
414 CreateNakedSigninManager();
415 AddToAccountTracker("gaia_id", user);
416 manager_->Initialize(g_browser_process->local_state());
417 // Currently signing in is prohibited by policy, so should be signed out.
418 EXPECT_EQ("", manager_->GetAuthenticatedUsername());
419 EXPECT_EQ("", manager_->GetAuthenticatedAccountId());
422 TEST_F(SigninManagerTest, UpgradeToNewPrefs) {
423 profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
424 "user@gmail.com");
425 profile()->GetPrefs()->SetString(prefs::kGoogleServicesUserAccountId,
426 "account_id");
427 CreateNakedSigninManager();
428 manager_->Initialize(g_browser_process->local_state());
429 EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedUsername());
431 // TODO(rogerta): until the migration to gaia id, the account id will remain
432 // the old username.
433 EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedAccountId());
434 EXPECT_EQ("user@gmail.com",
435 profile()->GetPrefs()->GetString(prefs::kGoogleServicesAccountId));
436 EXPECT_EQ("",
437 profile()->GetPrefs()->GetString(prefs::kGoogleServicesUsername));
439 // Make sure account tracker was updated.
440 AccountTrackerService* service =
441 AccountTrackerServiceFactory::GetForProfile(profile());
442 AccountTrackerService::AccountInfo info = service->GetAccountInfo(
443 manager_->GetAuthenticatedAccountId());
444 EXPECT_EQ("user@gmail.com", info.email);
445 EXPECT_EQ("account_id", info.gaia);
448 TEST_F(SigninManagerTest, CanonicalizesPrefs) {
449 profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
450 "user.C@gmail.com");
451 CreateNakedSigninManager();
452 manager_->Initialize(g_browser_process->local_state());
453 EXPECT_EQ("user.C@gmail.com", manager_->GetAuthenticatedUsername());
455 // TODO(rogerta): until the migration to gaia id, the account id will remain
456 // the old username.
457 EXPECT_EQ("userc@gmail.com", manager_->GetAuthenticatedAccountId());
458 EXPECT_EQ("userc@gmail.com",
459 profile()->GetPrefs()->GetString(prefs::kGoogleServicesAccountId));
460 EXPECT_EQ("",
461 profile()->GetPrefs()->GetString(prefs::kGoogleServicesUsername));
463 // Make sure account tracker has a canonicalized username.
464 AccountTrackerService* service =
465 AccountTrackerServiceFactory::GetForProfile(profile());
466 AccountTrackerService::AccountInfo info = service->GetAccountInfo(
467 manager_->GetAuthenticatedAccountId());
468 EXPECT_EQ("user.C@gmail.com", info.email);
469 EXPECT_EQ("userc@gmail.com", info.account_id);