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.h"
13 #include "chrome/browser/signin/profile_oauth2_token_service_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/profile_oauth2_token_service.h"
21 #include "components/signin/core/browser/signin_error_controller.h"
22 #include "components/signin/core/browser/signin_manager.h"
23 #include "content/public/test/test_browser_thread_bundle.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "ui/message_center/notification.h"
28 #include "chrome/browser/ui/ash/ash_util.h"
29 #include "ui/aura/test/test_screen.h"
30 #include "ui/gfx/screen.h"
31 #include "ui/gfx/screen_type_delegate.h"
39 static const char kTestAccountId
[] = "testuser@test.com";
40 static const char kTestUsername
[] = "testuser@test.com";
42 // Notification ID corresponding to kProfileSigninNotificationId +
44 static const std::string kNotificationId
=
45 "chrome://settings/signin/testuser@test.com";
49 class ScreenTypeDelegateDesktop
: public gfx::ScreenTypeDelegate
{
51 ScreenTypeDelegateDesktop() {}
52 virtual gfx::ScreenType
GetScreenTypeForNativeView(
53 gfx::NativeView view
) override
{
54 return chrome::IsNativeViewInAsh(view
) ?
55 gfx::SCREEN_TYPE_ALTERNATE
:
56 gfx::SCREEN_TYPE_NATIVE
;
59 DISALLOW_COPY_AND_ASSIGN(ScreenTypeDelegateDesktop
);
63 class SigninErrorNotifierTest
: public AshTestBase
{
65 virtual void SetUp() override
{
66 // Create a signed-in profile.
67 TestingProfile::Builder builder
;
68 builder
.AddTestingFactory(SigninManagerFactory::GetInstance(),
69 FakeSigninManagerBase::Build
);
70 profile_
= builder
.Build();
71 profile_
->set_profile_name(kTestAccountId
);
73 profile_manager_
.reset(
74 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
75 ASSERT_TRUE(profile_manager_
->SetUp());
77 TestingBrowserProcess::GetGlobal();
80 // Set up screen for Windows.
82 test_screen_
.reset(aura::TestScreen::Create(gfx::Size()));
83 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, test_screen_
.get());
84 gfx::Screen::SetScreenTypeDelegate(new ScreenTypeDelegateDesktop
);
88 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
.get())->
89 signin_error_controller();
90 SigninErrorNotifierFactory::GetForProfile(profile_
.get());
91 notification_ui_manager_
= g_browser_process
->notification_ui_manager();
94 virtual void TearDown() override
{
98 profile_manager_
.reset();
100 AshTestBase::TearDown();
104 void GetMessage(base::string16
* message
) {
105 const Notification
* notification
=
106 g_browser_process
->notification_ui_manager()->FindById(
108 NotificationUIManager::GetProfileID(profile_
.get()));
109 ASSERT_FALSE(notification
== NULL
);
110 *message
= notification
->message();
114 scoped_ptr
<gfx::Screen
> test_screen_
;
116 scoped_ptr
<TestingProfileManager
> profile_manager_
;
117 scoped_ptr
<TestingProfile
> profile_
;
118 SigninErrorController
* error_controller_
;
119 NotificationUIManager
* notification_ui_manager_
;
122 TEST_F(SigninErrorNotifierTest
, NoErrorAuthStatusProviders
) {
123 ASSERT_FALSE(notification_ui_manager_
->FindById(
124 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
126 // Add a provider (removes itself on exiting this scope).
127 FakeAuthStatusProvider
provider(error_controller_
);
128 ASSERT_FALSE(notification_ui_manager_
->FindById(
129 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
131 ASSERT_FALSE(notification_ui_manager_
->FindById(
132 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
136 // Disabled on Win due to flake. http://crbug.com/372236
137 TEST_F(SigninErrorNotifierTest
, ErrorAuthStatusProvider
) {
139 FakeAuthStatusProvider
provider(error_controller_
);
140 ASSERT_FALSE(notification_ui_manager_
->FindById(
141 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
143 FakeAuthStatusProvider
error_provider(error_controller_
);
144 error_provider
.SetAuthError(
147 GoogleServiceAuthError(
148 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS
));
149 ASSERT_TRUE(notification_ui_manager_
->FindById(
151 NotificationUIManager::GetProfileID(profile_
.get())));
153 // error_provider is removed now that we've left that scope.
154 ASSERT_FALSE(notification_ui_manager_
->FindById(
155 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
157 // All providers should be removed now.
158 ASSERT_FALSE(notification_ui_manager_
->FindById(
159 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
164 // Test started crashing on Win 7. http://crbug.com/372277
165 #define MAYBE_AuthStatusProviderErrorTransition \
166 DISABLED_AuthStatusProviderErrorTransition
168 #define MAYBE_AuthStatusProviderErrorTransition \
169 AuthStatusProviderErrorTransition
171 TEST_F(SigninErrorNotifierTest
, MAYBE_AuthStatusProviderErrorTransition
) {
173 FakeAuthStatusProvider
provider0(error_controller_
);
174 FakeAuthStatusProvider
provider1(error_controller_
);
175 provider0
.SetAuthError(
178 GoogleServiceAuthError(
179 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS
));
180 ASSERT_TRUE(notification_ui_manager_
->FindById(
181 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
183 base::string16 message
;
184 GetMessage(&message
);
185 ASSERT_FALSE(message
.empty());
187 // Now set another auth error and clear the original.
188 provider1
.SetAuthError(
191 GoogleServiceAuthError(
192 GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE
));
193 provider0
.SetAuthError(
196 GoogleServiceAuthError::AuthErrorNone());
198 ASSERT_TRUE(notification_ui_manager_
->FindById(
199 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
201 base::string16 new_message
;
202 GetMessage(&new_message
);
203 ASSERT_FALSE(new_message
.empty());
205 ASSERT_NE(new_message
, message
);
207 provider1
.SetAuthError(
208 kTestAccountId
, kTestUsername
, GoogleServiceAuthError::AuthErrorNone());
209 ASSERT_FALSE(notification_ui_manager_
->FindById(
210 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get())));
215 // Disabled on Win due to flake. http://crbug.com/372236
216 // Verify that SigninErrorNotifier ignores certain errors.
217 TEST_F(SigninErrorNotifierTest
, AuthStatusEnumerateAllErrors
) {
219 GoogleServiceAuthError::State error_state
;
223 ErrorTableEntry table
[] = {
224 { GoogleServiceAuthError::NONE
, false },
225 { GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS
, true },
226 { GoogleServiceAuthError::USER_NOT_SIGNED_UP
, true },
227 { GoogleServiceAuthError::CONNECTION_FAILED
, false },
228 { GoogleServiceAuthError::CAPTCHA_REQUIRED
, true },
229 { GoogleServiceAuthError::ACCOUNT_DELETED
, true },
230 { GoogleServiceAuthError::ACCOUNT_DISABLED
, true },
231 { GoogleServiceAuthError::SERVICE_UNAVAILABLE
, true },
232 { GoogleServiceAuthError::TWO_FACTOR
, true },
233 { GoogleServiceAuthError::REQUEST_CANCELED
, true },
234 { GoogleServiceAuthError::HOSTED_NOT_ALLOWED
, true },
235 { GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE
, true },
236 { GoogleServiceAuthError::SERVICE_ERROR
, true },
237 { GoogleServiceAuthError::WEB_LOGIN_REQUIRED
, true },
239 COMPILE_ASSERT(arraysize(table
) == GoogleServiceAuthError::NUM_STATES
,
240 kTable_size_does_not_match_number_of_auth_error_types
);
242 for (size_t i
= 0; i
< arraysize(table
); ++i
) {
243 FakeAuthStatusProvider
provider(error_controller_
);
244 provider
.SetAuthError(kTestAccountId
,
246 GoogleServiceAuthError(table
[i
].error_state
));
247 const Notification
* notification
= notification_ui_manager_
->FindById(
248 kNotificationId
, NotificationUIManager::GetProfileID(profile_
.get()));
249 ASSERT_EQ(table
[i
].is_error
, notification
!= NULL
);
250 if (table
[i
].is_error
) {
251 EXPECT_FALSE(notification
->title().empty());
252 EXPECT_FALSE(notification
->message().empty());
253 EXPECT_EQ((size_t)1, notification
->buttons().size());