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 "chrome/browser/chrome_notification_types.h"
8 #include "chrome/browser/sync/profile_sync_service_mock.h"
9 #include "chrome/browser/sync/sync_error_controller.h"
10 #include "chrome/browser/sync/sync_global_error_factory.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
13 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
14 #include "chrome/test/base/browser_with_test_window_test.h"
15 #include "chrome/test/base/testing_profile.h"
16 #include "content/public/browser/notification_observer.h"
17 #include "content/public/browser/notification_registrar.h"
18 #include "content/public/browser/notification_source.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 using ::testing::NiceMock
;
23 using ::testing::Return
;
24 using ::testing::ReturnRef
;
29 class FakeLoginUIService
: public LoginUIService
{
31 FakeLoginUIService() : LoginUIService(NULL
) {}
34 class FakeLoginUI
: public LoginUIService::LoginUI
{
36 FakeLoginUI() : focus_ui_call_count_(0) {}
38 ~FakeLoginUI() override
{}
40 int focus_ui_call_count() const { return focus_ui_call_count_
; }
43 // Overridden from LoginUIService::LoginUI:
44 void FocusUI() override
{ ++focus_ui_call_count_
; }
45 void CloseUI() override
{}
47 int focus_ui_call_count_
;
50 KeyedService
* BuildMockLoginUIService(content::BrowserContext
* profile
) {
51 return new FakeLoginUIService();
54 // Same as BrowserWithTestWindowTest, but uses MockBrowser to test calls to
55 // ExecuteCommand method.
56 class SyncGlobalErrorTest
: public BrowserWithTestWindowTest
{
58 SyncGlobalErrorTest() {}
59 ~SyncGlobalErrorTest() override
{}
61 void SetUp() override
{
62 profile_
.reset(ProfileSyncServiceMock::MakeSignedInTestingProfile());
64 BrowserWithTestWindowTest::SetUp();
67 Profile
* profile() { return profile_
.get(); }
70 scoped_ptr
<TestingProfile
> profile_
;
72 DISALLOW_COPY_AND_ASSIGN(SyncGlobalErrorTest
);
75 // Utility function to test that SyncGlobalError behaves correctly for the given
77 void VerifySyncGlobalErrorResult(NiceMock
<ProfileSyncServiceMock
>* service
,
78 FakeLoginUIService
* login_ui_service
,
80 SyncErrorController
* error
,
81 SyncGlobalError
* global_error
,
82 GoogleServiceAuthError::State error_state
,
85 EXPECT_CALL(*service
, HasSyncSetupCompleted())
86 .WillRepeatedly(Return(is_signed_in
));
88 GoogleServiceAuthError
auth_error(error_state
);
89 EXPECT_CALL(*service
, GetAuthError()).WillRepeatedly(ReturnRef(auth_error
));
91 error
->OnStateChanged();
92 EXPECT_EQ(is_error
, error
->HasError());
94 // If there is an error then a menu item and bubble view should be shown.
95 EXPECT_EQ(is_error
, global_error
->HasMenuItem());
96 EXPECT_EQ(is_error
, global_error
->HasBubbleView());
98 // If there is an error then labels should not be empty.
99 EXPECT_NE(0, global_error
->MenuItemCommandID());
100 EXPECT_NE(is_error
, global_error
->MenuItemLabel().empty());
101 EXPECT_NE(is_error
, global_error
->GetBubbleViewAcceptButtonLabel().empty());
103 // We never have a cancel button.
104 EXPECT_TRUE(global_error
->GetBubbleViewCancelButtonLabel().empty());
105 // We always return a hardcoded title.
106 EXPECT_FALSE(global_error
->GetBubbleViewTitle().empty());
108 // Test message handler.
110 FakeLoginUI
* login_ui
= static_cast<FakeLoginUI
*>(
111 login_ui_service
->current_login_ui());
112 global_error
->ExecuteMenuItem(browser
);
113 ASSERT_GT(login_ui
->focus_ui_call_count(), 0);
114 global_error
->BubbleViewAcceptButtonPressed(browser
);
115 global_error
->BubbleViewDidClose(browser
);
121 // Test that SyncGlobalError shows an error if a passphrase is required.
122 TEST_F(SyncGlobalErrorTest
, PassphraseGlobalError
) {
123 NiceMock
<ProfileSyncServiceMock
> service(profile());
125 FakeLoginUIService
* login_ui_service
= static_cast<FakeLoginUIService
*>(
126 LoginUIServiceFactory::GetInstance()->SetTestingFactoryAndUse(
127 profile(), BuildMockLoginUIService
));
128 FakeLoginUI login_ui
;
129 login_ui_service
->SetLoginUI(&login_ui
);
131 SyncErrorController
error(&service
);
132 SyncGlobalError
global_error(&error
, &service
);
134 browser_sync::SyncBackendHost::Status status
;
135 EXPECT_CALL(service
, QueryDetailedSyncStatus(_
))
136 .WillRepeatedly(Return(false));
138 EXPECT_CALL(service
, IsPassphraseRequired())
139 .WillRepeatedly(Return(true));
140 EXPECT_CALL(service
, IsPassphraseRequiredForDecryption())
141 .WillRepeatedly(Return(true));
142 VerifySyncGlobalErrorResult(
143 &service
, login_ui_service
, browser(), &error
, &global_error
,
144 GoogleServiceAuthError::NONE
, true /* signed in*/, true /* error */);
146 // Check that no menu item is shown if there is no error.
147 EXPECT_CALL(service
, IsPassphraseRequired())
148 .WillRepeatedly(Return(false));
149 EXPECT_CALL(service
, IsPassphraseRequiredForDecryption())
150 .WillRepeatedly(Return(false));
151 VerifySyncGlobalErrorResult(
152 &service
, login_ui_service
, browser(), &error
, &global_error
,
153 GoogleServiceAuthError::NONE
, true /* signed in */, false /* no error */);
155 // Check that no menu item is shown if sync setup is not completed.
156 EXPECT_CALL(service
, IsPassphraseRequired())
157 .WillRepeatedly(Return(true));
158 EXPECT_CALL(service
, IsPassphraseRequiredForDecryption())
159 .WillRepeatedly(Return(true));
160 VerifySyncGlobalErrorResult(
161 &service
, login_ui_service
, browser(), &error
, &global_error
,
162 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS
,
163 false /* not signed in */, false /* no error */);
165 global_error
.Shutdown();