1 // Copyright (c) 2013 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 "chrome/browser/signin/signin_global_error.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/prefs/pref_service.h"
9 #include "chrome/browser/signin/fake_auth_status_provider.h"
10 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
11 #include "chrome/browser/signin/fake_profile_oauth2_token_service_wrapper.h"
12 #include "chrome/browser/signin/fake_signin_manager.h"
13 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
14 #include "chrome/browser/signin/signin_manager.h"
15 #include "chrome/browser/signin/signin_manager_factory.h"
16 #include "chrome/browser/ui/global_error/global_error_service.h"
17 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 static const char kTestAccountId[] = "testuser@test.com";
24 static const char kOtherTestAccountId[] = "otheruser@test.com";
26 class SigninGlobalErrorTest : public testing::Test {
28 virtual void SetUp() OVERRIDE {
29 // Create a signed-in profile.
30 TestingProfile::Builder builder;
31 builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
32 FakeProfileOAuth2TokenServiceWrapper::Build);
33 builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
34 FakeSigninManagerBase::Build);
35 profile_ = builder.Build();
36 SigninManagerFactory::GetForProfile(profile_.get());
37 profile_->GetPrefs()->SetString(
38 prefs::kGoogleServicesUsername, kTestAccountId);
39 SigninManagerFactory::GetForProfile(profile_.get())
40 ->SetAuthenticatedUsername(kTestAccountId);
41 global_error_ = SigninGlobalError::GetForProfile(profile_.get());
44 content::TestBrowserThreadBundle thread_bundle_;
45 scoped_ptr<TestingProfile> profile_;
46 SigninGlobalError* global_error_;
49 TEST_F(SigninGlobalErrorTest, NoAuthStatusProviders) {
50 ASSERT_FALSE(global_error_->HasMenuItem());
53 TEST_F(SigninGlobalErrorTest, NoErrorAuthStatusProviders) {
55 // Add a provider (removes itself on exiting this scope).
56 FakeAuthStatusProvider provider(global_error_);
57 ASSERT_FALSE(global_error_->HasMenuItem());
59 ASSERT_FALSE(global_error_->HasMenuItem());
62 TEST_F(SigninGlobalErrorTest, ErrorAuthStatusProvider) {
64 FakeAuthStatusProvider provider(global_error_);
65 ASSERT_FALSE(global_error_->HasMenuItem());
67 FakeAuthStatusProvider error_provider(global_error_);
68 error_provider.SetAuthError(kTestAccountId, GoogleServiceAuthError(
69 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
70 ASSERT_TRUE(global_error_->HasMenuItem());
72 // error_provider is removed now that we've left that scope.
73 ASSERT_FALSE(global_error_->HasMenuItem());
75 // All providers should be removed now.
76 ASSERT_FALSE(global_error_->HasMenuItem());
79 TEST_F(SigninGlobalErrorTest, AuthStatusProviderErrorTransition) {
81 FakeAuthStatusProvider provider0(global_error_);
82 FakeAuthStatusProvider provider1(global_error_);
83 ASSERT_FALSE(global_error_->HasMenuItem());
84 provider0.SetAuthError(
86 GoogleServiceAuthError(
87 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
88 ASSERT_TRUE(global_error_->HasMenuItem());
89 provider1.SetAuthError(
91 GoogleServiceAuthError(GoogleServiceAuthError::ACCOUNT_DISABLED));
92 ASSERT_TRUE(global_error_->HasMenuItem());
94 // Now resolve the auth errors - the menu item should go away.
95 provider0.SetAuthError(kTestAccountId,
96 GoogleServiceAuthError::AuthErrorNone());
97 ASSERT_TRUE(global_error_->HasMenuItem());
98 provider1.SetAuthError(kTestAccountId,
99 GoogleServiceAuthError::AuthErrorNone());
100 ASSERT_FALSE(global_error_->HasMenuItem());
102 ASSERT_FALSE(global_error_->HasMenuItem());
105 TEST_F(SigninGlobalErrorTest, AuthStatusProviderAccountTransition) {
107 FakeAuthStatusProvider provider0(global_error_);
108 FakeAuthStatusProvider provider1(global_error_);
109 ASSERT_FALSE(global_error_->HasMenuItem());
111 provider0.SetAuthError(
113 GoogleServiceAuthError(
114 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
115 provider1.SetAuthError(
117 GoogleServiceAuthError(GoogleServiceAuthError::NONE));
118 ASSERT_TRUE(global_error_->HasMenuItem());
119 ASSERT_STREQ(kTestAccountId,
120 global_error_->GetAccountIdOfLastAuthError().c_str());
122 // Swap providers reporting errors.
123 provider1.set_error_without_status_change(
124 GoogleServiceAuthError(
125 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
126 provider0.set_error_without_status_change(
127 GoogleServiceAuthError(GoogleServiceAuthError::NONE));
128 global_error_->AuthStatusChanged();
129 ASSERT_TRUE(global_error_->HasMenuItem());
130 ASSERT_STREQ(kOtherTestAccountId,
131 global_error_->GetAccountIdOfLastAuthError().c_str());
133 // Now resolve the auth errors - the menu item should go away.
134 provider0.set_error_without_status_change(
135 GoogleServiceAuthError::AuthErrorNone());
136 provider1.set_error_without_status_change(
137 GoogleServiceAuthError::AuthErrorNone());
138 global_error_->AuthStatusChanged();
139 ASSERT_FALSE(global_error_->HasMenuItem());
141 ASSERT_FALSE(global_error_->HasMenuItem());
144 // Verify that SigninGlobalError ignores certain errors.
145 TEST_F(SigninGlobalErrorTest, AuthStatusEnumerateAllErrors) {
147 GoogleServiceAuthError::State error_state;
151 ErrorTableEntry table[] = {
152 { GoogleServiceAuthError::NONE, false },
153 { GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, true },
154 { GoogleServiceAuthError::USER_NOT_SIGNED_UP, true },
155 { GoogleServiceAuthError::CONNECTION_FAILED, false },
156 { GoogleServiceAuthError::CAPTCHA_REQUIRED, true },
157 { GoogleServiceAuthError::ACCOUNT_DELETED, true },
158 { GoogleServiceAuthError::ACCOUNT_DISABLED, true },
159 { GoogleServiceAuthError::SERVICE_UNAVAILABLE, true },
160 { GoogleServiceAuthError::TWO_FACTOR, true },
161 { GoogleServiceAuthError::REQUEST_CANCELED, true },
162 { GoogleServiceAuthError::HOSTED_NOT_ALLOWED, true },
163 { GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE, true },
164 { GoogleServiceAuthError::SERVICE_ERROR, true },
166 COMPILE_ASSERT(ARRAYSIZE_UNSAFE(table) == GoogleServiceAuthError::NUM_STATES,
167 kTable_size_does_not_match_number_of_auth_error_types);
169 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(table); ++i) {
170 FakeAuthStatusProvider provider(global_error_);
171 provider.SetAuthError(kTestAccountId,
172 GoogleServiceAuthError(table[i].error_state));
173 EXPECT_EQ(global_error_->HasMenuItem(), table[i].is_error);
174 // Only on chromeos do we have a separate menu item - on other platforms
175 // there's code in WrenchMenuModel to re-use the "sign in to chrome"
176 // menu item to display auth status/errors.
177 EXPECT_EQ(global_error_->HasMenuItem(), table[i].is_error);
178 EXPECT_EQ(global_error_->MenuItemLabel().empty(), !table[i].is_error);
179 EXPECT_EQ(global_error_->GetBubbleViewMessages().empty(),
181 EXPECT_FALSE(global_error_->GetBubbleViewTitle().empty());
182 EXPECT_FALSE(global_error_->GetBubbleViewAcceptButtonLabel().empty());
183 EXPECT_TRUE(global_error_->GetBubbleViewCancelButtonLabel().empty());