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.
4
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/ui/passwords/manage_passwords_bubble.h"
10#include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
11#include "chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h"
12#include "chrome/test/base/testing_profile.h"
13#include "components/password_manager/core/browser/password_manager_metrics_util.h"
14#include "components/password_manager/core/common/password_manager_ui.h"
15#include "content/public/test/test_browser_thread_bundle.h"
16#include "content/public/test/web_contents_tester.h"
17#include "testing/gtest/include/gtest/gtest.h"
18
19const char kUIDismissalReasonMetric[] = "PasswordManager.UIDismissalReason";
20
21class ManagePasswordsBubbleModelTest : public testing::Test {
22 public:
23  ManagePasswordsBubbleModelTest()
24      : test_web_contents_(
25            content::WebContentsTester::CreateTestWebContents(&profile_,
26                                                              NULL)) {}
27
28  virtual void SetUp() OVERRIDE {
29    // Create the test UIController here so that it's bound to
30    // |test_web_contents_| and therefore accessible to the model.
31    new ManagePasswordsUIControllerMock(test_web_contents_.get());
32
33    model_.reset(new ManagePasswordsBubbleModel(test_web_contents_.get()));
34  }
35
36  virtual void TearDown() OVERRIDE { model_.reset(); }
37
38  void PretendPasswordWaiting() {
39    model_->set_state(password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE);
40    model_->OnBubbleShown(ManagePasswordsBubble::AUTOMATIC);
41    controller()->SetState(
42        password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE);
43  }
44
45  void PretendManagingPasswords() {
46    model_->set_state(password_manager::ui::MANAGE_STATE);
47    model_->OnBubbleShown(ManagePasswordsBubble::USER_ACTION);
48    controller()->SetState(password_manager::ui::MANAGE_STATE);
49  }
50
51  void PretendBlacklisted() {
52    model_->set_state(password_manager::ui::BLACKLIST_STATE);
53    model_->OnBubbleShown(ManagePasswordsBubble::USER_ACTION);
54
55    base::string16 kTestUsername = base::ASCIIToUTF16("test_username");
56    autofill::ConstPasswordFormMap map;
57    map[kTestUsername] = &test_form_;
58    controller()->SetPasswordFormMap(map);
59    controller()->SetState(password_manager::ui::BLACKLIST_STATE);
60  }
61
62  ManagePasswordsUIControllerMock* controller() {
63    return static_cast<ManagePasswordsUIControllerMock*>(
64        ManagePasswordsUIController::FromWebContents(
65            test_web_contents_.get()));
66  }
67
68 protected:
69  scoped_ptr<ManagePasswordsBubbleModel> model_;
70  autofill::PasswordForm test_form_;
71
72 private:
73  content::TestBrowserThreadBundle thread_bundle_;
74  TestingProfile profile_;
75  scoped_ptr<content::WebContents> test_web_contents_;
76};
77
78TEST_F(ManagePasswordsBubbleModelTest, DefaultValues) {
79  EXPECT_EQ(model_->display_disposition(),
80            password_manager::metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING);
81  EXPECT_EQ(model_->dismissal_reason(),
82            password_manager::metrics_util::NOT_DISPLAYED);
83  EXPECT_FALSE(controller()->saved_password());
84  EXPECT_FALSE(controller()->never_saved_password());
85}
86
87TEST_F(ManagePasswordsBubbleModelTest, CloseWithoutLogging) {
88  base::HistogramTester histogram_tester;
89  model_->OnBubbleHidden();
90  EXPECT_EQ(model_->dismissal_reason(),
91            password_manager::metrics_util::NOT_DISPLAYED);
92  EXPECT_FALSE(controller()->saved_password());
93  EXPECT_FALSE(controller()->never_saved_password());
94
95  scoped_ptr<base::HistogramSamples> samples(
96      histogram_tester.GetHistogramSamplesSinceCreation(
97          kUIDismissalReasonMetric));
98  EXPECT_EQ(NULL, samples.get());
99}
100
101TEST_F(ManagePasswordsBubbleModelTest, CloseWithoutInteraction) {
102  base::HistogramTester histogram_tester;
103  PretendPasswordWaiting();
104  model_->OnBubbleHidden();
105  EXPECT_EQ(model_->dismissal_reason(),
106            password_manager::metrics_util::NO_DIRECT_INTERACTION);
107  EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE,
108            model_->state());
109  EXPECT_FALSE(controller()->saved_password());
110  EXPECT_FALSE(controller()->never_saved_password());
111
112  histogram_tester.ExpectUniqueSample(
113      kUIDismissalReasonMetric,
114      password_manager::metrics_util::NO_DIRECT_INTERACTION,
115      1);
116}
117
118TEST_F(ManagePasswordsBubbleModelTest, ClickSave) {
119  base::HistogramTester histogram_tester;
120  PretendPasswordWaiting();
121  model_->OnSaveClicked();
122  model_->OnBubbleHidden();
123  EXPECT_EQ(model_->dismissal_reason(),
124            password_manager::metrics_util::CLICKED_SAVE);
125  EXPECT_EQ(password_manager::ui::MANAGE_STATE, model_->state());
126  EXPECT_TRUE(controller()->saved_password());
127  EXPECT_FALSE(controller()->never_saved_password());
128
129  histogram_tester.ExpectUniqueSample(
130      kUIDismissalReasonMetric,
131      password_manager::metrics_util::CLICKED_SAVE,
132      1);
133}
134
135TEST_F(ManagePasswordsBubbleModelTest, ClickNope) {
136  base::HistogramTester histogram_tester;
137  PretendPasswordWaiting();
138  model_->OnNopeClicked();
139  model_->OnBubbleHidden();
140  EXPECT_EQ(model_->dismissal_reason(),
141            password_manager::metrics_util::CLICKED_NOPE);
142  EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE, model_->state());
143  EXPECT_FALSE(controller()->saved_password());
144  EXPECT_FALSE(controller()->never_saved_password());
145
146  histogram_tester.ExpectUniqueSample(
147      kUIDismissalReasonMetric,
148      password_manager::metrics_util::CLICKED_NOPE,
149      1);
150}
151
152TEST_F(ManagePasswordsBubbleModelTest, ClickNever) {
153  base::HistogramTester histogram_tester;
154  PretendPasswordWaiting();
155  model_->OnNeverForThisSiteClicked();
156  model_->OnBubbleHidden();
157  EXPECT_EQ(model_->dismissal_reason(),
158            password_manager::metrics_util::CLICKED_NEVER);
159  EXPECT_EQ(password_manager::ui::BLACKLIST_STATE, model_->state());
160  EXPECT_FALSE(controller()->saved_password());
161  EXPECT_TRUE(controller()->never_saved_password());
162
163  histogram_tester.ExpectUniqueSample(
164      kUIDismissalReasonMetric,
165      password_manager::metrics_util::CLICKED_NEVER,
166      1);
167}
168
169TEST_F(ManagePasswordsBubbleModelTest, ClickManage) {
170  base::HistogramTester histogram_tester;
171  PretendManagingPasswords();
172  model_->OnManageLinkClicked();
173  model_->OnBubbleHidden();
174  EXPECT_EQ(model_->dismissal_reason(),
175            password_manager::metrics_util::CLICKED_MANAGE);
176  EXPECT_EQ(password_manager::ui::MANAGE_STATE, model_->state());
177  EXPECT_FALSE(controller()->saved_password());
178  EXPECT_FALSE(controller()->never_saved_password());
179
180  histogram_tester.ExpectUniqueSample(
181      kUIDismissalReasonMetric,
182      password_manager::metrics_util::CLICKED_MANAGE,
183      1);
184}
185
186TEST_F(ManagePasswordsBubbleModelTest, ClickDone) {
187  base::HistogramTester histogram_tester;
188  PretendManagingPasswords();
189  model_->OnDoneClicked();
190  model_->OnBubbleHidden();
191  EXPECT_EQ(model_->dismissal_reason(),
192            password_manager::metrics_util::CLICKED_DONE);
193  EXPECT_EQ(password_manager::ui::MANAGE_STATE, model_->state());
194  EXPECT_FALSE(controller()->saved_password());
195  EXPECT_FALSE(controller()->never_saved_password());
196
197  histogram_tester.ExpectUniqueSample(
198      kUIDismissalReasonMetric,
199      password_manager::metrics_util::CLICKED_DONE,
200      1);
201}
202
203TEST_F(ManagePasswordsBubbleModelTest, ClickUnblacklist) {
204  base::HistogramTester histogram_tester;
205  PretendBlacklisted();
206  model_->OnUnblacklistClicked();
207  model_->OnBubbleHidden();
208  EXPECT_EQ(model_->dismissal_reason(),
209            password_manager::metrics_util::CLICKED_UNBLACKLIST);
210  EXPECT_EQ(password_manager::ui::MANAGE_STATE, model_->state());
211  EXPECT_FALSE(controller()->saved_password());
212  EXPECT_FALSE(controller()->never_saved_password());
213
214  histogram_tester.ExpectUniqueSample(
215      kUIDismissalReasonMetric,
216      password_manager::metrics_util::CLICKED_UNBLACKLIST,
217      1);
218}
219
220TEST_F(ManagePasswordsBubbleModelTest, PasswordPendingUserDecision) {
221  EXPECT_FALSE(password_manager::ui::IsPendingState(model_->state()));
222
223  model_->set_state(password_manager::ui::INACTIVE_STATE);
224  EXPECT_FALSE(password_manager::ui::IsPendingState(model_->state()));
225  model_->set_state(password_manager::ui::MANAGE_STATE);
226  EXPECT_FALSE(password_manager::ui::IsPendingState(model_->state()));
227  model_->set_state(password_manager::ui::BLACKLIST_STATE);
228  EXPECT_FALSE(password_manager::ui::IsPendingState(model_->state()));
229
230  model_->set_state(password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE);
231  EXPECT_TRUE(password_manager::ui::IsPendingState(model_->state()));
232  model_->set_state(password_manager::ui::PENDING_PASSWORD_STATE);
233  EXPECT_TRUE(password_manager::ui::IsPendingState(model_->state()));
234}
235