13dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <vector> 672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/message_loop.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/password_manager/password_manager.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/password_manager/password_manager_delegate.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/password_manager/password_store.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/testing_profile.h" 15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/test_render_view_host.h" 17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/test_tab_contents.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gmock/include/gmock/gmock.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing webkit_glue::PasswordForm; 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::_; 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::DoAll; 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing ::testing::Exactly; 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing ::testing::WithArg; 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing ::testing::Return; 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockPasswordManagerDelegate : public PasswordManagerDelegate { 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD1(FillPasswordForm, void( 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const webkit_glue::PasswordFormFillData&)); 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD1(AddSavePasswordInfoBar, void(PasswordFormManager*)); 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD0(GetProfileForPasswordManager, Profile*()); 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD0(DidLastPageLoadEncounterSSLErrors, bool()); 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TestingProfileWithPasswordStore : public TestingProfile { 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit TestingProfileWithPasswordStore(PasswordStore* store) 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : store_(store) {} 413dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen virtual ~TestingProfileWithPasswordStore() { 423dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen store_->Shutdown(); 433dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen } 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual PasswordStore* GetPasswordStore(ServiceAccessType access) { 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return store_; 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 483dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen scoped_refptr<PasswordStore> store_; 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockPasswordStore : public PasswordStore { 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD1(RemoveLogin, void(const PasswordForm&)); 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD2(GetLogins, int(const PasswordForm&, PasswordStoreConsumer*)); 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD1(AddLogin, void(const PasswordForm&)); 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD1(UpdateLogin, void(const PasswordForm&)); 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD0(ReportMetrics, void()); 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD0(ReportMetricsImpl, void()); 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD1(AddLoginImpl, void(const PasswordForm&)); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD1(UpdateLoginImpl, void(const PasswordForm&)); 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD1(RemoveLoginImpl, void(const PasswordForm&)); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD2(RemoveLoginsCreatedBetweenImpl, void(const base::Time&, 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const base::Time&)); 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD2(GetLoginsImpl, void(GetLoginsRequest*, const PasswordForm&)); 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD1(GetAutofillableLoginsImpl, void(GetLoginsRequest*)); 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD1(GetBlacklistLoginsImpl, void(GetLoginsRequest*)); 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD1(FillAutofillableLogins, 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool(std::vector<webkit_glue::PasswordForm*>*)); 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MOCK_METHOD1(FillBlacklistLogins, 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool(std::vector<webkit_glue::PasswordForm*>*)); 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochACTION_P2(InvokeConsumer, handle, forms) { 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch arg0->OnPasswordStoreRequestDone(handle, forms); 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochACTION_P(SaveToScopedPtr, scoped) { 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped->reset(arg0); 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenclass PasswordManagerTest : public RenderViewHostTestHarness { 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PasswordManagerTest() 84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : ui_thread_(BrowserThread::UI, MessageLoopForUI::current()) {} 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void SetUp() { 88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen RenderViewHostTestHarness::SetUp(); 89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch store_ = new MockPasswordStore(); 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_.reset(new TestingProfileWithPasswordStore(store_)); 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(delegate_, GetProfileForPasswordManager()) 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch .WillRepeatedly(Return(profile_.get())); 94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen manager_.reset(new PasswordManager(contents(), &delegate_)); 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(delegate_, DidLastPageLoadEncounterSSLErrors()) 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch .WillRepeatedly(Return(false)); 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void TearDown() { 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch manager_.reset(); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch store_ = NULL; 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm MakeSimpleForm() { 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm form; 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.origin = GURL("http://www.google.com/a/LoginAuth"); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.action = GURL("http://www.google.com/a/Login"); 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.username_element = ASCIIToUTF16("Email"); 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.password_element = ASCIIToUTF16("Passwd"); 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.username_value = ASCIIToUTF16("google"); 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.password_value = ASCIIToUTF16("password"); 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.submit_element = ASCIIToUTF16("signIn"); 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.signon_realm = "http://www.google.com"; 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return form; 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordManager* manager() { return manager_.get(); } 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We create a UI thread to satisfy PasswordStore. 120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread ui_thread_; 1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<Profile> profile_; 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<MockPasswordStore> store_; 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MockPasswordManagerDelegate delegate_; // Owned by manager_. 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<PasswordManager> manager_; 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMATCHER_P(FormMatches, form, "") { 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return form.signon_realm == arg.signon_realm && 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.origin == arg.origin && 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.action == arg.action && 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.username_element == arg.username_element && 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.password_element == arg.password_element && 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form.submit_element == arg.submit_element; 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PasswordManagerTest, FormSubmitEmptyStore) { 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Test that observing a newly submitted form shows the save password bar. 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm*> result; // Empty password store. 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(*store_, GetLogins(_,_)) 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch .WillOnce(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm> observed; 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm form(MakeSimpleForm()); 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observed.push_back(form); 14672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen manager()->OnPasswordFormsFound(observed); // The initial load. 14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen manager()->OnPasswordFormsVisible(observed); // The initial layout. 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // And the form submit contract is to call ProvisionallySavePassword. 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch manager()->ProvisionallySavePassword(form); 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<PasswordFormManager> form_to_save; 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(delegate_, AddSavePasswordInfoBar(_)) 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Now the password manager waits for the navigation to complete. 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch manager()->DidStopLoading(); 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(NULL == form_to_save.get()); 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(*store_, AddLogin(FormMatches(form))); 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Simulate saving the form, as if the info bar was accepted. 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form_to_save->Save(); 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PasswordManagerTest, FormSubmitNoGoodMatch) { 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Same as above, except with an existing form for the same signon realm, 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // but different origin. Detailed cases like this are covered by 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // PasswordFormManagerTest. 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm*> result; 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm* existing_different = new PasswordForm(MakeSimpleForm()); 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch existing_different->username_value = ASCIIToUTF16("google2"); 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result.push_back(existing_different); 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(delegate_, FillPasswordForm(_)); 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(*store_, GetLogins(_,_)) 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch .WillOnce(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm> observed; 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm form(MakeSimpleForm()); 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observed.push_back(form); 18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen manager()->OnPasswordFormsFound(observed); // The initial load. 18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen manager()->OnPasswordFormsVisible(observed); // The initial layout. 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch manager()->ProvisionallySavePassword(form); 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We still expect an add, since we didn't have a good match. 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<PasswordFormManager> form_to_save; 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(delegate_, AddSavePasswordInfoBar(_)) 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch manager()->DidStopLoading(); 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(*store_, AddLogin(FormMatches(form))); 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Simulate saving the form. 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form_to_save->Save(); 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PasswordManagerTest, FormSeenThenLeftPage) { 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm*> result; // Empty password store. 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(*store_, GetLogins(_,_)) 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch .WillOnce(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm> observed; 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm form(MakeSimpleForm()); 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observed.push_back(form); 20572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen manager()->OnPasswordFormsFound(observed); // The initial load. 20672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen manager()->OnPasswordFormsVisible(observed); // The initial layout. 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch manager()->DidNavigate(); 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // No expected calls. 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch manager()->DidStopLoading(); 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PasswordManagerTest, FormSubmitFailedLogin) { 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm*> result; // Empty password store. 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(*store_, GetLogins(_,_)) 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm> observed; 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm form(MakeSimpleForm()); 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observed.push_back(form); 22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen manager()->OnPasswordFormsFound(observed); // The initial load. 22372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen manager()->OnPasswordFormsVisible(observed); // The initial layout. 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch manager()->ProvisionallySavePassword(form); 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The form reappears, and is visible in the layout: 22872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen manager()->OnPasswordFormsFound(observed); 22972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen manager()->OnPasswordFormsVisible(observed); 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // No expected calls to the PasswordStore... 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch manager()->DidStopLoading(); 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PasswordManagerTest, FormSubmitInvisibleLogin) { 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Tests fix of issue 28911: if the login form reappears on the subsequent 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // page, but is invisible, it shouldn't count as a failed login. 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm*> result; // Empty password store. 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(*store_, GetLogins(_,_)) 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm> observed; 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm form(MakeSimpleForm()); 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observed.push_back(form); 24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen manager()->OnPasswordFormsFound(observed); // The initial load. 24672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen manager()->OnPasswordFormsVisible(observed); // The initial layout. 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch manager()->ProvisionallySavePassword(form); 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The form reappears, but is not visible in the layout: 25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen manager()->OnPasswordFormsFound(observed); 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // No call to PasswordFormsVisible. 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Expect info bar to appear: 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<PasswordFormManager> form_to_save; 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(delegate_, AddSavePasswordInfoBar(_)) 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch manager()->DidStopLoading(); 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(NULL == form_to_save.get()); 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(*store_, AddLogin(FormMatches(form))); 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Simulate saving the form. 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch form_to_save->Save(); 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(PasswordManagerTest, InitiallyInvisibleForm) { 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure an invisible login form still gets autofilled. 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm*> result; 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm* existing = new PasswordForm(MakeSimpleForm()); 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result.push_back(existing); 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(delegate_, FillPasswordForm(_)); 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_CALL(*store_, GetLogins(_,_)) 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(0, result)), Return(0))); 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<PasswordForm> observed; 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PasswordForm form(MakeSimpleForm()); 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observed.push_back(form); 27872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen manager()->OnPasswordFormsFound(observed); // The initial load. 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // PasswordFormsVisible is not called. 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch manager()->DidStopLoading(); 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 283