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