[sql] Remove _HAS_EXCEPTIONS=0 from build info.
[chromium-blink-merge.git] / chrome / browser / password_manager / chrome_password_manager_client_unittest.cc
blob04f82835b790b4040417afa2e39df62353811cdd
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/prefs/pref_registry_simple.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/prefs/testing_pref_service.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/sync/profile_sync_service_factory.h"
14 #include "chrome/browser/sync/profile_sync_service_mock.h"
15 #include "chrome/common/channel_info.h"
16 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
17 #include "chrome/test/base/testing_pref_service_syncable.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/log_receiver.h"
23 #include "components/password_manager/core/browser/password_manager_internals_service.h"
24 #include "components/password_manager/core/common/credential_manager_types.h"
25 #include "components/password_manager/core/common/password_manager_pref_names.h"
26 #include "components/password_manager/core/common/password_manager_switches.h"
27 #include "components/version_info/version_info.h"
28 #include "content/public/browser/browser_context.h"
29 #include "content/public/browser/web_contents.h"
30 #include "content/public/test/mock_render_process_host.h"
31 #include "testing/gmock/include/gmock/gmock.h"
32 #include "testing/gtest/include/gtest/gtest.h"
34 using content::BrowserContext;
35 using content::WebContents;
36 using testing::Return;
37 using testing::_;
39 namespace {
41 const char kTestText[] = "abcd1234";
43 class MockLogReceiver : public password_manager::LogReceiver {
44 public:
45 MOCK_METHOD1(LogSavePasswordProgress, void(const std::string&));
48 // TODO(vabr): Get rid of the mocked client in the client's own test, see
49 // http://crbug.com/474577.
50 class MockChromePasswordManagerClient : public ChromePasswordManagerClient {
51 public:
52 MOCK_CONST_METHOD0(IsPasswordManagementEnabledForCurrentPage, bool());
53 MOCK_CONST_METHOD0(DidLastPageLoadEncounterSSLErrors, bool());
54 MOCK_CONST_METHOD2(IsSyncAccountCredential,
55 bool(const std::string& username,
56 const std::string& origin));
58 explicit MockChromePasswordManagerClient(content::WebContents* web_contents)
59 : ChromePasswordManagerClient(web_contents, nullptr) {
60 ON_CALL(*this, DidLastPageLoadEncounterSSLErrors())
61 .WillByDefault(testing::Return(false));
62 ON_CALL(*this, IsPasswordManagementEnabledForCurrentPage())
63 .WillByDefault(testing::Return(true));
65 ~MockChromePasswordManagerClient() override {}
67 private:
68 DISALLOW_COPY_AND_ASSIGN(MockChromePasswordManagerClient);
71 } // namespace
73 class ChromePasswordManagerClientTest : public ChromeRenderViewHostTestHarness {
74 public:
75 ChromePasswordManagerClientTest();
77 void SetUp() override;
79 TestingPrefServiceSyncable* prefs() {
80 return profile()->GetTestingPrefService();
83 protected:
84 ChromePasswordManagerClient* GetClient();
86 // If the test IPC sink contains an AutofillMsg_SetLoggingState message, then
87 // copies its argument into |activation_flag| and returns true. Otherwise
88 // returns false.
89 bool WasLoggingActivationMessageSent(bool* activation_flag);
91 password_manager::PasswordManagerInternalsService* service_;
93 testing::StrictMock<MockLogReceiver> receiver_;
94 TestingPrefServiceSimple prefs_;
97 ChromePasswordManagerClientTest::ChromePasswordManagerClientTest()
98 : service_(nullptr) {
101 void ChromePasswordManagerClientTest::SetUp() {
102 ChromeRenderViewHostTestHarness::SetUp();
103 prefs_.registry()->RegisterBooleanPref(
104 password_manager::prefs::kPasswordManagerSavingEnabled, true);
105 ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient(
106 web_contents(), nullptr);
107 service_ = password_manager::PasswordManagerInternalsServiceFactory::
108 GetForBrowserContext(profile());
109 ASSERT_TRUE(service_);
112 ChromePasswordManagerClient* ChromePasswordManagerClientTest::GetClient() {
113 return ChromePasswordManagerClient::FromWebContents(web_contents());
116 bool ChromePasswordManagerClientTest::WasLoggingActivationMessageSent(
117 bool* activation_flag) {
118 const uint32 kMsgID = AutofillMsg_SetLoggingState::ID;
119 const IPC::Message* message =
120 process()->sink().GetFirstMessageMatching(kMsgID);
121 if (!message)
122 return false;
123 base::Tuple<bool> param;
124 AutofillMsg_SetLoggingState::Read(message, &param);
125 *activation_flag = base::get<0>(param);
126 process()->sink().ClearMessages();
127 return true;
130 TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressNoReceiver) {
131 ChromePasswordManagerClient* client = GetClient();
133 EXPECT_CALL(receiver_, LogSavePasswordProgress(kTestText)).Times(0);
134 // Before attaching the receiver, no text should be passed.
135 client->LogSavePasswordProgress(kTestText);
136 EXPECT_FALSE(client->IsLoggingActive());
139 TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressAttachReceiver) {
140 ChromePasswordManagerClient* client = GetClient();
141 EXPECT_FALSE(client->IsLoggingActive());
143 // After attaching the logger, text should be passed.
144 service_->RegisterReceiver(&receiver_);
145 EXPECT_TRUE(client->IsLoggingActive());
146 EXPECT_CALL(receiver_, LogSavePasswordProgress(kTestText)).Times(1);
147 client->LogSavePasswordProgress(kTestText);
148 service_->UnregisterReceiver(&receiver_);
149 EXPECT_FALSE(client->IsLoggingActive());
152 TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressDetachReceiver) {
153 ChromePasswordManagerClient* client = GetClient();
155 service_->RegisterReceiver(&receiver_);
156 EXPECT_TRUE(client->IsLoggingActive());
157 service_->UnregisterReceiver(&receiver_);
158 EXPECT_FALSE(client->IsLoggingActive());
160 // After detaching the logger, no text should be passed.
161 EXPECT_CALL(receiver_, LogSavePasswordProgress(kTestText)).Times(0);
162 client->LogSavePasswordProgress(kTestText);
165 TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressNotifyRenderer) {
166 ChromePasswordManagerClient* client = GetClient();
167 bool logging_active = false;
169 // Initially, the logging should be off, so no IPC messages.
170 EXPECT_FALSE(WasLoggingActivationMessageSent(&logging_active));
172 service_->RegisterReceiver(&receiver_);
173 EXPECT_TRUE(client->IsLoggingActive());
174 EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active));
175 EXPECT_TRUE(logging_active);
177 service_->UnregisterReceiver(&receiver_);
178 EXPECT_FALSE(client->IsLoggingActive());
179 EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active));
180 EXPECT_FALSE(logging_active);
183 TEST_F(ChromePasswordManagerClientTest, AnswerToPingsAboutLoggingState_Active) {
184 service_->RegisterReceiver(&receiver_);
186 process()->sink().ClearMessages();
188 // Ping the client for logging activity update.
189 AutofillHostMsg_PasswordAutofillAgentConstructed msg(0);
190 static_cast<content::WebContentsObserver*>(GetClient())->OnMessageReceived(
191 msg, web_contents()->GetMainFrame());
193 bool logging_active = false;
194 EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active));
195 EXPECT_TRUE(logging_active);
197 service_->UnregisterReceiver(&receiver_);
200 TEST_F(ChromePasswordManagerClientTest,
201 AnswerToPingsAboutLoggingState_Inactive) {
202 process()->sink().ClearMessages();
204 // Ping the client for logging activity update.
205 AutofillHostMsg_PasswordAutofillAgentConstructed msg(0);
206 static_cast<content::WebContentsObserver*>(GetClient())->OnMessageReceived(
207 msg, web_contents()->GetMainFrame());
209 bool logging_active = true;
210 EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active));
211 EXPECT_FALSE(logging_active);
214 TEST_F(ChromePasswordManagerClientTest,
215 IsAutomaticPasswordSavingEnabledDefaultBehaviourTest) {
216 EXPECT_FALSE(GetClient()->IsAutomaticPasswordSavingEnabled());
219 TEST_F(ChromePasswordManagerClientTest,
220 IsAutomaticPasswordSavingEnabledWhenFlagIsSetTest) {
221 base::CommandLine::ForCurrentProcess()->AppendSwitch(
222 password_manager::switches::kEnableAutomaticPasswordSaving);
223 if (chrome::GetChannel() == version_info::Channel::UNKNOWN)
224 EXPECT_TRUE(GetClient()->IsAutomaticPasswordSavingEnabled());
225 else
226 EXPECT_FALSE(GetClient()->IsAutomaticPasswordSavingEnabled());
229 TEST_F(ChromePasswordManagerClientTest, LogToAReceiver) {
230 ChromePasswordManagerClient* client = GetClient();
231 service_->RegisterReceiver(&receiver_);
232 EXPECT_TRUE(client->IsLoggingActive());
234 EXPECT_CALL(receiver_, LogSavePasswordProgress(kTestText)).Times(1);
235 client->LogSavePasswordProgress(kTestText);
237 service_->UnregisterReceiver(&receiver_);
238 EXPECT_FALSE(client->IsLoggingActive());
241 TEST_F(ChromePasswordManagerClientTest, ShouldFilterAutofillResult_Reauth) {
242 // Make client disallow only reauth requests.
243 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
244 command_line->AppendSwitch(
245 password_manager::switches::kDisallowAutofillSyncCredentialForReauth);
246 scoped_ptr<MockChromePasswordManagerClient> client(
247 new MockChromePasswordManagerClient(web_contents()));
248 autofill::PasswordForm form;
250 EXPECT_CALL(*client, IsSyncAccountCredential(_, _))
251 .WillRepeatedly(Return(false));
252 NavigateAndCommit(
253 GURL("https://accounts.google.com/login?rart=123&continue=blah"));
254 EXPECT_FALSE(client->ShouldFilterAutofillResult(form));
256 EXPECT_CALL(*client, IsSyncAccountCredential(_, _))
257 .WillRepeatedly(Return(true));
258 NavigateAndCommit(
259 GURL("https://accounts.google.com/login?rart=123&continue=blah"));
260 EXPECT_TRUE(client->ShouldFilterAutofillResult(form));
262 // This counts as a reauth url, though a valid URL should have a value for
263 // "rart"
264 NavigateAndCommit(GURL("https://accounts.google.com/addlogin?rart"));
265 EXPECT_TRUE(client->ShouldFilterAutofillResult(form));
267 NavigateAndCommit(GURL("https://accounts.google.com/login?param=123"));
268 EXPECT_FALSE(client->ShouldFilterAutofillResult(form));
270 NavigateAndCommit(GURL("https://site.com/login?rart=678"));
271 EXPECT_FALSE(client->ShouldFilterAutofillResult(form));
274 TEST_F(ChromePasswordManagerClientTest, ShouldFilterAutofillResult) {
275 // Normally the client should allow any credentials through, even if they
276 // are the sync credential.
277 scoped_ptr<MockChromePasswordManagerClient> client(
278 new MockChromePasswordManagerClient(web_contents()));
279 autofill::PasswordForm form;
280 EXPECT_CALL(*client, IsSyncAccountCredential(_, _))
281 .WillRepeatedly(Return(true));
282 NavigateAndCommit(GURL("https://accounts.google.com/Login"));
283 EXPECT_FALSE(client->ShouldFilterAutofillResult(form));
285 // Adding disallow switch should cause sync credential to be filtered.
286 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
287 command_line->AppendSwitch(
288 password_manager::switches::kDisallowAutofillSyncCredential);
289 client.reset(new MockChromePasswordManagerClient(web_contents()));
290 EXPECT_CALL(*client, IsSyncAccountCredential(_, _))
291 .WillRepeatedly(Return(true));
292 NavigateAndCommit(GURL("https://accounts.google.com/Login"));
293 EXPECT_TRUE(client->ShouldFilterAutofillResult(form));
296 TEST_F(ChromePasswordManagerClientTest,
297 IsPasswordManagementEnabledForCurrentPage) {
298 ChromePasswordManagerClient* client = GetClient();
299 NavigateAndCommit(
300 GURL("https://accounts.google.com/ServiceLogin?continue="
301 "https://passwords.google.com/settings&rart=123"));
302 EXPECT_FALSE(client->IsPasswordManagementEnabledForCurrentPage());
304 // Password site is inaccesible via HTTP, but because of HSTS the following
305 // link should still continue to https://passwords.google.com.
306 NavigateAndCommit(
307 GURL("https://accounts.google.com/ServiceLogin?continue="
308 "http://passwords.google.com/settings&rart=123"));
309 EXPECT_FALSE(client->IsPasswordManagementEnabledForCurrentPage());
310 EXPECT_FALSE(client->IsSavingEnabledForCurrentPage());
312 // Specifying default port still passes.
313 NavigateAndCommit(
314 GURL("https://accounts.google.com/ServiceLogin?continue="
315 "https://passwords.google.com:443/settings&rart=123"));
316 EXPECT_FALSE(client->IsPasswordManagementEnabledForCurrentPage());
317 EXPECT_FALSE(client->IsSavingEnabledForCurrentPage());
319 // Encoded URL is considered the same.
320 NavigateAndCommit(
321 GURL("https://accounts.google.com/ServiceLogin?continue="
322 "https://passwords.%67oogle.com/settings&rart=123"));
323 EXPECT_FALSE(client->IsPasswordManagementEnabledForCurrentPage());
324 EXPECT_FALSE(client->IsSavingEnabledForCurrentPage());
326 // Make sure testing sites are disabled as well.
327 NavigateAndCommit(
328 GURL("https://accounts.google.com/Login?continue="
329 "https://passwords-ac-testing.corp.google.com/settings&rart=456"));
330 EXPECT_FALSE(client->IsSavingEnabledForCurrentPage());
331 EXPECT_FALSE(client->IsPasswordManagementEnabledForCurrentPage());
333 // Fully qualified domain name is considered a different hostname by GURL.
334 // Ideally this would not be the case, but this quirk can be avoided by
335 // verification on the server. This test is simply documentation of this
336 // behavior.
337 NavigateAndCommit(
338 GURL("https://accounts.google.com/ServiceLogin?continue="
339 "https://passwords.google.com./settings&rart=123"));
340 EXPECT_TRUE(client->IsPasswordManagementEnabledForCurrentPage());
342 // Not a transactional reauth page.
343 NavigateAndCommit(
344 GURL("https://accounts.google.com/ServiceLogin?continue="
345 "https://passwords.google.com/settings"));
346 EXPECT_TRUE(client->IsPasswordManagementEnabledForCurrentPage());
348 // Should be enabled for other transactional reauth pages.
349 NavigateAndCommit(
350 GURL("https://accounts.google.com/ServiceLogin?continue="
351 "https://mail.google.com&rart=234"));
352 EXPECT_TRUE(client->IsPasswordManagementEnabledForCurrentPage());
354 // Reauth pages are only on accounts.google.com
355 NavigateAndCommit(
356 GURL("https://other.site.com/ServiceLogin?continue="
357 "https://passwords.google.com&rart=234"));
358 EXPECT_TRUE(client->IsPasswordManagementEnabledForCurrentPage());
361 TEST_F(ChromePasswordManagerClientTest, GetPasswordSyncState) {
362 ChromePasswordManagerClient* client = GetClient();
364 ProfileSyncServiceMock* mock_sync_service =
365 static_cast<ProfileSyncServiceMock*>(
366 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
367 profile(), ProfileSyncServiceMock::BuildMockProfileSyncService));
369 syncer::ModelTypeSet active_types;
370 active_types.Put(syncer::PASSWORDS);
371 EXPECT_CALL(*mock_sync_service, HasSyncSetupCompleted())
372 .WillRepeatedly(Return(true));
373 EXPECT_CALL(*mock_sync_service, IsSyncActive()).WillRepeatedly(Return(true));
374 EXPECT_CALL(*mock_sync_service, GetActiveDataTypes())
375 .WillRepeatedly(Return(active_types));
376 EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase())
377 .WillRepeatedly(Return(false));
379 // Passwords are syncing and custom passphrase isn't used.
380 EXPECT_EQ(password_manager::SYNCING_NORMAL_ENCRYPTION,
381 client->GetPasswordSyncState());
383 // Again, using a custom passphrase.
384 EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase())
385 .WillRepeatedly(Return(true));
387 EXPECT_EQ(password_manager::SYNCING_WITH_CUSTOM_PASSPHRASE,
388 client->GetPasswordSyncState());
390 // Report correctly if we aren't syncing passwords.
391 active_types.Remove(syncer::PASSWORDS);
392 active_types.Put(syncer::BOOKMARKS);
393 EXPECT_CALL(*mock_sync_service, GetActiveDataTypes())
394 .WillRepeatedly(Return(active_types));
396 EXPECT_EQ(password_manager::NOT_SYNCING_PASSWORDS,
397 client->GetPasswordSyncState());
399 // Again, without a custom passphrase.
400 EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase())
401 .WillRepeatedly(Return(false));
403 EXPECT_EQ(password_manager::NOT_SYNCING_PASSWORDS,
404 client->GetPasswordSyncState());
407 TEST_F(ChromePasswordManagerClientTest, IsOffTheRecordTest) {
408 ChromePasswordManagerClient* client = GetClient();
410 profile()->ForceIncognito(true);
411 EXPECT_TRUE(client->IsOffTheRecord());
413 profile()->ForceIncognito(false);
414 EXPECT_FALSE(client->IsOffTheRecord());
417 TEST_F(ChromePasswordManagerClientTest,
418 SavingDependsOnManagerEnabledPreference) {
419 // Test that saving passwords depends on the password manager enabled
420 // preference.
421 ChromePasswordManagerClient* client = GetClient();
422 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled,
423 new base::FundamentalValue(true));
424 EXPECT_TRUE(client->IsSavingEnabledForCurrentPage());
425 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled,
426 new base::FundamentalValue(false));
427 EXPECT_FALSE(client->IsSavingEnabledForCurrentPage());
430 TEST_F(ChromePasswordManagerClientTest, IsSavingEnabledForCurrentPageTest) {
431 scoped_ptr<MockChromePasswordManagerClient> client(
432 new MockChromePasswordManagerClient(web_contents()));
433 // Functionality disabled if there is SSL errors.
434 EXPECT_CALL(*client, DidLastPageLoadEncounterSSLErrors())
435 .WillRepeatedly(Return(true));
436 EXPECT_FALSE(client->IsSavingEnabledForCurrentPage());
438 // Functionality disabled if there are SSL errors and the manager itself is
439 // disabled.
440 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled,
441 new base::FundamentalValue(false));
442 EXPECT_FALSE(client->IsSavingEnabledForCurrentPage());
444 // Functionality disabled if there are no SSL errorsm, but the manager itself
445 // is disabled.
446 EXPECT_CALL(*client, DidLastPageLoadEncounterSSLErrors())
447 .WillRepeatedly(Return(false));
448 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled,
449 new base::FundamentalValue(false));
450 EXPECT_FALSE(client->IsSavingEnabledForCurrentPage());
452 // Functionality enabled if there are no SSL errors and the manager is
453 // enabled.
454 EXPECT_CALL(*client, DidLastPageLoadEncounterSSLErrors())
455 .WillRepeatedly(Return(false));
456 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled,
457 new base::FundamentalValue(true));
458 EXPECT_TRUE(client->IsSavingEnabledForCurrentPage());
460 // Functionality disabled in Incognito mode.
461 profile()->ForceIncognito(true);
462 EXPECT_FALSE(client->IsSavingEnabledForCurrentPage());
464 // Functionality disabled in Incognito mode also when manager itself is
465 // enabled.
466 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled,
467 new base::FundamentalValue(true));
468 EXPECT_FALSE(client->IsSavingEnabledForCurrentPage());
469 profile()->ForceIncognito(false);