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 "base/metrics/histogram_samples.h"
6 #include "base/prefs/pref_service.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "base/test/histogram_tester.h"
9 #include "chrome/browser/sync/profile_sync_service_factory.h"
10 #include "chrome/browser/sync/profile_sync_service_mock.h"
11 #include "chrome/browser/ui/passwords/manage_passwords_bubble.h"
12 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
13 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h"
14 #include "chrome/test/base/testing_profile.h"
15 #include "components/password_manager/core/browser/password_bubble_experiment.h"
16 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
17 #include "components/password_manager/core/common/credential_manager_types.h"
18 #include "components/password_manager/core/common/password_manager_pref_names.h"
19 #include "components/password_manager/core/common/password_manager_ui.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "content/public/test/web_contents_tester.h"
22 #include "testing/gtest/include/gtest/gtest.h"
26 const char kUIDismissalReasonMetric
[] = "PasswordManager.UIDismissalReason";
28 class TestSyncService
: public ProfileSyncServiceMock
{
30 explicit TestSyncService(Profile
* profile
)
31 : ProfileSyncServiceMock(profile
), smartlock_enabled_(false) {}
32 ~TestSyncService() override
{}
35 bool HasSyncSetupCompleted() const override
{ return true; }
36 bool IsSyncAllowed() const override
{ return true; }
37 bool IsSyncActive() const override
{ return true; }
38 syncer::ModelTypeSet
GetActiveDataTypes() const override
{
39 return smartlock_enabled_
? syncer::ModelTypeSet::All()
40 : syncer::ModelTypeSet();
42 bool CanSyncStart() const override
{ return true; }
43 syncer::ModelTypeSet
GetPreferredDataTypes() const override
{
44 return GetActiveDataTypes();
46 bool IsUsingSecondaryPassphrase() const override
{ return false; }
48 void set_smartlock_enabled(bool smartlock_enabled
) {
49 smartlock_enabled_
= smartlock_enabled
;
53 bool smartlock_enabled_
;
56 scoped_ptr
<KeyedService
> TestingSyncFactoryFunction(
57 content::BrowserContext
* context
) {
58 return make_scoped_ptr(new TestSyncService(static_cast<Profile
*>(context
)));
63 class ManagePasswordsBubbleModelTest
: public testing::Test
{
65 ManagePasswordsBubbleModelTest()
66 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP
),
68 content::WebContentsTester::CreateTestWebContents(&profile_
,
71 void SetUp() override
{
72 // Create the test UIController here so that it's bound to
73 // |test_web_contents_| and therefore accessible to the model.
74 new ManagePasswordsUIControllerMock(test_web_contents_
.get());
76 model_
.reset(new ManagePasswordsBubbleModel(test_web_contents_
.get()));
79 void TearDown() override
{ model_
.reset(); }
81 PrefService
* prefs() { return profile_
.GetPrefs(); }
83 TestingProfile
* profile() { return &profile_
; }
85 void PretendPasswordWaiting() {
86 model_
->set_state(password_manager::ui::PENDING_PASSWORD_STATE
);
87 model_
->OnBubbleShown(ManagePasswordsBubble::AUTOMATIC
);
90 void PretendUpdatePasswordWaiting() {
91 model_
->set_state(password_manager::ui::PENDING_PASSWORD_UPDATE_STATE
);
92 model_
->OnBubbleShown(ManagePasswordsBubble::AUTOMATIC
);
95 void PretendCredentialsWaiting() {
96 model_
->set_state(password_manager::ui::CREDENTIAL_REQUEST_STATE
);
97 model_
->OnBubbleShown(ManagePasswordsBubble::AUTOMATIC
);
100 void PretendAutoSigningIn() {
101 model_
->set_state(password_manager::ui::AUTO_SIGNIN_STATE
);
102 model_
->OnBubbleShown(ManagePasswordsBubble::AUTOMATIC
);
105 void PretendManagingPasswords() {
106 model_
->set_state(password_manager::ui::MANAGE_STATE
);
107 model_
->OnBubbleShown(ManagePasswordsBubble::USER_ACTION
);
110 ManagePasswordsUIControllerMock
* controller() {
111 return static_cast<ManagePasswordsUIControllerMock
*>(
112 ManagePasswordsUIController::FromWebContents(
113 test_web_contents_
.get()));
117 scoped_ptr
<ManagePasswordsBubbleModel
> model_
;
118 autofill::PasswordForm test_form_
;
121 content::TestBrowserThreadBundle thread_bundle_
;
122 TestingProfile profile_
;
123 scoped_ptr
<content::WebContents
> test_web_contents_
;
126 TEST_F(ManagePasswordsBubbleModelTest
, DefaultValues
) {
127 EXPECT_EQ(model_
->display_disposition(),
128 password_manager::metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING
);
129 EXPECT_EQ(model_
->dismissal_reason(),
130 password_manager::metrics_util::NOT_DISPLAYED
);
131 EXPECT_FALSE(controller()->saved_password());
132 EXPECT_FALSE(controller()->never_saved_password());
135 TEST_F(ManagePasswordsBubbleModelTest
, CloseWithoutLogging
) {
136 base::HistogramTester histogram_tester
;
137 model_
->OnBubbleHidden();
138 EXPECT_EQ(model_
->dismissal_reason(),
139 password_manager::metrics_util::NOT_DISPLAYED
);
140 EXPECT_FALSE(controller()->saved_password());
141 EXPECT_FALSE(controller()->never_saved_password());
143 histogram_tester
.ExpectTotalCount(kUIDismissalReasonMetric
, 0);
146 TEST_F(ManagePasswordsBubbleModelTest
, CloseWithoutInteraction
) {
147 base::HistogramTester histogram_tester
;
148 PretendPasswordWaiting();
149 model_
->OnBubbleHidden();
150 EXPECT_EQ(model_
->dismissal_reason(),
151 password_manager::metrics_util::NO_DIRECT_INTERACTION
);
152 EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE
,
154 EXPECT_FALSE(controller()->saved_password());
155 EXPECT_FALSE(controller()->never_saved_password());
157 histogram_tester
.ExpectUniqueSample(
158 kUIDismissalReasonMetric
,
159 password_manager::metrics_util::NO_DIRECT_INTERACTION
,
163 TEST_F(ManagePasswordsBubbleModelTest
, ClickSave
) {
164 base::HistogramTester histogram_tester
;
165 PretendPasswordWaiting();
166 model_
->OnSaveClicked();
167 model_
->OnBubbleHidden();
168 EXPECT_EQ(model_
->dismissal_reason(),
169 password_manager::metrics_util::CLICKED_SAVE
);
170 EXPECT_TRUE(controller()->saved_password());
171 EXPECT_FALSE(controller()->never_saved_password());
173 histogram_tester
.ExpectUniqueSample(
174 kUIDismissalReasonMetric
,
175 password_manager::metrics_util::CLICKED_SAVE
,
179 TEST_F(ManagePasswordsBubbleModelTest
, ClickNever
) {
180 base::HistogramTester histogram_tester
;
181 PretendPasswordWaiting();
182 model_
->OnNeverForThisSiteClicked();
183 model_
->OnBubbleHidden();
184 EXPECT_EQ(model_
->dismissal_reason(),
185 password_manager::metrics_util::CLICKED_NEVER
);
186 EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE
, model_
->state());
187 EXPECT_FALSE(controller()->saved_password());
188 EXPECT_TRUE(controller()->never_saved_password());
190 histogram_tester
.ExpectUniqueSample(
191 kUIDismissalReasonMetric
,
192 password_manager::metrics_util::CLICKED_NEVER
,
196 TEST_F(ManagePasswordsBubbleModelTest
, ClickManage
) {
197 base::HistogramTester histogram_tester
;
198 PretendManagingPasswords();
199 model_
->OnManageLinkClicked();
200 model_
->OnBubbleHidden();
201 EXPECT_EQ(model_
->dismissal_reason(),
202 password_manager::metrics_util::CLICKED_MANAGE
);
203 EXPECT_EQ(password_manager::ui::MANAGE_STATE
, model_
->state());
204 EXPECT_FALSE(controller()->saved_password());
205 EXPECT_FALSE(controller()->never_saved_password());
207 histogram_tester
.ExpectUniqueSample(
208 kUIDismissalReasonMetric
,
209 password_manager::metrics_util::CLICKED_MANAGE
,
213 TEST_F(ManagePasswordsBubbleModelTest
, ClickDone
) {
214 base::HistogramTester histogram_tester
;
215 PretendManagingPasswords();
216 model_
->OnDoneClicked();
217 model_
->OnBubbleHidden();
218 EXPECT_EQ(model_
->dismissal_reason(),
219 password_manager::metrics_util::CLICKED_DONE
);
220 EXPECT_EQ(password_manager::ui::MANAGE_STATE
, model_
->state());
221 EXPECT_FALSE(controller()->saved_password());
222 EXPECT_FALSE(controller()->never_saved_password());
224 histogram_tester
.ExpectUniqueSample(
225 kUIDismissalReasonMetric
,
226 password_manager::metrics_util::CLICKED_DONE
,
230 TEST_F(ManagePasswordsBubbleModelTest
, ClickCredential
) {
231 base::HistogramTester histogram_tester
;
232 PretendCredentialsWaiting();
233 EXPECT_FALSE(controller()->choose_credential());
234 autofill::PasswordForm form
;
235 model_
->OnChooseCredentials(
236 form
, password_manager::CredentialType::CREDENTIAL_TYPE_PASSWORD
);
237 model_
->OnBubbleHidden();
238 EXPECT_EQ(model_
->dismissal_reason(),
239 password_manager::metrics_util::CLICKED_CREDENTIAL
);
240 EXPECT_FALSE(controller()->saved_password());
241 EXPECT_FALSE(controller()->never_saved_password());
242 EXPECT_TRUE(controller()->choose_credential());
244 histogram_tester
.ExpectUniqueSample(
245 kUIDismissalReasonMetric
,
246 password_manager::metrics_util::CLICKED_CREDENTIAL
,
250 TEST_F(ManagePasswordsBubbleModelTest
, ClickCancelCredential
) {
251 base::HistogramTester histogram_tester
;
252 PretendCredentialsWaiting();
253 EXPECT_FALSE(controller()->choose_credential());
254 model_
->OnCancelClicked();
255 model_
->OnBubbleHidden();
256 EXPECT_EQ(model_
->dismissal_reason(),
257 password_manager::metrics_util::CLICKED_CANCEL
);
258 EXPECT_FALSE(controller()->saved_password());
259 EXPECT_FALSE(controller()->never_saved_password());
260 EXPECT_FALSE(controller()->choose_credential());
262 histogram_tester
.ExpectUniqueSample(
263 kUIDismissalReasonMetric
, password_manager::metrics_util::CLICKED_CANCEL
,
267 TEST_F(ManagePasswordsBubbleModelTest
, DismissCredential
) {
268 base::HistogramTester histogram_tester
;
269 PretendCredentialsWaiting();
270 EXPECT_FALSE(controller()->choose_credential());
271 model_
->OnBubbleHidden();
272 EXPECT_EQ(model_
->dismissal_reason(),
273 password_manager::metrics_util::NO_DIRECT_INTERACTION
);
274 EXPECT_FALSE(controller()->saved_password());
275 EXPECT_FALSE(controller()->never_saved_password());
276 EXPECT_FALSE(controller()->choose_credential());
278 histogram_tester
.ExpectUniqueSample(
279 kUIDismissalReasonMetric
,
280 password_manager::metrics_util::NO_DIRECT_INTERACTION
,
284 TEST_F(ManagePasswordsBubbleModelTest
, PopupAutoSigninToast
) {
285 base::HistogramTester histogram_tester
;
286 PretendAutoSigningIn();
287 model_
->OnAutoSignInToastTimeout();
288 model_
->OnBubbleHidden();
289 EXPECT_EQ(model_
->dismissal_reason(),
290 password_manager::metrics_util::AUTO_SIGNIN_TOAST_TIMEOUT
);
292 histogram_tester
.ExpectUniqueSample(
293 kUIDismissalReasonMetric
,
294 password_manager::metrics_util::AUTO_SIGNIN_TOAST_TIMEOUT
,
298 TEST_F(ManagePasswordsBubbleModelTest
, PopupAutoSigninAndManagedBubble
) {
299 base::HistogramTester histogram_tester
;
300 PretendAutoSigningIn();
301 model_
->OnAutoSignInToastTimeout();
302 model_
->OnAutoSignInClicked();
303 EXPECT_EQ(model_
->dismissal_reason(),
304 password_manager::metrics_util::AUTO_SIGNIN_TOAST_CLICKED
);
305 model_
->OnBubbleHidden();
307 EXPECT_TRUE(controller()->manage_accounts());
309 histogram_tester
.ExpectUniqueSample(
310 kUIDismissalReasonMetric
,
311 password_manager::metrics_util::AUTO_SIGNIN_TOAST_CLICKED
,
315 TEST_F(ManagePasswordsBubbleModelTest
, ClickUpdate
) {
316 PretendUpdatePasswordWaiting();
317 model_
->OnUpdateClicked(autofill::PasswordForm());
318 model_
->OnBubbleHidden();
319 EXPECT_TRUE(controller()->updated_password());
320 EXPECT_FALSE(controller()->never_saved_password());
323 TEST_F(ManagePasswordsBubbleModelTest
, ShowSmartLockWarmWelcome
) {
324 TestSyncService
* sync_service
= static_cast<TestSyncService
*>(
325 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
326 profile(), &TestingSyncFactoryFunction
));
327 sync_service
->set_smartlock_enabled(true);
328 base::FieldTrialList
field_trials(nullptr);
329 base::FieldTrialList::CreateFieldTrial(
330 password_bubble_experiment::kBrandingExperimentName
,
331 password_bubble_experiment::kSmartLockBrandingGroupName
);
333 PretendPasswordWaiting();
334 EXPECT_TRUE(model_
->ShouldShowGoogleSmartLockWelcome());
335 model_
->OnBubbleHidden();
336 EXPECT_FALSE(model_
->ShouldShowGoogleSmartLockWelcome());
337 EXPECT_TRUE(prefs()->GetBoolean(
338 password_manager::prefs::kWasSavePrompFirstRunExperienceShown
));
341 TEST_F(ManagePasswordsBubbleModelTest
, OmitSmartLockWarmWelcome
) {
342 TestSyncService
* sync_service
= static_cast<TestSyncService
*>(
343 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
344 profile(), &TestingSyncFactoryFunction
));
345 sync_service
->set_smartlock_enabled(false);
346 base::FieldTrialList
field_trials(nullptr);
347 base::FieldTrialList::CreateFieldTrial(
348 password_bubble_experiment::kBrandingExperimentName
,
349 password_bubble_experiment::kSmartLockBrandingGroupName
);
351 PretendPasswordWaiting();
352 EXPECT_FALSE(model_
->ShouldShowGoogleSmartLockWelcome());
353 model_
->OnBubbleHidden();
354 EXPECT_FALSE(model_
->ShouldShowGoogleSmartLockWelcome());
355 EXPECT_FALSE(prefs()->GetBoolean(
356 password_manager::prefs::kWasSavePrompFirstRunExperienceShown
));