1 // Copyright (c) 2012 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.
11 #include "base/bind.h"
12 #include "base/pickle.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/stl_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/synchronization/waitable_event.h"
17 #include "chrome/browser/password_manager/native_backend_kwallet_x.h"
18 #include "chrome/test/base/testing_profile.h"
19 #include "components/autofill/core/common/password_form.h"
20 #include "components/password_manager/core/common/password_manager_pref_names.h"
21 #include "content/public/test/test_browser_thread.h"
22 #include "dbus/message.h"
23 #include "dbus/mock_bus.h"
24 #include "dbus/mock_object_proxy.h"
25 #include "dbus/object_path.h"
26 #include "dbus/object_proxy.h"
27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h"
30 using autofill::PasswordForm
;
31 using base::UTF8ToUTF16
;
32 using content::BrowserThread
;
33 using password_manager::PasswordStoreChange
;
34 using password_manager::PasswordStoreChangeList
;
36 using testing::Invoke
;
37 using testing::Return
;
41 // This class implements a very simple version of KWallet in memory.
42 // We only provide the parts we actually use; the real version has more.
45 typedef std::basic_string
<uint8_t> Blob
; // std::string is binary-safe.
47 TestKWallet() : reject_local_folders_(false) {}
49 void set_reject_local_folders(bool value
) { reject_local_folders_
= value
; }
51 // NOTE: The method names here are the same as the corresponding DBus
52 // methods, and therefore have names that don't match our style guide.
54 // Check for presence of a given password folder.
55 bool hasFolder(const std::string
& folder
) const {
56 return data_
.find(folder
) != data_
.end();
59 // Check for presence of a given password in a given password folder.
60 bool hasEntry(const std::string
& folder
, const std::string
& key
) const {
61 Data::const_iterator it
= data_
.find(folder
);
62 return it
!= data_
.end() && it
->second
.find(key
) != it
->second
.end();
65 // Get a list of password keys in a given password folder.
66 bool entryList(const std::string
& folder
,
67 std::vector
<std::string
>* entries
) const {
68 Data::const_iterator it
= data_
.find(folder
);
69 if (it
== data_
.end()) return false;
70 for (Folder::const_iterator fit
= it
->second
.begin();
71 fit
!= it
->second
.end(); ++fit
)
72 entries
->push_back(fit
->first
);
76 // Read the password data for a given password in a given password folder.
77 bool readEntry(const std::string
& folder
, const std::string
& key
,
79 Data::const_iterator it
= data_
.find(folder
);
80 if (it
== data_
.end()) return false;
81 Folder::const_iterator fit
= it
->second
.find(key
);
82 if (fit
== it
->second
.end()) return false;
87 // Create the given password folder.
88 bool createFolder(const std::string
& folder
) {
89 if (reject_local_folders_
&& folder
.find('(') != std::string::npos
)
91 return data_
.insert(make_pair(folder
, Folder())).second
;
94 // Remove the given password from the given password folder.
95 bool removeEntry(const std::string
& folder
, const std::string
& key
) {
96 Data::iterator it
= data_
.find(folder
);
97 if (it
== data_
.end()) return false;
98 return it
->second
.erase(key
) > 0;
101 // Write the given password data to the given password folder.
102 bool writeEntry(const std::string
& folder
, const std::string
& key
,
104 Data::iterator it
= data_
.find(folder
);
105 if (it
== data_
.end()) return false;
106 it
->second
[key
] = value
;
111 typedef std::map
<std::string
, Blob
> Folder
;
112 typedef std::map
<std::string
, Folder
> Data
;
115 // "Local" folders are folders containing local profile IDs in their names. We
116 // can reject attempts to create them in order to make it easier to create
117 // legacy shared passwords in these tests, for testing the migration code.
118 bool reject_local_folders_
;
120 // No need to disallow copy and assign. This class is safe to copy and assign.
123 // Runs |backend->GetAutofillableLogins(forms)| and expects that the return
125 void CheckGetAutofillableLoginsFails(
126 PasswordStoreX::NativeBackend
* backend
,
127 ScopedVector
<autofill::PasswordForm
>* forms
) {
128 EXPECT_FALSE(backend
->GetAutofillableLogins(forms
));
131 } // anonymous namespace
133 // Obscure magic: we need to declare storage for this constant because we use it
134 // in ways that require its address in this test, but not in the actual code.
135 const int NativeBackendKWallet::kInvalidKWalletHandle
;
137 // Subclass NativeBackendKWallet to promote some members to public for testing.
138 class NativeBackendKWalletStub
: public NativeBackendKWallet
{
140 explicit NativeBackendKWalletStub(LocalProfileId id
)
141 : NativeBackendKWallet(id
) {
143 using NativeBackendKWallet::InitWithBus
;
144 using NativeBackendKWallet::kInvalidKWalletHandle
;
145 using NativeBackendKWallet::DeserializeValue
;
148 // Provide some test forms to avoid having to set them up in each test.
149 class NativeBackendKWalletTestBase
: public testing::Test
{
151 NativeBackendKWalletTestBase() {
152 old_form_google_
.origin
= GURL("http://www.google.com/");
153 old_form_google_
.action
= GURL("http://www.google.com/login");
154 old_form_google_
.username_element
= UTF8ToUTF16("user");
155 old_form_google_
.username_value
= UTF8ToUTF16("joeschmoe");
156 old_form_google_
.password_element
= UTF8ToUTF16("pass");
157 old_form_google_
.password_value
= UTF8ToUTF16("seekrit");
158 old_form_google_
.submit_element
= UTF8ToUTF16("submit");
159 old_form_google_
.signon_realm
= "Google";
160 old_form_google_
.date_created
= base::Time::Now();
162 form_google_
= old_form_google_
;
163 form_google_
.times_used
= 3;
164 form_google_
.type
= PasswordForm::TYPE_GENERATED
;
165 form_google_
.form_data
.name
= UTF8ToUTF16("form_name");
166 form_google_
.form_data
.user_submitted
= true;
167 form_google_
.date_synced
= base::Time::Now();
168 form_google_
.date_created
= old_form_google_
.date_created
;
169 form_google_
.display_name
= UTF8ToUTF16("Joe Schmoe");
170 form_google_
.avatar_url
= GURL("http://www.google.com/avatar");
171 form_google_
.federation_url
= GURL("http://www.google.com/federation_url");
172 form_google_
.skip_zero_click
= true;
174 form_isc_
.origin
= GURL("http://www.isc.org/");
175 form_isc_
.action
= GURL("http://www.isc.org/auth");
176 form_isc_
.username_element
= UTF8ToUTF16("id");
177 form_isc_
.username_value
= UTF8ToUTF16("janedoe");
178 form_isc_
.password_element
= UTF8ToUTF16("passwd");
179 form_isc_
.password_value
= UTF8ToUTF16("ihazabukkit");
180 form_isc_
.submit_element
= UTF8ToUTF16("login");
181 form_isc_
.signon_realm
= "ISC";
182 form_isc_
.date_synced
= base::Time::Now();
183 form_isc_
.date_created
= base::Time::Now();
186 static void CheckPasswordForm(const PasswordForm
& expected
,
187 const PasswordForm
& actual
,
188 bool check_date_created
);
189 static void CheckPasswordChanges(const PasswordStoreChangeList
& expected
,
190 const PasswordStoreChangeList
& actual
);
191 static void CheckPasswordChangesWithResult(
192 const PasswordStoreChangeList
* expected
,
193 const PasswordStoreChangeList
* actual
,
196 PasswordForm old_form_google_
;
197 PasswordForm form_google_
;
198 PasswordForm form_isc_
;
202 void NativeBackendKWalletTestBase::CheckPasswordForm(
203 const PasswordForm
& expected
,
204 const PasswordForm
& actual
,
205 bool check_date_created
) {
206 EXPECT_EQ(expected
.origin
, actual
.origin
);
207 EXPECT_EQ(expected
.password_value
, actual
.password_value
);
208 EXPECT_EQ(expected
.action
, actual
.action
);
209 EXPECT_EQ(expected
.username_element
, actual
.username_element
);
210 EXPECT_EQ(expected
.username_value
, actual
.username_value
);
211 EXPECT_EQ(expected
.password_element
, actual
.password_element
);
212 EXPECT_EQ(expected
.submit_element
, actual
.submit_element
);
213 EXPECT_EQ(expected
.signon_realm
, actual
.signon_realm
);
214 EXPECT_EQ(expected
.ssl_valid
, actual
.ssl_valid
);
215 EXPECT_EQ(expected
.preferred
, actual
.preferred
);
216 if (check_date_created
) {
217 EXPECT_EQ(expected
.date_created
, actual
.date_created
);
219 EXPECT_EQ(expected
.blacklisted_by_user
, actual
.blacklisted_by_user
);
220 EXPECT_EQ(expected
.type
, actual
.type
);
221 EXPECT_EQ(expected
.times_used
, actual
.times_used
);
222 EXPECT_EQ(expected
.scheme
, actual
.scheme
);
223 EXPECT_EQ(expected
.date_synced
, actual
.date_synced
);
224 EXPECT_EQ(expected
.display_name
, actual
.display_name
);
225 EXPECT_EQ(expected
.avatar_url
, actual
.avatar_url
);
226 EXPECT_EQ(expected
.federation_url
, actual
.federation_url
);
227 EXPECT_EQ(expected
.skip_zero_click
, actual
.skip_zero_click
);
228 EXPECT_EQ(expected
.generation_upload_status
, actual
.generation_upload_status
);
232 void NativeBackendKWalletTestBase::CheckPasswordChanges(
233 const PasswordStoreChangeList
& expected
,
234 const PasswordStoreChangeList
& actual
) {
235 ASSERT_EQ(expected
.size(), actual
.size());
236 for (size_t i
= 0; i
< expected
.size(); ++i
) {
237 EXPECT_EQ(expected
[i
].type(), actual
[i
].type());
238 CheckPasswordForm(expected
[i
].form(), actual
[i
].form(), true);
243 void NativeBackendKWalletTestBase::CheckPasswordChangesWithResult(
244 const PasswordStoreChangeList
* expected
,
245 const PasswordStoreChangeList
* actual
,
248 CheckPasswordChanges(*expected
, *actual
);
251 class NativeBackendKWalletTest
: public NativeBackendKWalletTestBase
{
253 NativeBackendKWalletTest()
254 : ui_thread_(BrowserThread::UI
, &message_loop_
),
255 db_thread_(BrowserThread::DB
), klauncher_ret_(0),
256 klauncher_contacted_(false), kwallet_runnable_(true),
257 kwallet_running_(true), kwallet_enabled_(true) {
260 void SetUp() override
;
261 void TearDown() override
;
263 // Let the DB thread run to completion of all current tasks.
265 base::WaitableEvent
event(false, false);
266 BrowserThread::PostTask(BrowserThread::DB
, FROM_HERE
,
267 base::Bind(ThreadDone
, &event
));
269 // Some of the tests may post messages to the UI thread, but we don't need
270 // to run those until after the DB thread is finished. So run it here.
271 message_loop_
.RunUntilIdle();
273 static void ThreadDone(base::WaitableEvent
* event
) {
277 // Utilities to help verify sets of expectations.
279 std::pair
<std::string
,
280 std::vector
<const PasswordForm
*> > > ExpectationArray
;
281 void CheckPasswordForms(const std::string
& folder
,
282 const ExpectationArray
& sorted_expected
);
284 enum RemoveBetweenMethod
{
289 // Tests RemoveLoginsCreatedBetween or RemoveLoginsSyncedBetween.
290 void TestRemoveLoginsBetween(RemoveBetweenMethod date_to_test
);
292 base::MessageLoopForUI message_loop_
;
293 content::TestBrowserThread ui_thread_
;
294 content::TestBrowserThread db_thread_
;
296 scoped_refptr
<dbus::MockBus
> mock_session_bus_
;
297 scoped_refptr
<dbus::MockObjectProxy
> mock_klauncher_proxy_
;
298 scoped_refptr
<dbus::MockObjectProxy
> mock_kwallet_proxy_
;
301 std::string klauncher_error_
;
302 bool klauncher_contacted_
;
304 bool kwallet_runnable_
;
305 bool kwallet_running_
;
306 bool kwallet_enabled_
;
310 // For all method names contained in |failing_methods_|, the mocked KWallet
311 // will return a null response.
312 std::set
<std::string
> failing_methods_
;
315 dbus::Response
* KLauncherMethodCall(
316 dbus::MethodCall
* method_call
, testing::Unused
);
318 dbus::Response
* KWalletMethodCall(
319 dbus::MethodCall
* method_call
, testing::Unused
);
322 void NativeBackendKWalletTest::SetUp() {
323 ASSERT_TRUE(db_thread_
.Start());
325 dbus::Bus::Options options
;
326 options
.bus_type
= dbus::Bus::SESSION
;
327 mock_session_bus_
= new dbus::MockBus(options
);
329 mock_klauncher_proxy_
=
330 new dbus::MockObjectProxy(mock_session_bus_
.get(),
332 dbus::ObjectPath("/KLauncher"));
333 EXPECT_CALL(*mock_klauncher_proxy_
.get(), MockCallMethodAndBlock(_
, _
))
335 Invoke(this, &NativeBackendKWalletTest::KLauncherMethodCall
));
337 mock_kwallet_proxy_
=
338 new dbus::MockObjectProxy(mock_session_bus_
.get(),
340 dbus::ObjectPath("/modules/kwalletd"));
341 EXPECT_CALL(*mock_kwallet_proxy_
.get(), MockCallMethodAndBlock(_
, _
))
343 Invoke(this, &NativeBackendKWalletTest::KWalletMethodCall
));
346 *mock_session_bus_
.get(),
347 GetObjectProxy("org.kde.klauncher", dbus::ObjectPath("/KLauncher")))
348 .WillRepeatedly(Return(mock_klauncher_proxy_
.get()));
350 *mock_session_bus_
.get(),
351 GetObjectProxy("org.kde.kwalletd", dbus::ObjectPath("/modules/kwalletd")))
352 .WillRepeatedly(Return(mock_kwallet_proxy_
.get()));
354 EXPECT_CALL(*mock_session_bus_
.get(), ShutdownAndBlock()).WillOnce(Return())
355 .WillRepeatedly(Return());
358 void NativeBackendKWalletTest::TearDown() {
359 base::MessageLoop::current()->PostTask(FROM_HERE
,
360 base::MessageLoop::QuitClosure());
361 base::MessageLoop::current()->Run();
365 void NativeBackendKWalletTest::TestRemoveLoginsBetween(
366 RemoveBetweenMethod date_to_test
) {
367 NativeBackendKWalletStub
backend(42);
368 EXPECT_TRUE(backend
.InitWithBus(mock_session_bus_
));
370 form_google_
.date_synced
= base::Time();
371 form_isc_
.date_synced
= base::Time();
372 form_google_
.date_created
= base::Time();
373 form_isc_
.date_created
= base::Time();
374 base::Time now
= base::Time::Now();
375 base::Time next_day
= now
+ base::TimeDelta::FromDays(1);
376 if (date_to_test
== CREATED
) {
377 form_google_
.date_created
= now
;
378 form_isc_
.date_created
= next_day
;
380 form_google_
.date_synced
= now
;
381 form_isc_
.date_synced
= next_day
;
384 BrowserThread::PostTask(
387 base::Bind(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin
),
388 base::Unretained(&backend
),
390 BrowserThread::PostTask(
393 base::Bind(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin
),
394 base::Unretained(&backend
),
397 PasswordStoreChangeList expected_changes
;
398 expected_changes
.push_back(
399 PasswordStoreChange(PasswordStoreChange::REMOVE
, form_google_
));
400 PasswordStoreChangeList changes
;
401 bool (NativeBackendKWallet::*method
)(
402 base::Time
, base::Time
, password_manager::PasswordStoreChangeList
*) =
403 date_to_test
== CREATED
404 ? &NativeBackendKWalletStub::RemoveLoginsCreatedBetween
405 : &NativeBackendKWalletStub::RemoveLoginsSyncedBetween
;
406 BrowserThread::PostTaskAndReplyWithResult(
410 method
, base::Unretained(&backend
), base::Time(), next_day
, &changes
),
411 base::Bind(&NativeBackendKWalletTest::CheckPasswordChangesWithResult
,
416 std::vector
<const PasswordForm
*> forms
;
417 forms
.push_back(&form_isc_
);
418 ExpectationArray expected
;
419 expected
.push_back(make_pair(std::string(form_isc_
.signon_realm
), forms
));
420 CheckPasswordForms("Chrome Form Data (42)", expected
);
423 expected_changes
.clear();
424 expected_changes
.push_back(
425 PasswordStoreChange(PasswordStoreChange::REMOVE
, form_isc_
));
426 BrowserThread::PostTaskAndReplyWithResult(
430 method
, base::Unretained(&backend
), next_day
, base::Time(), &changes
),
431 base::Bind(&NativeBackendKWalletTest::CheckPasswordChangesWithResult
,
436 CheckPasswordForms("Chrome Form Data (42)", ExpectationArray());
439 dbus::Response
* NativeBackendKWalletTest::KLauncherMethodCall(
440 dbus::MethodCall
* method_call
, testing::Unused
) {
441 EXPECT_EQ("org.kde.KLauncher", method_call
->GetInterface());
442 EXPECT_EQ("start_service_by_desktop_name", method_call
->GetMember());
444 klauncher_contacted_
= true;
446 dbus::MessageReader
reader(method_call
);
447 std::string service_name
;
448 std::vector
<std::string
> urls
;
449 std::vector
<std::string
> envs
;
450 std::string startup_id
;
453 EXPECT_TRUE(reader
.PopString(&service_name
));
454 EXPECT_TRUE(reader
.PopArrayOfStrings(&urls
));
455 EXPECT_TRUE(reader
.PopArrayOfStrings(&envs
));
456 EXPECT_TRUE(reader
.PopString(&startup_id
));
457 EXPECT_TRUE(reader
.PopBool(&blind
));
459 EXPECT_EQ("kwalletd", service_name
);
460 EXPECT_TRUE(urls
.empty());
461 EXPECT_TRUE(envs
.empty());
462 EXPECT_TRUE(startup_id
.empty());
465 if (kwallet_runnable_
)
466 kwallet_running_
= true;
468 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
469 dbus::MessageWriter
writer(response
.get());
470 writer
.AppendInt32(klauncher_ret_
);
471 writer
.AppendString(std::string()); // dbus_name
472 writer
.AppendString(klauncher_error_
);
473 writer
.AppendInt32(1234); // pid
474 return response
.release();
477 dbus::Response
* NativeBackendKWalletTest::KWalletMethodCall(
478 dbus::MethodCall
* method_call
, testing::Unused
) {
479 if (!kwallet_running_
)
481 EXPECT_EQ("org.kde.KWallet", method_call
->GetInterface());
483 if (ContainsKey(failing_methods_
, method_call
->GetMember()))
485 scoped_ptr
<dbus::Response
> response
;
486 if (method_call
->GetMember() == "isEnabled") {
487 response
= dbus::Response::CreateEmpty();
488 dbus::MessageWriter
writer(response
.get());
489 writer
.AppendBool(kwallet_enabled_
);
490 } else if (method_call
->GetMember() == "networkWallet") {
491 response
= dbus::Response::CreateEmpty();
492 dbus::MessageWriter
writer(response
.get());
493 writer
.AppendString("test_wallet"); // Should match |open| below.
494 } else if (method_call
->GetMember() == "open") {
495 dbus::MessageReader
reader(method_call
);
496 std::string wallet_name
;
498 std::string app_name
;
499 EXPECT_TRUE(reader
.PopString(&wallet_name
));
500 EXPECT_TRUE(reader
.PopInt64(&wallet_id
));
501 EXPECT_TRUE(reader
.PopString(&app_name
));
502 EXPECT_EQ("test_wallet", wallet_name
); // Should match |networkWallet|.
503 response
= dbus::Response::CreateEmpty();
504 dbus::MessageWriter
writer(response
.get());
505 writer
.AppendInt32(1); // Can be anything but kInvalidKWalletHandle.
506 } else if (method_call
->GetMember() == "hasFolder" ||
507 method_call
->GetMember() == "createFolder") {
508 dbus::MessageReader
reader(method_call
);
509 int handle
= NativeBackendKWalletStub::kInvalidKWalletHandle
;
510 std::string folder_name
;
511 std::string app_name
;
512 EXPECT_TRUE(reader
.PopInt32(&handle
));
513 EXPECT_TRUE(reader
.PopString(&folder_name
));
514 EXPECT_TRUE(reader
.PopString(&app_name
));
515 EXPECT_NE(NativeBackendKWalletStub::kInvalidKWalletHandle
, handle
);
516 response
= dbus::Response::CreateEmpty();
517 dbus::MessageWriter
writer(response
.get());
518 if (method_call
->GetMember() == "hasFolder")
519 writer
.AppendBool(wallet_
.hasFolder(folder_name
));
521 writer
.AppendBool(wallet_
.createFolder(folder_name
));
522 } else if (method_call
->GetMember() == "hasEntry" ||
523 method_call
->GetMember() == "removeEntry") {
524 dbus::MessageReader
reader(method_call
);
525 int handle
= NativeBackendKWalletStub::kInvalidKWalletHandle
;
526 std::string folder_name
;
528 std::string app_name
;
529 EXPECT_TRUE(reader
.PopInt32(&handle
));
530 EXPECT_TRUE(reader
.PopString(&folder_name
));
531 EXPECT_TRUE(reader
.PopString(&key
));
532 EXPECT_TRUE(reader
.PopString(&app_name
));
533 EXPECT_NE(NativeBackendKWalletStub::kInvalidKWalletHandle
, handle
);
534 response
= dbus::Response::CreateEmpty();
535 dbus::MessageWriter
writer(response
.get());
536 if (method_call
->GetMember() == "hasEntry")
537 writer
.AppendBool(wallet_
.hasEntry(folder_name
, key
));
539 writer
.AppendInt32(wallet_
.removeEntry(folder_name
, key
) ? 0 : 1);
540 } else if (method_call
->GetMember() == "entryList") {
541 dbus::MessageReader
reader(method_call
);
542 int handle
= NativeBackendKWalletStub::kInvalidKWalletHandle
;
543 std::string folder_name
;
544 std::string app_name
;
545 EXPECT_TRUE(reader
.PopInt32(&handle
));
546 EXPECT_TRUE(reader
.PopString(&folder_name
));
547 EXPECT_TRUE(reader
.PopString(&app_name
));
548 EXPECT_NE(NativeBackendKWalletStub::kInvalidKWalletHandle
, handle
);
549 std::vector
<std::string
> entries
;
550 if (wallet_
.entryList(folder_name
, &entries
)) {
551 response
= dbus::Response::CreateEmpty();
552 dbus::MessageWriter
writer(response
.get());
553 writer
.AppendArrayOfStrings(entries
);
555 } else if (method_call
->GetMember() == "readEntry") {
556 dbus::MessageReader
reader(method_call
);
557 int handle
= NativeBackendKWalletStub::kInvalidKWalletHandle
;
558 std::string folder_name
;
560 std::string app_name
;
561 EXPECT_TRUE(reader
.PopInt32(&handle
));
562 EXPECT_TRUE(reader
.PopString(&folder_name
));
563 EXPECT_TRUE(reader
.PopString(&key
));
564 EXPECT_TRUE(reader
.PopString(&app_name
));
565 EXPECT_NE(NativeBackendKWalletStub::kInvalidKWalletHandle
, handle
);
566 TestKWallet::Blob value
;
567 if (wallet_
.readEntry(folder_name
, key
, &value
)) {
568 response
= dbus::Response::CreateEmpty();
569 dbus::MessageWriter
writer(response
.get());
570 writer
.AppendArrayOfBytes(value
.data(), value
.size());
572 } else if (method_call
->GetMember() == "writeEntry") {
573 dbus::MessageReader
reader(method_call
);
574 int handle
= NativeBackendKWalletStub::kInvalidKWalletHandle
;
575 std::string folder_name
;
577 const uint8_t* bytes
= nullptr;
579 std::string app_name
;
580 EXPECT_TRUE(reader
.PopInt32(&handle
));
581 EXPECT_TRUE(reader
.PopString(&folder_name
));
582 EXPECT_TRUE(reader
.PopString(&key
));
583 EXPECT_TRUE(reader
.PopArrayOfBytes(&bytes
, &length
));
584 EXPECT_TRUE(reader
.PopString(&app_name
));
585 EXPECT_NE(NativeBackendKWalletStub::kInvalidKWalletHandle
, handle
);
586 response
= dbus::Response::CreateEmpty();
587 dbus::MessageWriter
writer(response
.get());
589 wallet_
.writeEntry(folder_name
, key
,
590 TestKWallet::Blob(bytes
, length
)) ? 0 : 1);
593 EXPECT_TRUE(response
);
594 return response
.release();
597 void NativeBackendKWalletTest::CheckPasswordForms(
598 const std::string
& folder
, const ExpectationArray
& sorted_expected
) {
599 EXPECT_TRUE(wallet_
.hasFolder(folder
));
600 std::vector
<std::string
> entries
;
601 EXPECT_TRUE(wallet_
.entryList(folder
, &entries
));
602 EXPECT_EQ(sorted_expected
.size(), entries
.size());
603 std::sort(entries
.begin(), entries
.end());
604 for (size_t i
= 0; i
< entries
.size() && i
< sorted_expected
.size(); ++i
) {
605 EXPECT_EQ(sorted_expected
[i
].first
, entries
[i
]);
606 TestKWallet::Blob value
;
607 EXPECT_TRUE(wallet_
.readEntry(folder
, entries
[i
], &value
));
608 Pickle
pickle(reinterpret_cast<const char*>(value
.data()), value
.size());
609 ScopedVector
<autofill::PasswordForm
> forms
=
610 NativeBackendKWalletStub::DeserializeValue(entries
[i
], pickle
);
611 const std::vector
<const PasswordForm
*>& expect
= sorted_expected
[i
].second
;
612 EXPECT_EQ(expect
.size(), forms
.size());
613 for (size_t j
= 0; j
< forms
.size() && j
< expect
.size(); ++j
)
614 CheckPasswordForm(*expect
[j
], *forms
[j
], true);
618 TEST_F(NativeBackendKWalletTest
, NotEnabled
) {
619 NativeBackendKWalletStub
kwallet(42);
620 kwallet_enabled_
= false;
621 EXPECT_FALSE(kwallet
.InitWithBus(mock_session_bus_
));
622 EXPECT_FALSE(klauncher_contacted_
);
625 TEST_F(NativeBackendKWalletTest
, NotRunnable
) {
626 NativeBackendKWalletStub
kwallet(42);
627 kwallet_runnable_
= false;
628 kwallet_running_
= false;
629 EXPECT_FALSE(kwallet
.InitWithBus(mock_session_bus_
));
630 EXPECT_TRUE(klauncher_contacted_
);
633 TEST_F(NativeBackendKWalletTest
, NotRunningOrEnabled
) {
634 NativeBackendKWalletStub
kwallet(42);
635 kwallet_running_
= false;
636 kwallet_enabled_
= false;
637 EXPECT_FALSE(kwallet
.InitWithBus(mock_session_bus_
));
638 EXPECT_TRUE(klauncher_contacted_
);
641 TEST_F(NativeBackendKWalletTest
, NotRunning
) {
642 NativeBackendKWalletStub
kwallet(42);
643 kwallet_running_
= false;
644 EXPECT_TRUE(kwallet
.InitWithBus(mock_session_bus_
));
645 EXPECT_TRUE(klauncher_contacted_
);
648 TEST_F(NativeBackendKWalletTest
, BasicStartup
) {
649 NativeBackendKWalletStub
kwallet(42);
650 EXPECT_TRUE(kwallet
.InitWithBus(mock_session_bus_
));
651 EXPECT_FALSE(klauncher_contacted_
);
654 TEST_F(NativeBackendKWalletTest
, BasicAddLogin
) {
655 NativeBackendKWalletStub
backend(42);
656 EXPECT_TRUE(backend
.InitWithBus(mock_session_bus_
));
658 BrowserThread::PostTask(
659 BrowserThread::DB
, FROM_HERE
,
660 base::Bind(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin
),
661 base::Unretained(&backend
), form_google_
));
665 EXPECT_FALSE(wallet_
.hasFolder("Chrome Form Data"));
667 std::vector
<const PasswordForm
*> forms
;
668 forms
.push_back(&form_google_
);
669 ExpectationArray expected
;
670 expected
.push_back(make_pair(std::string(form_google_
.signon_realm
), forms
));
671 CheckPasswordForms("Chrome Form Data (42)", expected
);
674 TEST_F(NativeBackendKWalletTest
, BasicUpdateLogin
) {
675 NativeBackendKWalletStub
backend(42);
676 EXPECT_TRUE(backend
.InitWithBus(mock_session_bus_
));
678 BrowserThread::PostTask(
679 BrowserThread::DB
, FROM_HERE
,
680 base::Bind(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin
),
681 base::Unretained(&backend
), form_google_
));
685 PasswordForm
new_form_google(form_google_
);
686 new_form_google
.times_used
= 10;
687 new_form_google
.action
= GURL("http://www.google.com/different/login");
690 PasswordStoreChangeList changes
;
691 BrowserThread::PostTask(
692 BrowserThread::DB
, FROM_HERE
,
693 base::Bind(base::IgnoreResult(&NativeBackendKWalletStub::UpdateLogin
),
694 base::Unretained(&backend
),
696 base::Unretained(&changes
)));
699 ASSERT_EQ(1u, changes
.size());
700 EXPECT_EQ(PasswordStoreChange::UPDATE
, changes
.front().type());
701 EXPECT_EQ(new_form_google
, changes
.front().form());
703 std::vector
<const PasswordForm
*> forms
;
704 forms
.push_back(&new_form_google
);
705 ExpectationArray expected
;
706 expected
.push_back(make_pair(std::string(form_google_
.signon_realm
), forms
));
707 CheckPasswordForms("Chrome Form Data (42)", expected
);
710 TEST_F(NativeBackendKWalletTest
, BasicListLogins
) {
711 NativeBackendKWalletStub
backend(42);
712 EXPECT_TRUE(backend
.InitWithBus(mock_session_bus_
));
714 BrowserThread::PostTask(
715 BrowserThread::DB
, FROM_HERE
,
716 base::Bind(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin
),
717 base::Unretained(&backend
), form_google_
));
719 ScopedVector
<autofill::PasswordForm
> form_list
;
720 BrowserThread::PostTask(
721 BrowserThread::DB
, FROM_HERE
,
723 base::IgnoreResult(&NativeBackendKWalletStub::GetAutofillableLogins
),
724 base::Unretained(&backend
), &form_list
));
728 // Quick check that we got something back.
729 EXPECT_EQ(1u, form_list
.size());
731 EXPECT_FALSE(wallet_
.hasFolder("Chrome Form Data"));
733 std::vector
<const PasswordForm
*> forms
;
734 forms
.push_back(&form_google_
);
735 ExpectationArray expected
;
736 expected
.push_back(make_pair(std::string(form_google_
.signon_realm
), forms
));
737 CheckPasswordForms("Chrome Form Data (42)", expected
);
740 TEST_F(NativeBackendKWalletTest
, BasicRemoveLogin
) {
741 NativeBackendKWalletStub
backend(42);
742 EXPECT_TRUE(backend
.InitWithBus(mock_session_bus_
));
744 BrowserThread::PostTask(
745 BrowserThread::DB
, FROM_HERE
,
746 base::Bind(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin
),
747 base::Unretained(&backend
), form_google_
));
751 EXPECT_FALSE(wallet_
.hasFolder("Chrome Form Data"));
753 std::vector
<const PasswordForm
*> forms
;
754 forms
.push_back(&form_google_
);
755 ExpectationArray expected
;
756 expected
.push_back(make_pair(std::string(form_google_
.signon_realm
), forms
));
757 CheckPasswordForms("Chrome Form Data (42)", expected
);
759 BrowserThread::PostTask(
760 BrowserThread::DB
, FROM_HERE
,
761 base::Bind(base::IgnoreResult(&NativeBackendKWalletStub::RemoveLogin
),
762 base::Unretained(&backend
), form_google_
));
767 CheckPasswordForms("Chrome Form Data (42)", expected
);
770 TEST_F(NativeBackendKWalletTest
, UpdateNonexistentLogin
) {
771 NativeBackendKWalletStub
backend(42);
772 EXPECT_TRUE(backend
.InitWithBus(mock_session_bus_
));
774 // First add an unrelated login.
775 BrowserThread::PostTask(
776 BrowserThread::DB
, FROM_HERE
,
777 base::Bind(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin
),
778 base::Unretained(&backend
), form_google_
));
782 std::vector
<const PasswordForm
*> forms
;
783 forms
.push_back(&form_google_
);
784 ExpectationArray expected
;
785 expected
.push_back(make_pair(std::string(form_google_
.signon_realm
), forms
));
786 CheckPasswordForms("Chrome Form Data (42)", expected
);
788 // Attempt to update a login that doesn't exist.
789 PasswordStoreChangeList changes
;
790 BrowserThread::PostTask(
791 BrowserThread::DB
, FROM_HERE
,
792 base::Bind(base::IgnoreResult(&NativeBackendKWalletStub::UpdateLogin
),
793 base::Unretained(&backend
),
795 base::Unretained(&changes
)));
799 EXPECT_EQ(PasswordStoreChangeList(), changes
);
800 CheckPasswordForms("Chrome Form Data (42)", expected
);
803 TEST_F(NativeBackendKWalletTest
, RemoveNonexistentLogin
) {
804 NativeBackendKWalletStub
backend(42);
805 EXPECT_TRUE(backend
.InitWithBus(mock_session_bus_
));
807 // First add an unrelated login.
808 BrowserThread::PostTask(
809 BrowserThread::DB
, FROM_HERE
,
810 base::Bind(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin
),
811 base::Unretained(&backend
), form_google_
));
815 EXPECT_FALSE(wallet_
.hasFolder("Chrome Form Data"));
817 std::vector
<const PasswordForm
*> forms
;
818 forms
.push_back(&form_google_
);
819 ExpectationArray expected
;
820 expected
.push_back(make_pair(std::string(form_google_
.signon_realm
), forms
));
821 CheckPasswordForms("Chrome Form Data (42)", expected
);
823 // Attempt to remove a login that doesn't exist.
824 BrowserThread::PostTask(
825 BrowserThread::DB
, FROM_HERE
,
826 base::Bind(base::IgnoreResult(&NativeBackendKWalletStub::RemoveLogin
),
827 base::Unretained(&backend
), form_isc_
));
829 // Make sure we can still get the first form back.
830 ScopedVector
<autofill::PasswordForm
> form_list
;
831 BrowserThread::PostTask(
832 BrowserThread::DB
, FROM_HERE
,
834 base::IgnoreResult(&NativeBackendKWalletStub::GetAutofillableLogins
),
835 base::Unretained(&backend
), &form_list
));
839 // Quick check that we got something back.
840 EXPECT_EQ(1u, form_list
.size());
842 CheckPasswordForms("Chrome Form Data (42)", expected
);
845 TEST_F(NativeBackendKWalletTest
, AddDuplicateLogin
) {
846 NativeBackendKWalletStub
backend(42);
847 EXPECT_TRUE(backend
.InitWithBus(mock_session_bus_
));
849 PasswordStoreChangeList changes
;
850 changes
.push_back(PasswordStoreChange(PasswordStoreChange::ADD
,
852 BrowserThread::PostTaskAndReplyWithResult(
853 BrowserThread::DB
, FROM_HERE
,
854 base::Bind(&NativeBackendKWalletStub::AddLogin
,
855 base::Unretained(&backend
), form_google_
),
856 base::Bind(&NativeBackendKWalletTest::CheckPasswordChanges
,
860 changes
.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE
,
862 form_google_
.times_used
++;
863 changes
.push_back(PasswordStoreChange(PasswordStoreChange::ADD
,
866 BrowserThread::PostTaskAndReplyWithResult(
867 BrowserThread::DB
, FROM_HERE
,
868 base::Bind(&NativeBackendKWalletStub::AddLogin
,
869 base::Unretained(&backend
), form_google_
),
870 base::Bind(&NativeBackendKWalletTest::CheckPasswordChanges
,
875 EXPECT_FALSE(wallet_
.hasFolder("Chrome Form Data"));
877 std::vector
<const PasswordForm
*> forms
;
878 forms
.push_back(&form_google_
);
879 ExpectationArray expected
;
880 expected
.push_back(make_pair(std::string(form_google_
.signon_realm
), forms
));
881 CheckPasswordForms("Chrome Form Data (42)", expected
);
884 TEST_F(NativeBackendKWalletTest
, AndroidCredentials
) {
885 NativeBackendKWalletStub
backend(42);
886 EXPECT_TRUE(backend
.InitWithBus(mock_session_bus_
));
888 PasswordForm observed_android_form
;
889 observed_android_form
.scheme
= PasswordForm::SCHEME_HTML
;
890 observed_android_form
.signon_realm
=
891 "android://7x7IDboo8u9YKraUsbmVkuf1-@net.rateflix.app/";
892 PasswordForm saved_android_form
= observed_android_form
;
893 saved_android_form
.username_value
= base::UTF8ToUTF16("randomusername");
894 saved_android_form
.password_value
= base::UTF8ToUTF16("password");
896 BrowserThread::PostTask(
897 BrowserThread::DB
, FROM_HERE
,
898 base::Bind(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin
),
899 base::Unretained(&backend
), saved_android_form
));
901 ScopedVector
<autofill::PasswordForm
> form_list
;
902 BrowserThread::PostTask(
903 BrowserThread::DB
, FROM_HERE
,
905 base::IgnoreResult(&NativeBackendKWalletStub::GetLogins
),
906 base::Unretained(&backend
), observed_android_form
, &form_list
));
910 EXPECT_EQ(1u, form_list
.size());
912 std::vector
<const PasswordForm
*> forms
;
913 forms
.push_back(&saved_android_form
);
914 ExpectationArray expected
;
916 make_pair(std::string(saved_android_form
.signon_realm
), forms
));
917 CheckPasswordForms("Chrome Form Data (42)", expected
);
920 TEST_F(NativeBackendKWalletTest
, RemoveLoginsCreatedBetween
) {
921 TestRemoveLoginsBetween(CREATED
);
924 TEST_F(NativeBackendKWalletTest
, RemoveLoginsSyncedBetween
) {
925 TestRemoveLoginsBetween(SYNCED
);
928 // TODO(mdm): add more basic tests here at some point.
929 // (For example tests for storing >1 password per realm pickle.)
931 class NativeBackendKWalletPickleTest
: public NativeBackendKWalletTestBase
{
933 void CreateVersion6Pickle(const PasswordForm
& form
, Pickle
* pickle
);
934 void CreateVersion5Pickle(const PasswordForm
& form
, Pickle
* pickle
);
935 void CreateVersion3Pickle(const PasswordForm
& form
, Pickle
* pickle
);
936 void CreateVersion2Pickle(const PasswordForm
& form
, Pickle
* pickle
);
937 void CreateVersion1Pickle(const PasswordForm
& form
, Pickle
* pickle
);
938 void CreateVersion0Pickle(bool size_32
,
939 const PasswordForm
& form
,
941 void CheckVersion6Pickle();
942 void CheckVersion5Pickle();
943 void CheckVersion3Pickle();
944 void CheckVersion2Pickle();
945 void CheckVersion1Pickle();
946 void CheckVersion0Pickle(bool size_32
, PasswordForm::Scheme scheme
);
949 // Creates a Pickle from |form|. If |size_32| is true, stores the number of
950 // forms in the pickle as a 32bit uint, otherwise as 64 bit size_t. The latter
951 // should be the case for versions > 0. If |date_created_internal| is true,
952 // stores |date_created| as base::Time's internal value, otherwise as time_t.
953 void CreatePickle(bool size_32
,
954 bool date_created_internal
,
955 const PasswordForm
& form
,
959 void NativeBackendKWalletPickleTest::CreateVersion6Pickle(
960 const PasswordForm
& form
,
963 CreatePickle(false, true, form
, pickle
);
964 pickle
->WriteInt(form
.type
);
965 pickle
->WriteInt(form
.times_used
);
966 autofill::SerializeFormData(form
.form_data
, pickle
);
967 pickle
->WriteInt64(form
.date_synced
.ToInternalValue());
968 pickle
->WriteString16(form
.display_name
);
969 pickle
->WriteString(form
.avatar_url
.spec());
970 pickle
->WriteString(form
.federation_url
.spec());
971 pickle
->WriteBool(form
.skip_zero_click
);
972 pickle
->WriteInt(form
.generation_upload_status
);
975 void NativeBackendKWalletPickleTest::CreateVersion5Pickle(
976 const PasswordForm
& form
,
979 CreatePickle(false, true, form
, pickle
);
980 pickle
->WriteInt(form
.type
);
981 pickle
->WriteInt(form
.times_used
);
982 autofill::SerializeFormData(form
.form_data
, pickle
);
983 pickle
->WriteInt64(form
.date_synced
.ToInternalValue());
984 pickle
->WriteString16(form
.display_name
);
985 pickle
->WriteString(form
.avatar_url
.spec());
986 pickle
->WriteString(form
.federation_url
.spec());
987 pickle
->WriteBool(form
.skip_zero_click
);
990 void NativeBackendKWalletPickleTest::CreateVersion3Pickle(
991 const PasswordForm
& form
, Pickle
* pickle
) {
993 CreatePickle(false, false, form
, pickle
);
994 pickle
->WriteInt(form
.type
);
995 pickle
->WriteInt(form
.times_used
);
996 autofill::SerializeFormData(form
.form_data
, pickle
);
997 pickle
->WriteInt64(form
.date_synced
.ToInternalValue());
1000 void NativeBackendKWalletPickleTest::CreateVersion2Pickle(
1001 const PasswordForm
& form
, Pickle
* pickle
) {
1002 pickle
->WriteInt(2);
1003 CreatePickle(false, false, form
, pickle
);
1004 pickle
->WriteInt(form
.type
);
1005 pickle
->WriteInt(form
.times_used
);
1006 autofill::SerializeFormData(form
.form_data
, pickle
);
1009 void NativeBackendKWalletPickleTest::CreateVersion1Pickle(
1010 const PasswordForm
& form
, Pickle
* pickle
) {
1011 pickle
->WriteInt(1);
1012 CreatePickle(false, false, form
, pickle
);
1015 void NativeBackendKWalletPickleTest::CreateVersion0Pickle(
1016 bool size_32
, const PasswordForm
& form
, Pickle
* pickle
) {
1017 pickle
->WriteInt(0);
1018 CreatePickle(size_32
, false, form
, pickle
);
1021 void NativeBackendKWalletPickleTest::CreatePickle(bool size_32
,
1022 bool date_created_internal
,
1023 const PasswordForm
& form
,
1026 pickle
->WriteUInt32(1); // Size of form list. 32 bits.
1028 pickle
->WriteSizeT(1); // Size of form list. 64 bits.
1029 pickle
->WriteInt(form
.scheme
);
1030 pickle
->WriteString(form
.origin
.spec());
1031 pickle
->WriteString(form
.action
.spec());
1032 pickle
->WriteString16(form
.username_element
);
1033 pickle
->WriteString16(form
.username_value
);
1034 pickle
->WriteString16(form
.password_element
);
1035 pickle
->WriteString16(form
.password_value
);
1036 pickle
->WriteString16(form
.submit_element
);
1037 pickle
->WriteBool(form
.ssl_valid
);
1038 pickle
->WriteBool(form
.preferred
);
1039 pickle
->WriteBool(form
.blacklisted_by_user
);
1040 if (date_created_internal
)
1041 pickle
->WriteInt64(form
.date_created
.ToInternalValue());
1043 pickle
->WriteInt64(form
.date_created
.ToTimeT());
1046 void NativeBackendKWalletPickleTest::CheckVersion6Pickle() {
1048 PasswordForm form
= form_google_
;
1049 form
.generation_upload_status
= PasswordForm::NEGATIVE_SIGNAL_SENT
;
1050 CreateVersion6Pickle(form
, &pickle
);
1052 ScopedVector
<PasswordForm
> form_list
=
1053 NativeBackendKWalletStub::DeserializeValue(form
.signon_realm
, pickle
);
1055 EXPECT_EQ(1u, form_list
.size());
1056 if (form_list
.size() > 0)
1057 CheckPasswordForm(form
, *form_list
[0], true);
1061 void NativeBackendKWalletPickleTest::CheckVersion5Pickle() {
1063 PasswordForm form
= form_google_
;
1064 CreateVersion5Pickle(form
, &pickle
);
1066 ScopedVector
<PasswordForm
> form_list
=
1067 NativeBackendKWalletStub::DeserializeValue(form
.signon_realm
, pickle
);
1069 EXPECT_EQ(1u, form_list
.size());
1070 if (form_list
.size() > 0)
1071 CheckPasswordForm(form
, *form_list
[0], true);
1074 void NativeBackendKWalletPickleTest::CheckVersion3Pickle() {
1076 PasswordForm form
= form_google_
;
1077 // Remove the fields which were not present in version #3.
1078 form
.display_name
.clear();
1079 form
.avatar_url
= GURL();
1080 form
.federation_url
= GURL();
1081 form
.skip_zero_click
= false;
1082 CreateVersion3Pickle(form
, &pickle
);
1084 ScopedVector
<PasswordForm
> form_list
=
1085 NativeBackendKWalletStub::DeserializeValue(form
.signon_realm
, pickle
);
1087 EXPECT_EQ(1u, form_list
.size());
1088 if (form_list
.size() > 0)
1089 CheckPasswordForm(form
, *form_list
[0], false);
1092 void NativeBackendKWalletPickleTest::CheckVersion2Pickle() {
1094 PasswordForm form
= old_form_google_
;
1095 form
.times_used
= form_google_
.times_used
;
1096 form
.type
= form_google_
.type
;
1097 form
.form_data
= form_google_
.form_data
;
1098 CreateVersion2Pickle(form
, &pickle
);
1100 ScopedVector
<PasswordForm
> form_list
=
1101 NativeBackendKWalletStub::DeserializeValue(form
.signon_realm
, pickle
);
1103 EXPECT_EQ(1u, form_list
.size());
1104 if (form_list
.size() > 0)
1105 CheckPasswordForm(form
, *form_list
[0], false);
1108 // Make sure that we can still read version 1 pickles.
1109 void NativeBackendKWalletPickleTest::CheckVersion1Pickle() {
1111 PasswordForm form
= form_google_
;
1112 CreateVersion1Pickle(form
, &pickle
);
1114 ScopedVector
<autofill::PasswordForm
> form_list
=
1115 NativeBackendKWalletStub::DeserializeValue(form
.signon_realm
, pickle
);
1117 // This will match |old_form_google_| because not all the fields present in
1118 // |form_google_| will be deserialized.
1119 EXPECT_EQ(1u, form_list
.size());
1120 if (form_list
.size() > 0)
1121 CheckPasswordForm(old_form_google_
, *form_list
[0], false);
1124 void NativeBackendKWalletPickleTest::CheckVersion0Pickle(
1125 bool size_32
, PasswordForm::Scheme scheme
) {
1127 PasswordForm form
= old_form_google_
;
1128 form
.scheme
= scheme
;
1129 CreateVersion0Pickle(size_32
, form
, &pickle
);
1130 ScopedVector
<autofill::PasswordForm
> form_list
=
1131 NativeBackendKWalletStub::DeserializeValue(form
.signon_realm
, pickle
);
1132 EXPECT_EQ(1u, form_list
.size());
1133 if (form_list
.size() > 0)
1134 CheckPasswordForm(form
, *form_list
[0], false);
1137 // Check that if KWallet fails to respond, the backend propagates the error.
1138 TEST_F(NativeBackendKWalletTest
, GetAllLoginsErrorHandling
) {
1139 NativeBackendKWalletStub
backend(42);
1140 EXPECT_TRUE(backend
.InitWithBus(mock_session_bus_
));
1141 // Make KWallet fail on calling readEntry.
1142 failing_methods_
.insert("readEntry");
1144 // Store some non-blacklisted logins to be potentially returned.
1145 BrowserThread::PostTask(
1146 BrowserThread::DB
, FROM_HERE
,
1147 base::Bind(base::IgnoreResult(&NativeBackendKWalletStub::AddLogin
),
1148 base::Unretained(&backend
), form_google_
));
1150 // Verify that nothing is in fact returned, because KWallet fails to respond.
1151 ScopedVector
<autofill::PasswordForm
> form_list
;
1152 BrowserThread::PostTask(BrowserThread::DB
, FROM_HERE
,
1153 base::Bind(&CheckGetAutofillableLoginsFails
,
1154 base::Unretained(&backend
), &form_list
));
1156 EXPECT_EQ(0u, form_list
.size());
1159 // We try both SCHEME_HTML and SCHEME_BASIC since the scheme is stored right
1160 // after the size in the pickle, so it's what gets read as part of the count
1161 // when reading 32-bit pickles on 64-bit systems. SCHEME_HTML is 0 (so we'll
1162 // detect errors later) while SCHEME_BASIC is 1 (so we'll detect it then). We
1163 // try both 32-bit and 64-bit pickles since only one will be the "other" size
1164 // for whatever architecture we're running on, but we want to make sure we can
1165 // read all combinations in any event.
1167 TEST_F(NativeBackendKWalletPickleTest
, ReadsOld32BitHTMLPickles
) {
1168 CheckVersion0Pickle(true, PasswordForm::SCHEME_HTML
);
1171 TEST_F(NativeBackendKWalletPickleTest
, ReadsOld32BitHTTPPickles
) {
1172 CheckVersion0Pickle(true, PasswordForm::SCHEME_BASIC
);
1175 TEST_F(NativeBackendKWalletPickleTest
, ReadsOld64BitHTMLPickles
) {
1176 CheckVersion0Pickle(false, PasswordForm::SCHEME_HTML
);
1179 TEST_F(NativeBackendKWalletPickleTest
, ReadsOld64BitHTTPPickles
) {
1180 CheckVersion0Pickle(false, PasswordForm::SCHEME_BASIC
);
1183 TEST_F(NativeBackendKWalletPickleTest
, CheckVersion1Pickle
) {
1184 CheckVersion1Pickle();
1187 TEST_F(NativeBackendKWalletPickleTest
, CheckVersion2Pickle
) {
1188 CheckVersion2Pickle();
1191 TEST_F(NativeBackendKWalletPickleTest
, CheckVersion3Pickle
) {
1192 CheckVersion3Pickle();
1195 TEST_F(NativeBackendKWalletPickleTest
, CheckVersion5Pickle
) {
1196 CheckVersion5Pickle();
1199 TEST_F(NativeBackendKWalletPickleTest
, CheckVersion6Pickle
) {
1200 CheckVersion6Pickle();