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 "chrome/browser/sync/sync_global_error.h"
7 #include "base/basictypes.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/app/chrome_command_ids.h"
10 #include "chrome/browser/signin/signin_manager.h"
11 #include "chrome/browser/signin/signin_manager_factory.h"
12 #include "chrome/browser/sync/profile_sync_service_mock.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
15 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
16 #include "chrome/test/base/browser_with_test_window_test.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "content/public/test/test_browser_thread.h"
19 #include "testing/gmock/include/gmock/gmock-actions.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 using ::testing::NiceMock
;
24 using ::testing::Return
;
25 using ::testing::ReturnRef
;
27 using content::BrowserThread
;
32 // TODO(altimofeev) See below.
33 class BrowserMock
: public Browser
{
35 explicit BrowserMock(Type type
, Profile
* profile
) : Browser(type
, profile
) {}
37 MOCK_METHOD2(ExecuteCommandWithDisposition
,
38 void(int command_id
, WindowOpenDisposition
));
42 class FakeLoginUIService
: public LoginUIService
{
44 FakeLoginUIService() : LoginUIService(NULL
) {}
47 class FakeLoginUI
: public LoginUIService::LoginUI
{
49 FakeLoginUI() : focus_ui_call_count_(0) {}
51 virtual ~FakeLoginUI() {}
53 int focus_ui_call_count() const { return focus_ui_call_count_
; }
56 // Overridden from LoginUIService::LoginUI:
57 virtual void FocusUI() OVERRIDE
{
58 ++focus_ui_call_count_
;
60 virtual void CloseUI() OVERRIDE
{}
62 int focus_ui_call_count_
;
65 BrowserContextKeyedService
* BuildMockLoginUIService(
66 content::BrowserContext
* profile
) {
67 return new FakeLoginUIService();
70 // Same as BrowserWithTestWindowTest, but uses MockBrowser to test calls to
71 // ExecuteCommand method.
72 class SyncGlobalErrorTest
: public BrowserWithTestWindowTest
{
74 SyncGlobalErrorTest() {}
75 virtual ~SyncGlobalErrorTest() {}
78 // TODO(altimofeev): see below.
79 virtual void SetUp() OVERRIDE
{
80 testing::Test::SetUp();
82 set_profile(CreateProfile());
83 set_browser(new BrowserMock(Browser::TYPE_TABBED
, profile()));
84 set_window(new TestBrowserWindow(browser()));
85 browser()->SetWindowForTesting(window());
88 virtual void TearDown() OVERRIDE
{
89 testing::Test::TearDown();
94 DISALLOW_COPY_AND_ASSIGN(SyncGlobalErrorTest
);
97 // Utility function to test that SyncGlobalError behaves correct for the given
99 void VerifySyncGlobalErrorResult(NiceMock
<ProfileSyncServiceMock
>* service
,
100 FakeLoginUIService
* login_ui_service
,
102 SyncGlobalError
* error
,
103 GoogleServiceAuthError::State error_state
,
106 EXPECT_CALL(*service
, HasSyncSetupCompleted())
107 .WillRepeatedly(Return(is_signed_in
));
109 GoogleServiceAuthError
auth_error(error_state
);
110 EXPECT_CALL(*service
, GetAuthError()).WillRepeatedly(ReturnRef(auth_error
));
112 error
->OnStateChanged();
114 // If there is an error then a menu item and bubble view should be shown.
115 EXPECT_EQ(error
->HasMenuItem(), is_error
);
116 EXPECT_EQ(error
->HasBubbleView(), is_error
);
118 // If there is an error then labels should not be empty.
119 EXPECT_NE(error
->MenuItemCommandID(), 0);
120 EXPECT_NE(error
->MenuItemLabel().empty(), is_error
);
121 EXPECT_NE(error
->GetBubbleViewAcceptButtonLabel().empty(), is_error
);
123 // We never have a cancel button.
124 EXPECT_TRUE(error
->GetBubbleViewCancelButtonLabel().empty());
125 // We always return a hardcoded title.
126 EXPECT_FALSE(error
->GetBubbleViewTitle().empty());
128 #if defined(OS_CHROMEOS)
129 // TODO(altimofeev): Implement this in a way that doesn't involve subclassing
130 // Browser or using GMock on browser/ui types which is
131 // banned. Consider observing NOTIFICATION_APP_TERMINATING
133 // http://crbug.com/134675
135 #if defined(OS_CHROMEOS)
136 if (error_state
!= GoogleServiceAuthError::NONE
) {
137 // In CrOS sign-in/sign-out is made to fix the error.
138 EXPECT_CALL(*static_cast<BrowserMock
*>(browser
),
139 ExecuteCommandWithDisposition(IDC_EXIT
, _
));
140 error
->ExecuteMenuItem(browser
);
143 // Test message handler.
145 FakeLoginUI
* login_ui
= static_cast<FakeLoginUI
*>(
146 login_ui_service
->current_login_ui());
147 error
->ExecuteMenuItem(browser
);
148 ASSERT_GT(login_ui
->focus_ui_call_count(), 0);
149 error
->BubbleViewAcceptButtonPressed(browser
);
150 error
->BubbleViewDidClose(browser
);
158 // Test that SyncGlobalError shows an error if a passphrase is required.
159 TEST_F(SyncGlobalErrorTest
, PassphraseGlobalError
) {
160 scoped_ptr
<Profile
> profile(
161 ProfileSyncServiceMock::MakeSignedInTestingProfile());
162 NiceMock
<ProfileSyncServiceMock
> service(profile
.get());
163 SigninManagerBase
* signin
=
164 SigninManagerFactory::GetForProfile(profile
.get());
165 FakeLoginUIService
* login_ui_service
= static_cast<FakeLoginUIService
*>(
166 LoginUIServiceFactory::GetInstance()->SetTestingFactoryAndUse(
167 profile
.get(), BuildMockLoginUIService
));
168 FakeLoginUI login_ui
;
169 login_ui_service
->SetLoginUI(&login_ui
);
170 SyncGlobalError
error(&service
, signin
);
172 browser_sync::SyncBackendHost::Status status
;
173 EXPECT_CALL(service
, QueryDetailedSyncStatus(_
))
174 .WillRepeatedly(Return(false));
176 EXPECT_CALL(service
, IsPassphraseRequired())
177 .WillRepeatedly(Return(true));
178 EXPECT_CALL(service
, IsPassphraseRequiredForDecryption())
179 .WillRepeatedly(Return(true));
180 VerifySyncGlobalErrorResult(
181 &service
, login_ui_service
, browser(), &error
,
182 GoogleServiceAuthError::NONE
, true, true);