1 // Copyright 2014 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_error_notifier_ash.h"
7 #include "ash/test/ash_test_base.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/notifications/notification.h"
11 #include "chrome/browser/notifications/notification_ui_manager.h"
12 #include "chrome/browser/signin/fake_signin_manager_builder.h"
13 #include "chrome/browser/signin/signin_error_controller_factory.h"
14 #include "chrome/browser/signin/signin_error_notifier_factory_ash.h"
15 #include "chrome/browser/signin/signin_manager_factory.h"
16 #include "chrome/test/base/testing_browser_process.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "chrome/test/base/testing_profile_manager.h"
19 #include "components/signin/core/browser/fake_auth_status_provider.h"
20 #include "components/signin/core/browser/signin_error_controller.h"
21 #include "components/signin/core/browser/signin_manager.h"
22 #include "content/public/test/test_browser_thread_bundle.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "ui/message_center/notification.h"
27 #include "chrome/browser/ui/ash/ash_util.h"
28 #include "ui/aura/test/test_screen.h"
29 #include "ui/gfx/screen.h"
30 #include "ui/gfx/screen_type_delegate.h"
38 static const char kTestAccountId
[] = "testuser@test.com";
40 // Notification ID corresponding to kProfileSigninNotificationId +
42 static const std::string kNotificationId
=
43 "chrome://settings/signin/testuser@test.com";
47 class ScreenTypeDelegateDesktop
: public gfx::ScreenTypeDelegate
{
49 ScreenTypeDelegateDesktop() {}
50 gfx::ScreenType
GetScreenTypeForNativeView(gfx::NativeView view
) override
{
51 return chrome::IsNativeViewInAsh(view
) ?
52 gfx::SCREEN_TYPE_ALTERNATE
:
53 gfx::SCREEN_TYPE_NATIVE
;
56 DISALLOW_COPY_AND_ASSIGN(ScreenTypeDelegateDesktop
);
60 class SigninErrorNotifierTest
: public AshTestBase
{
62 void SetUp() override
{
63 // Create a signed-in profile.
64 TestingProfile::Builder builder
;
65 builder
.AddTestingFactory(SigninManagerFactory::GetInstance(),
66 BuildFakeSigninManagerBase
);
67 profile_
= builder
.Build();
68 profile_
->set_profile_name(kTestAccountId
);
70 profile_manager_
.reset(
71 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
72 ASSERT_TRUE(profile_manager_
->SetUp());
74 TestingBrowserProcess::GetGlobal();
77 // Set up screen for Windows.
79 test_screen_
.reset(aura::TestScreen::Create(gfx::Size()));
80 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, test_screen_
.get());
81 gfx::Screen::SetScreenTypeDelegate(&screen_type_delegate_
);
84 error_controller_
= SigninErrorControllerFactory::GetForProfile(
86 SigninErrorNotifierFactory::GetForProfile(profile_
.get());
87 notification_ui_manager_
= g_browser_process
->notification_ui_manager();
90 void TearDown() override
{
92 gfx::Screen::SetScreenTypeDelegate(nullptr);
93 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, nullptr);
96 profile_manager_
.reset();
98 AshTestBase::TearDown();
102 void GetMessage(base::string16
* message
) {
103 const Notification
* notification
=
104 g_browser_process
->notification_ui_manager()->FindById(
106 NotificationUIManager::GetProfileID(profile_
.get()));
107 ASSERT_FALSE(notification
== NULL
);
108 *message
= notification
->message();
112 ScreenTypeDelegateDesktop screen_type_delegate_
;
113 scoped_ptr
<gfx::Screen
> test_screen_
;
115 scoped_ptr
<TestingProfileManager
> profile_manager_
;
116 scoped_ptr
<TestingProfile
> profile_
;
117 SigninErrorController
* error_controller_
;
118 NotificationUIManager
* notification_ui_manager_
;
121 TEST_F(SigninErrorNotifierTest
, NoErrorAuthStatusProviders
) {
122 ASSERT_FALSE(notification_ui_manager_
->FindById(
123 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
125 // Add a provider (removes itself on exiting this scope).
126 FakeAuthStatusProvider
provider(error_controller_
);
127 ASSERT_FALSE(notification_ui_manager_
->FindById(
128 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
130 ASSERT_FALSE(notification_ui_manager_
->FindById(
131 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
135 // Disabled on Win due to flake. http://crbug.com/372236
136 TEST_F(SigninErrorNotifierTest
, ErrorAuthStatusProvider
) {
138 FakeAuthStatusProvider
provider(error_controller_
);
139 ASSERT_FALSE(notification_ui_manager_
->FindById(
140 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
142 FakeAuthStatusProvider
error_provider(error_controller_
);
143 error_provider
.SetAuthError(
145 GoogleServiceAuthError(
146 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS
));
147 ASSERT_TRUE(notification_ui_manager_
->FindById(
149 NotificationUIManager::GetProfileID(profile_
.get())));
151 // error_provider is removed now that we've left that scope.
152 ASSERT_FALSE(notification_ui_manager_
->FindById(
153 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
155 // All providers should be removed now.
156 ASSERT_FALSE(notification_ui_manager_
->FindById(
157 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
162 // Test started crashing on Win 7. http://crbug.com/372277
163 #define MAYBE_AuthStatusProviderErrorTransition \
164 DISABLED_AuthStatusProviderErrorTransition
166 #define MAYBE_AuthStatusProviderErrorTransition \
167 AuthStatusProviderErrorTransition
169 TEST_F(SigninErrorNotifierTest
, MAYBE_AuthStatusProviderErrorTransition
) {
171 FakeAuthStatusProvider
provider0(error_controller_
);
172 FakeAuthStatusProvider
provider1(error_controller_
);
173 provider0
.SetAuthError(
175 GoogleServiceAuthError(
176 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS
));
177 ASSERT_TRUE(notification_ui_manager_
->FindById(
178 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
180 base::string16 message
;
181 GetMessage(&message
);
182 ASSERT_FALSE(message
.empty());
184 // Now set another auth error and clear the original.
185 provider1
.SetAuthError(
187 GoogleServiceAuthError(
188 GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE
));
189 provider0
.SetAuthError(
191 GoogleServiceAuthError::AuthErrorNone());
193 ASSERT_TRUE(notification_ui_manager_
->FindById(
194 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
196 base::string16 new_message
;
197 GetMessage(&new_message
);
198 ASSERT_FALSE(new_message
.empty());
200 ASSERT_NE(new_message
, message
);
202 provider1
.SetAuthError(
203 kTestAccountId
, GoogleServiceAuthError::AuthErrorNone());
204 ASSERT_FALSE(notification_ui_manager_
->FindById(
205 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
210 // Disabled on Win due to flake. http://crbug.com/372236
211 // Verify that SigninErrorNotifier ignores certain errors.
212 TEST_F(SigninErrorNotifierTest
, AuthStatusEnumerateAllErrors
) {
214 GoogleServiceAuthError::State error_state
;
218 ErrorTableEntry table
[] = {
219 { GoogleServiceAuthError::NONE
, false },
220 { GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS
, true },
221 { GoogleServiceAuthError::USER_NOT_SIGNED_UP
, true },
222 { GoogleServiceAuthError::CONNECTION_FAILED
, false },
223 { GoogleServiceAuthError::CAPTCHA_REQUIRED
, true },
224 { GoogleServiceAuthError::ACCOUNT_DELETED
, true },
225 { GoogleServiceAuthError::ACCOUNT_DISABLED
, true },
226 { GoogleServiceAuthError::SERVICE_UNAVAILABLE
, true },
227 { GoogleServiceAuthError::TWO_FACTOR
, true },
228 { GoogleServiceAuthError::REQUEST_CANCELED
, true },
229 { GoogleServiceAuthError::HOSTED_NOT_ALLOWED
, true },
230 { GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE
, true },
231 { GoogleServiceAuthError::SERVICE_ERROR
, true },
232 { GoogleServiceAuthError::WEB_LOGIN_REQUIRED
, true },
234 static_assert(arraysize(table
) == GoogleServiceAuthError::NUM_STATES
,
235 "table size should match number of auth error types");
237 for (size_t i
= 0; i
< arraysize(table
); ++i
) {
238 FakeAuthStatusProvider
provider(error_controller_
);
239 provider
.SetAuthError(kTestAccountId
,
240 GoogleServiceAuthError(table
[i
].error_state
));
241 const Notification
* notification
= notification_ui_manager_
->FindById(
242 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get()));
243 ASSERT_EQ(table
[i
].is_error
, notification
!= NULL
);
244 if (table
[i
].is_error
) {
245 EXPECT_FALSE(notification
->title().empty());
246 EXPECT_FALSE(notification
->message().empty());
247 EXPECT_EQ((size_t)1, notification
->buttons().size());