1 // Copyright 2015 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.
7 #include "base/command_line.h"
8 #include "base/memory/linked_ptr.h"
9 #include "base/observer_list_threadsafe.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/values.h"
12 #include "chrome/browser/extensions/api/passwords_private/passwords_private_delegate.h"
13 #include "chrome/browser/extensions/api/passwords_private/passwords_private_delegate_factory.h"
14 #include "chrome/browser/extensions/extension_apitest.h"
15 #include "chrome/common/extensions/api/passwords_private.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "components/keyed_service/core/keyed_service.h"
18 #include "content/public/test/test_utils.h"
19 #include "extensions/common/switches.h"
21 namespace extensions
{
25 static const size_t kNumMocks
= 3;
26 static const int kNumCharactersInPassword
= 10;
27 static const char kPlaintextPassword
[] = "plaintext";
29 linked_ptr
<api::passwords_private::PasswordUiEntry
> CreateEntry(size_t num
) {
30 api::passwords_private::PasswordUiEntry
* entry
=
31 new api::passwords_private::PasswordUiEntry();
33 ss
<< "http://test" << num
<< ".com";
34 entry
->login_pair
.origin_url
= ss
.str();
36 ss
<< "testName" << num
;
37 entry
->login_pair
.username
= ss
.str();
38 entry
->num_characters_in_password
= kNumCharactersInPassword
;
39 return make_linked_ptr(entry
);
42 std::string
CreateException(size_t num
) {
44 ss
<< "http://exception" << num
<< ".com";
48 // A test PasswordsPrivateDelegate implementation which uses mock data.
49 // TestDelegate starts out with kNumMocks mocks of each type (saved password
50 // and password exception) and removes one mock each time RemoveSavedPassword()
51 // or RemovePasswordException() is called.
52 class TestDelegate
: public PasswordsPrivateDelegate
{
54 TestDelegate() : observers_(new base::ObserverListThreadSafe
<Observer
>()) {
56 for (size_t i
= 0; i
< kNumMocks
; i
++) {
57 current_entries_
.push_back(CreateEntry(i
));;
58 current_exceptions_
.push_back(CreateException(i
));
61 ~TestDelegate() override
{}
63 void AddObserver(Observer
* observer
) override
{
64 observers_
->AddObserver(observer
);
65 SendSavedPasswordsList();
66 SendPasswordExceptionsList();
69 void RemoveObserver(Observer
* observer
) override
{
70 observers_
->RemoveObserver(observer
);
73 void RemoveSavedPassword(
74 const std::string
& origin_url
, const std::string
& username
) override
{
75 if (!current_entries_
.size())
78 // Since this is just mock data, remove the first entry regardless of
79 // the data contained.
80 current_entries_
.erase(current_entries_
.begin());
81 SendSavedPasswordsList();
84 void RemovePasswordException(const std::string
& exception_url
) override
{
85 if (!current_exceptions_
.size())
88 // Since this is just mock data, remove the first entry regardless of
89 // the data contained.
90 current_exceptions_
.erase(current_exceptions_
.begin());
91 SendPasswordExceptionsList();
94 void RequestShowPassword(const std::string
& origin_url
,
95 const std::string
& username
,
96 content::WebContents
* web_contents
) override
{
97 // Return a mocked password value.
98 std::string
plaintext_password(kPlaintextPassword
);
101 &Observer::OnPlaintextPasswordFetched
,
108 void SendSavedPasswordsList() {
111 &Observer::OnSavedPasswordsListChanged
,
115 void SendPasswordExceptionsList() {
118 &Observer::OnPasswordExceptionsListChanged
,
119 current_exceptions_
);
122 // The current list of entries/exceptions. Cached here so that when new
123 // observers are added, this delegate can send the current lists without
124 // having to request them from |password_manager_presenter_| again.
125 std::vector
<linked_ptr
<api::passwords_private::PasswordUiEntry
>>
127 std::vector
<std::string
> current_exceptions_
;
130 scoped_refptr
<base::ObserverListThreadSafe
<Observer
>> observers_
;
133 class PasswordsPrivateApiTest
: public ExtensionApiTest
{
135 PasswordsPrivateApiTest() {
136 if (!s_test_delegate_
) {
137 s_test_delegate_
= new TestDelegate();
140 ~PasswordsPrivateApiTest() override
{}
142 static scoped_ptr
<KeyedService
> GetPasswordsPrivateDelegate(
143 content::BrowserContext
* profile
) {
144 CHECK(s_test_delegate_
);
145 return make_scoped_ptr(s_test_delegate_
);
148 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
149 ExtensionApiTest::SetUpCommandLine(command_line
);
152 void SetUp() override
{
153 ExtensionApiTest::SetUp();
156 void SetUpOnMainThread() override
{
157 ExtensionApiTest::SetUpOnMainThread();
158 PasswordsPrivateDelegateFactory::GetInstance()->SetTestingFactory(
159 profile(), &PasswordsPrivateApiTest::GetPasswordsPrivateDelegate
);
160 content::RunAllPendingInMessageLoop();
164 bool RunPasswordsSubtest(const std::string
& subtest
) {
165 return RunExtensionSubtest("passwords_private",
166 "main.html?" + subtest
,
167 kFlagLoadAsComponent
);
171 static TestDelegate
* s_test_delegate_
;
173 DISALLOW_COPY_AND_ASSIGN(PasswordsPrivateApiTest
);
177 TestDelegate
* PasswordsPrivateApiTest::s_test_delegate_
= nullptr;
181 IN_PROC_BROWSER_TEST_F(PasswordsPrivateApiTest
, CanPasswordAccountBeManaged
) {
182 EXPECT_TRUE(RunPasswordsSubtest("canPasswordAccountBeManaged")) << message_
;
185 IN_PROC_BROWSER_TEST_F(PasswordsPrivateApiTest
, RemoveSavedPassword
) {
186 EXPECT_TRUE(RunPasswordsSubtest("removeSavedPassword")) << message_
;
189 IN_PROC_BROWSER_TEST_F(PasswordsPrivateApiTest
, RemovePasswordException
) {
190 EXPECT_TRUE(RunPasswordsSubtest("removePasswordException")) << message_
;
193 IN_PROC_BROWSER_TEST_F(PasswordsPrivateApiTest
, RequestPlaintextPassword
) {
194 EXPECT_TRUE(RunPasswordsSubtest("requestPlaintextPassword")) << message_
;
197 } // namespace extensions