Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / password_manager / chrome_password_manager_client_unittest.cc
blob366f00159235633215c5565f53d52e4904a3360e
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/password_manager/chrome_password_manager_client.h"
7 #include "base/command_line.h"
8 #include "base/metrics/field_trial.h"
9 #include "base/prefs/pref_registry_simple.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/prefs/testing_pref_service.h"
12 #include "base/strings/string16.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/sync/profile_sync_service_factory.h"
15 #include "chrome/browser/sync/profile_sync_service_mock.h"
16 #include "chrome/common/channel_info.h"
17 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
18 #include "chrome/test/base/testing_profile.h"
19 #include "components/autofill/content/common/autofill_messages.h"
20 #include "components/password_manager/content/browser/password_manager_internals_service_factory.h"
21 #include "components/password_manager/content/common/credential_manager_messages.h"
22 #include "components/password_manager/core/browser/credentials_filter.h"
23 #include "components/password_manager/core/browser/log_receiver.h"
24 #include "components/password_manager/core/browser/password_manager_internals_service.h"
25 #include "components/password_manager/core/common/credential_manager_types.h"
26 #include "components/password_manager/core/common/password_manager_pref_names.h"
27 #include "components/password_manager/core/common/password_manager_switches.h"
28 #include "components/syncable_prefs/testing_pref_service_syncable.h"
29 #include "components/version_info/version_info.h"
30 #include "content/public/browser/browser_context.h"
31 #include "content/public/browser/web_contents.h"
32 #include "content/public/test/mock_render_process_host.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h"
36 using content::BrowserContext;
37 using content::WebContents;
38 using testing::Return;
39 using testing::_;
41 namespace {
43 const char kPasswordManagerSettingsBehaviourChangeFieldTrialName[] =
44 "PasswordManagerSettingsBehaviourChange";
45 const char kPasswordManagerSettingsBehaviourChangeEnabledGroupName[] =
46 "PasswordManagerSettingsBehaviourChange.Active";
47 const char kPasswordManagerSettingsBehaviourChangeDisabledGroupName[] =
48 "PasswordManagerSettingsBehaviourChange.NotActive";
50 const char kTestText[] = "abcd1234";
52 class MockLogReceiver : public password_manager::LogReceiver {
53 public:
54 MOCK_METHOD1(LogSavePasswordProgress, void(const std::string&));
57 // TODO(vabr): Get rid of the mocked client in the client's own test, see
58 // http://crbug.com/474577.
59 class MockChromePasswordManagerClient : public ChromePasswordManagerClient {
60 public:
61 MOCK_CONST_METHOD0(DidLastPageLoadEncounterSSLErrors, bool());
63 explicit MockChromePasswordManagerClient(content::WebContents* web_contents)
64 : ChromePasswordManagerClient(web_contents, nullptr) {
65 ON_CALL(*this, DidLastPageLoadEncounterSSLErrors())
66 .WillByDefault(testing::Return(false));
68 ~MockChromePasswordManagerClient() override {}
70 private:
71 DISALLOW_COPY_AND_ASSIGN(MockChromePasswordManagerClient);
74 } // namespace
76 class ChromePasswordManagerClientTest : public ChromeRenderViewHostTestHarness {
77 public:
78 ChromePasswordManagerClientTest()
79 : service_(nullptr), field_trial_list_(nullptr) {}
80 void SetUp() override;
82 syncable_prefs::TestingPrefServiceSyncable* prefs() {
83 return profile()->GetTestingPrefService();
86 void EnforcePasswordManagerSettingsBehaviourChangeExperimentGroup(
87 const char* name) {
88 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
89 kPasswordManagerSettingsBehaviourChangeFieldTrialName, name));
92 protected:
93 ChromePasswordManagerClient* GetClient();
95 // If the test IPC sink contains an AutofillMsg_SetLoggingState message, then
96 // copies its argument into |activation_flag| and returns true. Otherwise
97 // returns false.
98 bool WasLoggingActivationMessageSent(bool* activation_flag);
100 password_manager::PasswordManagerInternalsService* service_;
102 testing::StrictMock<MockLogReceiver> receiver_;
103 TestingPrefServiceSimple prefs_;
104 base::FieldTrialList field_trial_list_;
107 void ChromePasswordManagerClientTest::SetUp() {
108 ChromeRenderViewHostTestHarness::SetUp();
109 prefs_.registry()->RegisterBooleanPref(
110 password_manager::prefs::kPasswordManagerSavingEnabled, true);
111 ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient(
112 web_contents(), nullptr);
113 service_ = password_manager::PasswordManagerInternalsServiceFactory::
114 GetForBrowserContext(profile());
115 ASSERT_TRUE(service_);
118 ChromePasswordManagerClient* ChromePasswordManagerClientTest::GetClient() {
119 return ChromePasswordManagerClient::FromWebContents(web_contents());
122 bool ChromePasswordManagerClientTest::WasLoggingActivationMessageSent(
123 bool* activation_flag) {
124 const uint32 kMsgID = AutofillMsg_SetLoggingState::ID;
125 const IPC::Message* message =
126 process()->sink().GetFirstMessageMatching(kMsgID);
127 if (!message)
128 return false;
129 base::Tuple<bool> param;
130 AutofillMsg_SetLoggingState::Read(message, &param);
131 *activation_flag = base::get<0>(param);
132 process()->sink().ClearMessages();
133 return true;
136 TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressNoReceiver) {
137 ChromePasswordManagerClient* client = GetClient();
139 EXPECT_CALL(receiver_, LogSavePasswordProgress(kTestText)).Times(0);
140 // Before attaching the receiver, no text should be passed.
141 client->LogSavePasswordProgress(kTestText);
142 EXPECT_FALSE(client->IsLoggingActive());
145 TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressAttachReceiver) {
146 ChromePasswordManagerClient* client = GetClient();
147 EXPECT_FALSE(client->IsLoggingActive());
149 // After attaching the logger, text should be passed.
150 service_->RegisterReceiver(&receiver_);
151 EXPECT_TRUE(client->IsLoggingActive());
152 EXPECT_CALL(receiver_, LogSavePasswordProgress(kTestText)).Times(1);
153 client->LogSavePasswordProgress(kTestText);
154 service_->UnregisterReceiver(&receiver_);
155 EXPECT_FALSE(client->IsLoggingActive());
158 TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressDetachReceiver) {
159 ChromePasswordManagerClient* client = GetClient();
161 service_->RegisterReceiver(&receiver_);
162 EXPECT_TRUE(client->IsLoggingActive());
163 service_->UnregisterReceiver(&receiver_);
164 EXPECT_FALSE(client->IsLoggingActive());
166 // After detaching the logger, no text should be passed.
167 EXPECT_CALL(receiver_, LogSavePasswordProgress(kTestText)).Times(0);
168 client->LogSavePasswordProgress(kTestText);
171 TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressNotifyRenderer) {
172 ChromePasswordManagerClient* client = GetClient();
173 bool logging_active = false;
175 // Initially, the logging should be off, so no IPC messages.
176 EXPECT_FALSE(WasLoggingActivationMessageSent(&logging_active));
178 service_->RegisterReceiver(&receiver_);
179 EXPECT_TRUE(client->IsLoggingActive());
180 EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active));
181 EXPECT_TRUE(logging_active);
183 service_->UnregisterReceiver(&receiver_);
184 EXPECT_FALSE(client->IsLoggingActive());
185 EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active));
186 EXPECT_FALSE(logging_active);
189 TEST_F(ChromePasswordManagerClientTest, AnswerToPingsAboutLoggingState_Active) {
190 service_->RegisterReceiver(&receiver_);
192 process()->sink().ClearMessages();
194 // Ping the client for logging activity update.
195 AutofillHostMsg_PasswordAutofillAgentConstructed msg(0);
196 static_cast<content::WebContentsObserver*>(GetClient())->OnMessageReceived(
197 msg, web_contents()->GetMainFrame());
199 bool logging_active = false;
200 EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active));
201 EXPECT_TRUE(logging_active);
203 service_->UnregisterReceiver(&receiver_);
206 TEST_F(ChromePasswordManagerClientTest,
207 AnswerToPingsAboutLoggingState_Inactive) {
208 process()->sink().ClearMessages();
210 // Ping the client for logging activity update.
211 AutofillHostMsg_PasswordAutofillAgentConstructed msg(0);
212 static_cast<content::WebContentsObserver*>(GetClient())->OnMessageReceived(
213 msg, web_contents()->GetMainFrame());
215 bool logging_active = true;
216 EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active));
217 EXPECT_FALSE(logging_active);
220 TEST_F(ChromePasswordManagerClientTest,
221 IsAutomaticPasswordSavingEnabledDefaultBehaviourTest) {
222 EXPECT_FALSE(GetClient()->IsAutomaticPasswordSavingEnabled());
225 TEST_F(ChromePasswordManagerClientTest,
226 IsAutomaticPasswordSavingEnabledWhenFlagIsSetTest) {
227 base::CommandLine::ForCurrentProcess()->AppendSwitch(
228 password_manager::switches::kEnableAutomaticPasswordSaving);
229 if (chrome::GetChannel() == version_info::Channel::UNKNOWN)
230 EXPECT_TRUE(GetClient()->IsAutomaticPasswordSavingEnabled());
231 else
232 EXPECT_FALSE(GetClient()->IsAutomaticPasswordSavingEnabled());
235 TEST_F(ChromePasswordManagerClientTest, LogToAReceiver) {
236 ChromePasswordManagerClient* client = GetClient();
237 service_->RegisterReceiver(&receiver_);
238 EXPECT_TRUE(client->IsLoggingActive());
240 EXPECT_CALL(receiver_, LogSavePasswordProgress(kTestText)).Times(1);
241 client->LogSavePasswordProgress(kTestText);
243 service_->UnregisterReceiver(&receiver_);
244 EXPECT_FALSE(client->IsLoggingActive());
247 TEST_F(ChromePasswordManagerClientTest, IsFillingEnabledForCurrentPage) {
248 ChromePasswordManagerClient* client = GetClient();
249 NavigateAndCommit(
250 GURL("https://accounts.google.com/ServiceLogin?continue="
251 "https://passwords.google.com/settings&rart=123"));
252 EXPECT_FALSE(client->IsFillingEnabledForCurrentPage());
254 // Password site is inaccesible via HTTP, but because of HSTS the following
255 // link should still continue to https://passwords.google.com.
256 NavigateAndCommit(
257 GURL("https://accounts.google.com/ServiceLogin?continue="
258 "http://passwords.google.com/settings&rart=123"));
259 EXPECT_FALSE(client->IsSavingAndFillingEnabledForCurrentPage());
260 EXPECT_FALSE(client->IsFillingEnabledForCurrentPage());
262 // Specifying default port still passes.
263 NavigateAndCommit(
264 GURL("https://accounts.google.com/ServiceLogin?continue="
265 "https://passwords.google.com:443/settings&rart=123"));
266 EXPECT_FALSE(client->IsSavingAndFillingEnabledForCurrentPage());
267 EXPECT_FALSE(client->IsFillingEnabledForCurrentPage());
269 // Encoded URL is considered the same.
270 NavigateAndCommit(
271 GURL("https://accounts.google.com/ServiceLogin?continue="
272 "https://passwords.%67oogle.com/settings&rart=123"));
273 EXPECT_FALSE(client->IsSavingAndFillingEnabledForCurrentPage());
274 EXPECT_FALSE(client->IsFillingEnabledForCurrentPage());
276 // Make sure testing sites are disabled as well.
277 NavigateAndCommit(
278 GURL("https://accounts.google.com/Login?continue="
279 "https://passwords-ac-testing.corp.google.com/settings&rart=456"));
280 EXPECT_FALSE(client->IsFillingEnabledForCurrentPage());
282 // Fully qualified domain name is considered a different hostname by GURL.
283 // Ideally this would not be the case, but this quirk can be avoided by
284 // verification on the server. This test is simply documentation of this
285 // behavior.
286 NavigateAndCommit(
287 GURL("https://accounts.google.com/ServiceLogin?continue="
288 "https://passwords.google.com./settings&rart=123"));
289 EXPECT_TRUE(client->IsFillingEnabledForCurrentPage());
291 // Not a transactional reauth page.
292 NavigateAndCommit(
293 GURL("https://accounts.google.com/ServiceLogin?continue="
294 "https://passwords.google.com/settings"));
295 EXPECT_TRUE(client->IsFillingEnabledForCurrentPage());
297 // Should be enabled for other transactional reauth pages.
298 NavigateAndCommit(
299 GURL("https://accounts.google.com/ServiceLogin?continue="
300 "https://mail.google.com&rart=234"));
301 EXPECT_TRUE(client->IsFillingEnabledForCurrentPage());
303 // Reauth pages are only on accounts.google.com
304 NavigateAndCommit(
305 GURL("https://other.site.com/ServiceLogin?continue="
306 "https://passwords.google.com&rart=234"));
307 EXPECT_TRUE(client->IsFillingEnabledForCurrentPage());
310 TEST_F(ChromePasswordManagerClientTest, GetPasswordSyncState) {
311 ChromePasswordManagerClient* client = GetClient();
313 ProfileSyncServiceMock* mock_sync_service =
314 static_cast<ProfileSyncServiceMock*>(
315 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
316 profile(), ProfileSyncServiceMock::BuildMockProfileSyncService));
318 syncer::ModelTypeSet active_types;
319 active_types.Put(syncer::PASSWORDS);
320 EXPECT_CALL(*mock_sync_service, HasSyncSetupCompleted())
321 .WillRepeatedly(Return(true));
322 EXPECT_CALL(*mock_sync_service, IsSyncActive()).WillRepeatedly(Return(true));
323 EXPECT_CALL(*mock_sync_service, GetActiveDataTypes())
324 .WillRepeatedly(Return(active_types));
325 EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase())
326 .WillRepeatedly(Return(false));
328 // Passwords are syncing and custom passphrase isn't used.
329 EXPECT_EQ(password_manager::SYNCING_NORMAL_ENCRYPTION,
330 client->GetPasswordSyncState());
332 // Again, using a custom passphrase.
333 EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase())
334 .WillRepeatedly(Return(true));
336 EXPECT_EQ(password_manager::SYNCING_WITH_CUSTOM_PASSPHRASE,
337 client->GetPasswordSyncState());
339 // Report correctly if we aren't syncing passwords.
340 active_types.Remove(syncer::PASSWORDS);
341 active_types.Put(syncer::BOOKMARKS);
342 EXPECT_CALL(*mock_sync_service, GetActiveDataTypes())
343 .WillRepeatedly(Return(active_types));
345 EXPECT_EQ(password_manager::NOT_SYNCING_PASSWORDS,
346 client->GetPasswordSyncState());
348 // Again, without a custom passphrase.
349 EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase())
350 .WillRepeatedly(Return(false));
352 EXPECT_EQ(password_manager::NOT_SYNCING_PASSWORDS,
353 client->GetPasswordSyncState());
356 TEST_F(ChromePasswordManagerClientTest, IsOffTheRecordTest) {
357 ChromePasswordManagerClient* client = GetClient();
359 profile()->ForceIncognito(true);
360 EXPECT_TRUE(client->IsOffTheRecord());
362 profile()->ForceIncognito(false);
363 EXPECT_FALSE(client->IsOffTheRecord());
366 TEST_F(ChromePasswordManagerClientTest,
367 SavingDependsOnManagerEnabledPreference) {
368 // Test that saving passwords depends on the password manager enabled
369 // preference.
370 ChromePasswordManagerClient* client = GetClient();
371 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled,
372 new base::FundamentalValue(true));
373 EXPECT_TRUE(client->IsSavingAndFillingEnabledForCurrentPage());
374 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled,
375 new base::FundamentalValue(false));
376 EXPECT_FALSE(client->IsSavingAndFillingEnabledForCurrentPage());
379 TEST_F(ChromePasswordManagerClientTest,
380 FillingDependsOnManagerEnabledPreferenceAndExperimentEnabled) {
381 // Test that filing of passwords depends on the password manager enabled
382 // preference and is the user participated in behavior change experiment.
383 ChromePasswordManagerClient* client = GetClient();
384 EnforcePasswordManagerSettingsBehaviourChangeExperimentGroup(
385 kPasswordManagerSettingsBehaviourChangeEnabledGroupName);
386 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled,
387 new base::FundamentalValue(true));
388 EXPECT_TRUE(client->IsSavingAndFillingEnabledForCurrentPage());
389 EXPECT_TRUE(client->IsFillingEnabledForCurrentPage());
390 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled,
391 new base::FundamentalValue(false));
392 EXPECT_FALSE(client->IsSavingAndFillingEnabledForCurrentPage());
393 EXPECT_FALSE(client->IsFillingEnabledForCurrentPage());
396 TEST_F(ChromePasswordManagerClientTest,
397 FillingDependsOnManagerEnabledPreferenceAndExperimentDisabled) {
398 // Test that filing of passwords depends on the password manager enabled
399 // preference and is the user participated in behavior change experiment.
400 ChromePasswordManagerClient* client = GetClient();
401 EnforcePasswordManagerSettingsBehaviourChangeExperimentGroup(
402 kPasswordManagerSettingsBehaviourChangeDisabledGroupName);
403 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled,
404 new base::FundamentalValue(true));
405 EXPECT_TRUE(client->IsFillingEnabledForCurrentPage());
406 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled,
407 new base::FundamentalValue(false));
408 EXPECT_TRUE(client->IsFillingEnabledForCurrentPage());
411 TEST_F(ChromePasswordManagerClientTest, SavingAndFillingEnabledConditionsTest) {
412 scoped_ptr<MockChromePasswordManagerClient> client(
413 new MockChromePasswordManagerClient(web_contents()));
414 // Functionality disabled if there is SSL errors.
415 EXPECT_CALL(*client, DidLastPageLoadEncounterSSLErrors())
416 .WillRepeatedly(Return(true));
417 EXPECT_FALSE(client->IsSavingAndFillingEnabledForCurrentPage());
418 EXPECT_FALSE(client->IsFillingEnabledForCurrentPage());
420 // Functionality disabled if there are SSL errors and the manager itself is
421 // disabled.
422 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled,
423 new base::FundamentalValue(false));
424 EXPECT_FALSE(client->IsSavingAndFillingEnabledForCurrentPage());
425 EXPECT_FALSE(client->IsFillingEnabledForCurrentPage());
427 // Functionality disabled if there are no SSL errors, but the manager itself
428 // is disabled.
429 EXPECT_CALL(*client, DidLastPageLoadEncounterSSLErrors())
430 .WillRepeatedly(Return(false));
431 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled,
432 new base::FundamentalValue(false));
433 EXPECT_FALSE(client->IsSavingAndFillingEnabledForCurrentPage());
434 EXPECT_TRUE(client->IsFillingEnabledForCurrentPage());
436 // Functionality enabled if there are no SSL errors and the manager is
437 // enabled.
438 EXPECT_CALL(*client, DidLastPageLoadEncounterSSLErrors())
439 .WillRepeatedly(Return(false));
440 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled,
441 new base::FundamentalValue(true));
442 EXPECT_TRUE(client->IsSavingAndFillingEnabledForCurrentPage());
443 EXPECT_TRUE(client->IsFillingEnabledForCurrentPage());
445 // Functionality disabled in Incognito mode.
446 profile()->ForceIncognito(true);
447 EXPECT_FALSE(client->IsSavingAndFillingEnabledForCurrentPage());
448 EXPECT_TRUE(client->IsFillingEnabledForCurrentPage());
450 // Functionality disabled in Incognito mode also when manager itself is
451 // enabled.
452 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled,
453 new base::FundamentalValue(true));
454 EXPECT_FALSE(client->IsSavingAndFillingEnabledForCurrentPage());
455 EXPECT_TRUE(client->IsFillingEnabledForCurrentPage());
456 profile()->ForceIncognito(false);
459 TEST_F(ChromePasswordManagerClientTest, GetLastCommittedEntryURL_Empty) {
460 EXPECT_EQ(GURL::EmptyGURL(), GetClient()->GetLastCommittedEntryURL());
463 TEST_F(ChromePasswordManagerClientTest, GetLastCommittedEntryURL) {
464 GURL kUrl(
465 "https://accounts.google.com/ServiceLogin?continue="
466 "https://passwords.google.com/settings&rart=123");
467 NavigateAndCommit(kUrl);
468 EXPECT_EQ(kUrl, GetClient()->GetLastCommittedEntryURL());