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 "components/password_manager/content/browser/content_credential_manager_dispatcher.h"
7 #include "base/command_line.h"
8 #include "base/run_loop.h"
9 #include "base/strings/string16.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "components/password_manager/content/browser/credential_manager_password_form_manager.h"
12 #include "components/password_manager/content/common/credential_manager_messages.h"
13 #include "components/password_manager/content/common/credential_manager_types.h"
14 #include "components/password_manager/core/browser/stub_password_manager_client.h"
15 #include "components/password_manager/core/browser/stub_password_manager_driver.h"
16 #include "components/password_manager/core/browser/test_password_store.h"
17 #include "content/public/browser/web_contents.h"
18 #include "content/public/test/mock_render_process_host.h"
19 #include "content/public/test/test_renderer_host.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 using content::BrowserContext
;
24 using content::WebContents
;
28 // Chosen by fair dice roll. Guaranteed to be random.
29 const int kRequestId
= 4;
31 class TestPasswordManagerClient
32 : public password_manager::StubPasswordManagerClient
{
34 TestPasswordManagerClient(password_manager::PasswordStore
* store
)
35 : did_prompt_user_to_save_(false), store_(store
) {}
36 ~TestPasswordManagerClient() override
{}
38 password_manager::PasswordStore
* GetPasswordStore() override
{
42 password_manager::PasswordManagerDriver
* GetDriver() override
{
46 bool PromptUserToSavePassword(
47 scoped_ptr
<password_manager::PasswordFormManager
> manager
) override
{
48 did_prompt_user_to_save_
= true;
49 manager_
.reset(manager
.release());
53 bool did_prompt_user_to_save() const { return did_prompt_user_to_save_
; }
55 password_manager::PasswordFormManager
* pending_manager() const {
56 return manager_
.get();
60 bool did_prompt_user_to_save_
;
61 password_manager::PasswordStore
* store_
;
62 password_manager::StubPasswordManagerDriver driver_
;
63 scoped_ptr
<password_manager::PasswordFormManager
> manager_
;
66 void RunAllPendingTasks() {
67 base::RunLoop run_loop
;
68 base::MessageLoop::current()->PostTask(
69 FROM_HERE
, base::MessageLoop::QuitWhenIdleClosure());
75 namespace password_manager
{
77 class ContentCredentialManagerDispatcherTest
78 : public content::RenderViewHostTestHarness
{
80 ContentCredentialManagerDispatcherTest() {}
82 virtual void SetUp() override
{
83 content::RenderViewHostTestHarness::SetUp();
84 store_
= new TestPasswordStore
;
85 client_
.reset(new TestPasswordManagerClient(store_
.get()));
87 new ContentCredentialManagerDispatcher(web_contents(), client_
.get()));
89 NavigateAndCommit(GURL("https://example.com/test.html"));
91 form_
.username_value
= base::ASCIIToUTF16("Username");
92 form_
.display_name
= base::ASCIIToUTF16("Display Name");
93 form_
.password_value
= base::ASCIIToUTF16("Password");
94 form_
.origin
= web_contents()->GetLastCommittedURL().GetOrigin();
95 form_
.signon_realm
= form_
.origin
.spec();
96 form_
.scheme
= autofill::PasswordForm::SCHEME_HTML
;
99 EXPECT_TRUE(store_
->IsEmpty());
102 virtual void TearDown() override
{
104 content::RenderViewHostTestHarness::TearDown();
107 ContentCredentialManagerDispatcher
* dispatcher() { return dispatcher_
.get(); }
110 autofill::PasswordForm form_
;
111 scoped_refptr
<TestPasswordStore
> store_
;
112 scoped_ptr
<ContentCredentialManagerDispatcher
> dispatcher_
;
113 scoped_ptr
<TestPasswordManagerClient
> client_
;
116 TEST_F(ContentCredentialManagerDispatcherTest
,
117 CredentialManagerOnNotifyFailedSignIn
) {
119 info
.type
= CREDENTIAL_TYPE_LOCAL
;
120 dispatcher()->OnNotifyFailedSignIn(kRequestId
, info
);
122 const uint32 kMsgID
= CredentialManagerMsg_AcknowledgeFailedSignIn::ID
;
123 const IPC::Message
* message
=
124 process()->sink().GetFirstMessageMatching(kMsgID
);
125 EXPECT_TRUE(message
);
126 process()->sink().ClearMessages();
129 TEST_F(ContentCredentialManagerDispatcherTest
,
130 CredentialManagerOnNotifySignedIn
) {
131 CredentialInfo
info(form_
);
132 dispatcher()->OnNotifySignedIn(kRequestId
, info
);
134 const uint32 kMsgID
= CredentialManagerMsg_AcknowledgeSignedIn::ID
;
135 const IPC::Message
* message
=
136 process()->sink().GetFirstMessageMatching(kMsgID
);
137 EXPECT_TRUE(message
);
138 process()->sink().ClearMessages();
140 // Allow the PasswordFormManager to talk to the password store, determine
141 // that the form is new, and set it as pending.
142 RunAllPendingTasks();
144 EXPECT_TRUE(client_
->did_prompt_user_to_save());
145 EXPECT_TRUE(client_
->pending_manager()->HasCompletedMatching());
147 autofill::PasswordForm new_form
=
148 client_
->pending_manager()->pending_credentials();
149 EXPECT_EQ(form_
.username_value
, new_form
.username_value
);
150 EXPECT_EQ(form_
.display_name
, new_form
.display_name
);
151 EXPECT_EQ(form_
.password_value
, new_form
.password_value
);
152 EXPECT_EQ(form_
.origin
, new_form
.origin
);
153 EXPECT_EQ(form_
.signon_realm
, new_form
.signon_realm
);
154 EXPECT_EQ(autofill::PasswordForm::SCHEME_HTML
, new_form
.scheme
);
157 TEST_F(ContentCredentialManagerDispatcherTest
,
158 CredentialManagerOnNotifySignedOut
) {
159 dispatcher()->OnNotifySignedOut(kRequestId
);
161 const uint32 kMsgID
= CredentialManagerMsg_AcknowledgeSignedOut::ID
;
162 const IPC::Message
* message
=
163 process()->sink().GetFirstMessageMatching(kMsgID
);
164 EXPECT_TRUE(message
);
165 process()->sink().ClearMessages();
168 TEST_F(ContentCredentialManagerDispatcherTest
,
169 CredentialManagerOnRequestCredentialWithEmptyPasswordStore
) {
170 std::vector
<GURL
> federations
;
171 dispatcher()->OnRequestCredential(kRequestId
, false, federations
);
173 RunAllPendingTasks();
175 const uint32 kMsgID
= CredentialManagerMsg_SendCredential::ID
;
176 const IPC::Message
* message
=
177 process()->sink().GetFirstMessageMatching(kMsgID
);
178 EXPECT_TRUE(message
);
179 CredentialManagerMsg_SendCredential::Param param
;
180 CredentialManagerMsg_SendCredential::Read(message
, ¶m
);
181 EXPECT_EQ(CREDENTIAL_TYPE_EMPTY
, param
.b
.type
);
182 process()->sink().ClearMessages();
185 TEST_F(ContentCredentialManagerDispatcherTest
,
186 CredentialManagerOnRequestCredentialWithFullPasswordStore
) {
187 store_
->AddLogin(form_
);
189 std::vector
<GURL
> federations
;
190 dispatcher()->OnRequestCredential(kRequestId
, false, federations
);
192 RunAllPendingTasks();
194 const uint32 kMsgID
= CredentialManagerMsg_SendCredential::ID
;
195 const IPC::Message
* message
=
196 process()->sink().GetFirstMessageMatching(kMsgID
);
197 EXPECT_TRUE(message
);
198 process()->sink().ClearMessages();
201 TEST_F(ContentCredentialManagerDispatcherTest
,
202 CredentialManagerOnRequestCredentialWhileRequestPending
) {
203 store_
->AddLogin(form_
);
205 std::vector
<GURL
> federations
;
206 dispatcher()->OnRequestCredential(kRequestId
, false, federations
);
207 dispatcher()->OnRequestCredential(kRequestId
, false, federations
);
209 // Check that the second request triggered a rejection.
210 uint32 kMsgID
= CredentialManagerMsg_RejectCredentialRequest::ID
;
211 const IPC::Message
* message
=
212 process()->sink().GetFirstMessageMatching(kMsgID
);
213 EXPECT_TRUE(message
);
214 CredentialManagerMsg_RejectCredentialRequest::Param reject_param
;
215 CredentialManagerMsg_RejectCredentialRequest::Read(message
, &reject_param
);
216 EXPECT_EQ(blink::WebCredentialManagerError::ErrorTypePendingRequest
,
219 process()->sink().ClearMessages();
221 // Execute the PasswordStore asynchronousness.
222 RunAllPendingTasks();
224 // Check that the first request resolves.
225 kMsgID
= CredentialManagerMsg_SendCredential::ID
;
226 message
= process()->sink().GetFirstMessageMatching(kMsgID
);
227 EXPECT_TRUE(message
);
228 CredentialManagerMsg_SendCredential::Param send_param
;
229 CredentialManagerMsg_SendCredential::Read(message
, &send_param
);
230 CredentialManagerMsg_SendCredential::Read(message
, &send_param
);
231 EXPECT_NE(CREDENTIAL_TYPE_EMPTY
, send_param
.b
.type
);
232 process()->sink().ClearMessages();
235 } // namespace password_manager