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(kNotificationId
);
107 ASSERT_FALSE(notification
== NULL
);
108 *message
= notification
->message();
112 scoped_ptr
<gfx::Screen
> test_screen_
;
114 scoped_ptr
<TestingProfileManager
> profile_manager_
;
115 scoped_ptr
<TestingProfile
> profile_
;
116 SigninErrorController
* error_controller_
;
117 NotificationUIManager
* notification_ui_manager_
;
120 TEST_F(SigninErrorNotifierTest
, NoErrorAuthStatusProviders
) {
121 ASSERT_FALSE(notification_ui_manager_
->FindById(kNotificationId
));
123 // Add a provider (removes itself on exiting this scope).
124 FakeAuthStatusProvider
provider(error_controller_
);
125 ASSERT_FALSE(notification_ui_manager_
->FindById(kNotificationId
));
127 ASSERT_FALSE(notification_ui_manager_
->FindById(kNotificationId
));
131 // Disabled on Win due to flake. http://crbug.com/372236
132 TEST_F(SigninErrorNotifierTest
, ErrorAuthStatusProvider
) {
134 FakeAuthStatusProvider
provider(error_controller_
);
135 ASSERT_FALSE(notification_ui_manager_
->FindById(kNotificationId
));
137 FakeAuthStatusProvider
error_provider(error_controller_
);
138 error_provider
.SetAuthError(
141 GoogleServiceAuthError(
142 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS
));
143 ASSERT_TRUE(notification_ui_manager_
->FindById(kNotificationId
));
145 // error_provider is removed now that we've left that scope.
146 ASSERT_FALSE(notification_ui_manager_
->FindById(kNotificationId
));
148 // All providers should be removed now.
149 ASSERT_FALSE(notification_ui_manager_
->FindById(kNotificationId
));
154 // Test started crashing on Win 7. http://crbug.com/372277
155 #define MAYBE_AuthStatusProviderErrorTransition \
156 DISABLED_AuthStatusProviderErrorTransition
158 #define MAYBE_AuthStatusProviderErrorTransition \
159 AuthStatusProviderErrorTransition
161 TEST_F(SigninErrorNotifierTest
, MAYBE_AuthStatusProviderErrorTransition
) {
163 FakeAuthStatusProvider
provider0(error_controller_
);
164 FakeAuthStatusProvider
provider1(error_controller_
);
165 provider0
.SetAuthError(
168 GoogleServiceAuthError(
169 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS
));
170 ASSERT_TRUE(notification_ui_manager_
->FindById(kNotificationId
));
172 base::string16 message
;
173 GetMessage(&message
);
174 ASSERT_FALSE(message
.empty());
176 // Now set another auth error and clear the original.
177 provider1
.SetAuthError(
180 GoogleServiceAuthError(
181 GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE
));
182 provider0
.SetAuthError(
185 GoogleServiceAuthError::AuthErrorNone());
187 ASSERT_TRUE(notification_ui_manager_
->FindById(kNotificationId
));
189 base::string16 new_message
;
190 GetMessage(&new_message
);
191 ASSERT_FALSE(new_message
.empty());
193 ASSERT_NE(new_message
, message
);
195 provider1
.SetAuthError(
196 kTestAccountId
, kTestUsername
, GoogleServiceAuthError::AuthErrorNone());
197 ASSERT_FALSE(notification_ui_manager_
->FindById(kNotificationId
));
202 // Disabled on Win due to flake. http://crbug.com/372236
203 // Verify that SigninErrorNotifier ignores certain errors.
204 TEST_F(SigninErrorNotifierTest
, AuthStatusEnumerateAllErrors
) {
206 GoogleServiceAuthError::State error_state
;
210 ErrorTableEntry table
[] = {
211 { GoogleServiceAuthError::NONE
, false },
212 { GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS
, true },
213 { GoogleServiceAuthError::USER_NOT_SIGNED_UP
, true },
214 { GoogleServiceAuthError::CONNECTION_FAILED
, false },
215 { GoogleServiceAuthError::CAPTCHA_REQUIRED
, true },
216 { GoogleServiceAuthError::ACCOUNT_DELETED
, true },
217 { GoogleServiceAuthError::ACCOUNT_DISABLED
, true },
218 { GoogleServiceAuthError::SERVICE_UNAVAILABLE
, true },
219 { GoogleServiceAuthError::TWO_FACTOR
, true },
220 { GoogleServiceAuthError::REQUEST_CANCELED
, true },
221 { GoogleServiceAuthError::HOSTED_NOT_ALLOWED
, true },
222 { GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE
, true },
223 { GoogleServiceAuthError::SERVICE_ERROR
, true },
225 COMPILE_ASSERT(ARRAYSIZE_UNSAFE(table
) == GoogleServiceAuthError::NUM_STATES
,
226 kTable_size_does_not_match_number_of_auth_error_types
);
228 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(table
); ++i
) {
229 FakeAuthStatusProvider
provider(error_controller_
);
230 provider
.SetAuthError(kTestAccountId
,
232 GoogleServiceAuthError(table
[i
].error_state
));
233 const Notification
* notification
= notification_ui_manager_
->
234 FindById(kNotificationId
);
235 ASSERT_EQ(table
[i
].is_error
, notification
!= NULL
);
236 if (table
[i
].is_error
) {
237 EXPECT_FALSE(notification
->title().empty());
238 EXPECT_FALSE(notification
->message().empty());
239 EXPECT_EQ((size_t)1, notification
->buttons().size());