Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / password_manager / login_database_unittest.cc
blobf6146e46b3532fde62f4673528f7a083b9f0e0db
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.
5 #include "testing/gtest/include/gtest/gtest.h"
7 #include "base/basictypes.h"
8 #include "base/file_util.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/path_service.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/time/time.h"
14 #include "chrome/browser/password_manager/login_database.h"
15 #include "chrome/browser/password_manager/psl_matching_helper.h"
16 #include "chrome/common/chrome_paths.h"
17 #include "components/autofill/core/common/password_form.h"
18 #include "testing/gmock/include/gmock/gmock.h"
20 using autofill::PasswordForm;
21 using base::ASCIIToUTF16;
22 using ::testing::Eq;
24 class LoginDatabaseTest : public testing::Test {
25 protected:
26 virtual void SetUp() {
27 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
28 file_ = temp_dir_.path().AppendASCII("TestMetadataStoreMacDatabase");
30 ASSERT_TRUE(db_.Init(file_));
33 Pickle SerializeVector(const std::vector<base::string16>& vec) const {
34 return db_.SerializeVector(vec);
37 std::vector<base::string16> DeserializeVector(const Pickle& pickle) const {
38 return db_.DeserializeVector(pickle);
41 void FormsAreEqual(const PasswordForm& expected, const PasswordForm& actual) {
42 PasswordForm expected_copy(expected);
43 #if defined(OS_MACOSX)
44 // On the Mac we should never be storing passwords in the database.
45 expected_copy.password_value = ASCIIToUTF16("");
46 #endif
47 EXPECT_EQ(expected_copy, actual);
50 base::ScopedTempDir temp_dir_;
51 base::FilePath file_;
52 LoginDatabase db_;
55 TEST_F(LoginDatabaseTest, Logins) {
56 std::vector<PasswordForm*> result;
58 // Verify the database is empty.
59 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
60 EXPECT_EQ(0U, result.size());
62 // Example password form.
63 PasswordForm form;
64 form.origin = GURL("http://accounts.google.com/LoginAuth");
65 form.action = GURL("http://accounts.google.com/Login");
66 form.username_element = ASCIIToUTF16("Email");
67 form.username_value = ASCIIToUTF16("test@gmail.com");
68 form.password_element = ASCIIToUTF16("Passwd");
69 form.password_value = ASCIIToUTF16("test");
70 form.submit_element = ASCIIToUTF16("signIn");
71 form.signon_realm = "http://www.google.com/";
72 form.ssl_valid = false;
73 form.preferred = false;
74 form.scheme = PasswordForm::SCHEME_HTML;
75 form.times_used = 1;
76 form.form_data.name = ASCIIToUTF16("form_name");
77 form.form_data.method = ASCIIToUTF16("POST");
79 // Add it and make sure it is there and that all the fields were retrieved
80 // correctly.
81 EXPECT_TRUE(db_.AddLogin(form));
82 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
83 EXPECT_EQ(1U, result.size());
84 FormsAreEqual(form, *result[0]);
85 delete result[0];
86 result.clear();
88 // Match against an exact copy.
89 EXPECT_TRUE(db_.GetLogins(form, &result));
90 EXPECT_EQ(1U, result.size());
91 delete result[0];
92 result.clear();
94 // The example site changes...
95 PasswordForm form2(form);
96 form2.origin = GURL("http://www.google.com/new/accounts/LoginAuth");
97 form2.submit_element = ASCIIToUTF16("reallySignIn");
99 // Match against an inexact copy
100 EXPECT_TRUE(db_.GetLogins(form2, &result));
101 EXPECT_EQ(1U, result.size());
102 delete result[0];
103 result.clear();
105 // Uh oh, the site changed origin & action URLs all at once!
106 PasswordForm form3(form2);
107 form3.action = GURL("http://www.google.com/new/accounts/Login");
109 // signon_realm is the same, should match.
110 EXPECT_TRUE(db_.GetLogins(form3, &result));
111 EXPECT_EQ(1U, result.size());
112 delete result[0];
113 result.clear();
115 // Imagine the site moves to a secure server for login.
116 PasswordForm form4(form3);
117 form4.signon_realm = "https://www.google.com/";
118 form4.ssl_valid = true;
120 // We have only an http record, so no match for this.
121 EXPECT_TRUE(db_.GetLogins(form4, &result));
122 EXPECT_EQ(0U, result.size());
124 // Let's imagine the user logs into the secure site.
125 EXPECT_TRUE(db_.AddLogin(form4));
126 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
127 EXPECT_EQ(2U, result.size());
128 delete result[0];
129 delete result[1];
130 result.clear();
132 // Now the match works
133 EXPECT_TRUE(db_.GetLogins(form4, &result));
134 EXPECT_EQ(1U, result.size());
135 delete result[0];
136 result.clear();
138 // The user chose to forget the original but not the new.
139 EXPECT_TRUE(db_.RemoveLogin(form));
140 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
141 EXPECT_EQ(1U, result.size());
142 delete result[0];
143 result.clear();
145 // The old form wont match the new site (http vs https).
146 EXPECT_TRUE(db_.GetLogins(form, &result));
147 EXPECT_EQ(0U, result.size());
149 // The user's request for the HTTPS site is intercepted
150 // by an attacker who presents an invalid SSL cert.
151 PasswordForm form5(form4);
152 form5.ssl_valid = 0;
154 // It will match in this case.
155 EXPECT_TRUE(db_.GetLogins(form5, &result));
156 EXPECT_EQ(1U, result.size());
157 delete result[0];
158 result.clear();
160 // User changes his password.
161 PasswordForm form6(form5);
162 form6.password_value = ASCIIToUTF16("test6");
163 form6.preferred = true;
165 // We update, and check to make sure it matches the
166 // old form, and there is only one record.
167 int rows_changed = 0;
168 EXPECT_TRUE(db_.UpdateLogin(form6, &rows_changed));
169 EXPECT_EQ(1, rows_changed);
170 // matches
171 EXPECT_TRUE(db_.GetLogins(form5, &result));
172 EXPECT_EQ(1U, result.size());
173 delete result[0];
174 result.clear();
175 // Only one record.
176 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
177 EXPECT_EQ(1U, result.size());
178 // Password element was updated.
179 #if defined(OS_MACOSX)
180 // On the Mac we should never be storing passwords in the database.
181 EXPECT_EQ(base::string16(), result[0]->password_value);
182 #else
183 EXPECT_EQ(form6.password_value, result[0]->password_value);
184 #endif
185 // Preferred login.
186 EXPECT_TRUE(form6.preferred);
187 delete result[0];
188 result.clear();
190 // Make sure everything can disappear.
191 EXPECT_TRUE(db_.RemoveLogin(form4));
192 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
193 EXPECT_EQ(0U, result.size());
196 TEST_F(LoginDatabaseTest, TestPublicSuffixDomainMatching) {
197 PSLMatchingHelper::EnablePublicSuffixDomainMatchingForTesting();
198 std::vector<PasswordForm*> result;
200 // Verify the database is empty.
201 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
202 EXPECT_EQ(0U, result.size());
204 // Example password form.
205 PasswordForm form;
206 form.origin = GURL("https://foo.com/");
207 form.action = GURL("https://foo.com/login");
208 form.username_element = ASCIIToUTF16("username");
209 form.username_value = ASCIIToUTF16("test@gmail.com");
210 form.password_element = ASCIIToUTF16("password");
211 form.password_value = ASCIIToUTF16("test");
212 form.submit_element = ASCIIToUTF16("");
213 form.signon_realm = "https://foo.com/";
214 form.ssl_valid = true;
215 form.preferred = false;
216 form.scheme = PasswordForm::SCHEME_HTML;
218 // Add it and make sure it is there.
219 EXPECT_TRUE(db_.AddLogin(form));
220 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
221 EXPECT_EQ(1U, result.size());
222 delete result[0];
223 result.clear();
225 // Match against an exact copy.
226 EXPECT_TRUE(db_.GetLogins(form, &result));
227 EXPECT_EQ(1U, result.size());
228 delete result[0];
229 result.clear();
231 // We go to the mobile site.
232 PasswordForm form2(form);
233 form2.origin = GURL("https://mobile.foo.com/");
234 form2.action = GURL("https://mobile.foo.com/login");
235 form2.signon_realm = "https://mobile.foo.com/";
237 // Match against the mobile site.
238 EXPECT_TRUE(db_.GetLogins(form2, &result));
239 EXPECT_EQ(1U, result.size());
240 EXPECT_EQ("https://mobile.foo.com/", result[0]->signon_realm);
241 EXPECT_EQ("https://foo.com/", result[0]->original_signon_realm);
242 delete result[0];
243 result.clear();
246 TEST_F(LoginDatabaseTest, TestPublicSuffixDomainMatchingShouldMatchingApply) {
247 PSLMatchingHelper::EnablePublicSuffixDomainMatchingForTesting();
248 std::vector<PasswordForm*> result;
250 // Verify the database is empty.
251 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
252 EXPECT_EQ(0U, result.size());
254 // Example password form.
255 PasswordForm form;
256 form.origin = GURL("https://accounts.google.com/");
257 form.action = GURL("https://accounts.google.com/login");
258 form.username_element = ASCIIToUTF16("username");
259 form.username_value = ASCIIToUTF16("test@gmail.com");
260 form.password_element = ASCIIToUTF16("password");
261 form.password_value = ASCIIToUTF16("test");
262 form.submit_element = ASCIIToUTF16("");
263 form.signon_realm = "https://accounts.google.com/";
264 form.ssl_valid = true;
265 form.preferred = false;
266 form.scheme = PasswordForm::SCHEME_HTML;
268 // Add it and make sure it is there.
269 EXPECT_TRUE(db_.AddLogin(form));
270 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
271 EXPECT_EQ(1U, result.size());
272 delete result[0];
273 result.clear();
275 // Match against an exact copy.
276 EXPECT_TRUE(db_.GetLogins(form, &result));
277 EXPECT_EQ(1U, result.size());
278 delete result[0];
279 result.clear();
281 // We go to a different site on the same domain where feature is not needed.
282 PasswordForm form2(form);
283 form2.origin = GURL("https://some.other.google.com/");
284 form2.action = GURL("https://some.other.google.com/login");
285 form2.signon_realm = "https://some.other.google.com/";
287 // Match against the other site. Should not match since feature should not be
288 // enabled for this domain.
289 EXPECT_TRUE(db_.GetLogins(form2, &result));
290 EXPECT_EQ(0U, result.size());
293 // This test fails if the implementation of GetLogins uses GetCachedStatement
294 // instead of GetUniqueStatement, since REGEXP is in use. See
295 // http://crbug.com/248608.
296 TEST_F(LoginDatabaseTest, TestPublicSuffixDomainMatchingDifferentSites) {
297 PSLMatchingHelper::EnablePublicSuffixDomainMatchingForTesting();
298 std::vector<PasswordForm*> result;
300 // Verify the database is empty.
301 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
302 EXPECT_EQ(0U, result.size());
304 // Example password form.
305 PasswordForm form;
306 form.origin = GURL("https://foo.com/");
307 form.action = GURL("https://foo.com/login");
308 form.username_element = ASCIIToUTF16("username");
309 form.username_value = ASCIIToUTF16("test@gmail.com");
310 form.password_element = ASCIIToUTF16("password");
311 form.password_value = ASCIIToUTF16("test");
312 form.submit_element = ASCIIToUTF16("");
313 form.signon_realm = "https://foo.com/";
314 form.ssl_valid = true;
315 form.preferred = false;
316 form.scheme = PasswordForm::SCHEME_HTML;
318 // Add it and make sure it is there.
319 EXPECT_TRUE(db_.AddLogin(form));
320 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
321 EXPECT_EQ(1U, result.size());
322 delete result[0];
323 result.clear();
325 // Match against an exact copy.
326 EXPECT_TRUE(db_.GetLogins(form, &result));
327 EXPECT_EQ(1U, result.size());
328 delete result[0];
329 result.clear();
331 // We go to the mobile site.
332 PasswordForm form2(form);
333 form2.origin = GURL("https://mobile.foo.com/");
334 form2.action = GURL("https://mobile.foo.com/login");
335 form2.signon_realm = "https://mobile.foo.com/";
337 // Match against the mobile site.
338 EXPECT_TRUE(db_.GetLogins(form2, &result));
339 EXPECT_EQ(1U, result.size());
340 EXPECT_EQ("https://mobile.foo.com/", result[0]->signon_realm);
341 EXPECT_EQ("https://foo.com/", result[0]->original_signon_realm);
342 delete result[0];
343 result.clear();
345 // Add baz.com desktop site.
346 form.origin = GURL("https://baz.com/login/");
347 form.action = GURL("https://baz.com/login/");
348 form.username_element = ASCIIToUTF16("email");
349 form.username_value = ASCIIToUTF16("test@gmail.com");
350 form.password_element = ASCIIToUTF16("password");
351 form.password_value = ASCIIToUTF16("test");
352 form.submit_element = ASCIIToUTF16("");
353 form.signon_realm = "https://baz.com/";
354 form.ssl_valid = true;
355 form.preferred = false;
356 form.scheme = PasswordForm::SCHEME_HTML;
358 // Add it and make sure it is there.
359 EXPECT_TRUE(db_.AddLogin(form));
360 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
361 EXPECT_EQ(2U, result.size());
362 delete result[0];
363 delete result[1];
364 result.clear();
366 // We go to the mobile site of baz.com.
367 PasswordForm form3(form);
368 form3.origin = GURL("https://m.baz.com/login/");
369 form3.action = GURL("https://m.baz.com/login/");
370 form3.signon_realm = "https://m.baz.com/";
372 // Match against the mobile site of baz.com.
373 EXPECT_TRUE(db_.GetLogins(form3, &result));
374 EXPECT_EQ(1U, result.size());
375 EXPECT_EQ("https://m.baz.com/", result[0]->signon_realm);
376 EXPECT_EQ("https://baz.com/", result[0]->original_signon_realm);
377 delete result[0];
378 result.clear();
381 PasswordForm GetFormWithNewSignonRealm(PasswordForm form,
382 std::string signon_realm) {
383 PasswordForm form2(form);
384 form2.origin = GURL(signon_realm);
385 form2.action = GURL(signon_realm);
386 form2.signon_realm = signon_realm;
387 return form2;
390 TEST_F(LoginDatabaseTest, TestPublicSuffixDomainMatchingRegexp) {
391 PSLMatchingHelper::EnablePublicSuffixDomainMatchingForTesting();
392 std::vector<PasswordForm*> result;
394 // Verify the database is empty.
395 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
396 EXPECT_EQ(0U, result.size());
398 // Example password form.
399 PasswordForm form;
400 form.origin = GURL("http://foo.com/");
401 form.action = GURL("http://foo.com/login");
402 form.username_element = ASCIIToUTF16("username");
403 form.username_value = ASCIIToUTF16("test@gmail.com");
404 form.password_element = ASCIIToUTF16("password");
405 form.password_value = ASCIIToUTF16("test");
406 form.submit_element = ASCIIToUTF16("");
407 form.signon_realm = "http://foo.com/";
408 form.ssl_valid = false;
409 form.preferred = false;
410 form.scheme = PasswordForm::SCHEME_HTML;
412 // Add it and make sure it is there.
413 EXPECT_TRUE(db_.AddLogin(form));
414 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
415 EXPECT_EQ(1U, result.size());
416 delete result[0];
417 result.clear();
419 // Example password form that has - in the domain name.
420 PasswordForm form_dash =
421 GetFormWithNewSignonRealm(form, "http://www.foo-bar.com/");
423 // Add it and make sure it is there.
424 EXPECT_TRUE(db_.AddLogin(form_dash));
425 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
426 EXPECT_EQ(2U, result.size());
427 delete result[0];
428 delete result[1];
429 result.clear();
431 // Match against an exact copy.
432 EXPECT_TRUE(db_.GetLogins(form, &result));
433 EXPECT_EQ(1U, result.size());
434 delete result[0];
435 result.clear();
437 // www.foo.com should match.
438 PasswordForm form2 = GetFormWithNewSignonRealm(form, "http://www.foo.com/");
439 EXPECT_TRUE(db_.GetLogins(form2, &result));
440 EXPECT_EQ(1U, result.size());
441 delete result[0];
442 result.clear();
444 // a.b.foo.com should match.
445 form2 = GetFormWithNewSignonRealm(form, "http://a.b.foo.com/");
446 EXPECT_TRUE(db_.GetLogins(form2, &result));
447 EXPECT_EQ(1U, result.size());
448 delete result[0];
449 result.clear();
451 // a-b.foo.com should match.
452 form2 = GetFormWithNewSignonRealm(form, "http://a-b.foo.com/");
453 EXPECT_TRUE(db_.GetLogins(form2, &result));
454 EXPECT_EQ(1U, result.size());
455 delete result[0];
456 result.clear();
458 // foo-bar.com should match.
459 form2 = GetFormWithNewSignonRealm(form, "http://foo-bar.com/");
460 EXPECT_TRUE(db_.GetLogins(form2, &result));
461 EXPECT_EQ(1U, result.size());
462 delete result[0];
463 result.clear();
465 // www.foo-bar.com should match.
466 form2 = GetFormWithNewSignonRealm(form, "http://www.foo-bar.com/");
467 EXPECT_TRUE(db_.GetLogins(form2, &result));
468 EXPECT_EQ(1U, result.size());
469 delete result[0];
470 result.clear();
472 // a.b.foo-bar.com should match.
473 form2 = GetFormWithNewSignonRealm(form, "http://a.b.foo-bar.com/");
474 EXPECT_TRUE(db_.GetLogins(form2, &result));
475 EXPECT_EQ(1U, result.size());
476 delete result[0];
477 result.clear();
479 // a-b.foo-bar.com should match.
480 form2 = GetFormWithNewSignonRealm(form, "http://a-b.foo-bar.com/");
481 EXPECT_TRUE(db_.GetLogins(form2, &result));
482 EXPECT_EQ(1U, result.size());
483 delete result[0];
484 result.clear();
486 // foo.com with port 1337 should not match.
487 form2 = GetFormWithNewSignonRealm(form, "http://foo.com:1337/");
488 EXPECT_TRUE(db_.GetLogins(form2, &result));
489 EXPECT_EQ(0U, result.size());
491 // http://foo.com should not match since the scheme is wrong.
492 form2 = GetFormWithNewSignonRealm(form, "https://foo.com/");
493 EXPECT_TRUE(db_.GetLogins(form2, &result));
494 EXPECT_EQ(0U, result.size());
496 // notfoo.com should not match.
497 form2 = GetFormWithNewSignonRealm(form, "http://notfoo.com/");
498 EXPECT_TRUE(db_.GetLogins(form2, &result));
499 EXPECT_EQ(0U, result.size());
501 // baz.com should not match.
502 form2 = GetFormWithNewSignonRealm(form, "http://baz.com/");
503 EXPECT_TRUE(db_.GetLogins(form2, &result));
504 EXPECT_EQ(0U, result.size());
506 // foo-baz.com should not match.
507 form2 = GetFormWithNewSignonRealm(form, "http://foo-baz.com/");
508 EXPECT_TRUE(db_.GetLogins(form2, &result));
509 EXPECT_EQ(0U, result.size());
512 static bool AddTimestampedLogin(LoginDatabase* db, std::string url,
513 const std::string& unique_string,
514 const base::Time& time) {
515 // Example password form.
516 PasswordForm form;
517 form.origin = GURL(url + std::string("/LoginAuth"));
518 form.username_element = ASCIIToUTF16(unique_string);
519 form.username_value = ASCIIToUTF16(unique_string);
520 form.password_element = ASCIIToUTF16(unique_string);
521 form.submit_element = ASCIIToUTF16("signIn");
522 form.signon_realm = url;
523 form.date_created = time;
524 return db->AddLogin(form);
527 static void ClearResults(std::vector<PasswordForm*>* results) {
528 for (size_t i = 0; i < results->size(); ++i) {
529 delete (*results)[i];
531 results->clear();
534 TEST_F(LoginDatabaseTest, ClearPrivateData_SavedPasswords) {
535 std::vector<PasswordForm*> result;
537 // Verify the database is empty.
538 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
539 EXPECT_EQ(0U, result.size());
541 base::Time now = base::Time::Now();
542 base::TimeDelta one_day = base::TimeDelta::FromDays(1);
544 // Create one with a 0 time.
545 EXPECT_TRUE(AddTimestampedLogin(&db_, "1", "foo1", base::Time()));
546 // Create one for now and +/- 1 day.
547 EXPECT_TRUE(AddTimestampedLogin(&db_, "2", "foo2", now - one_day));
548 EXPECT_TRUE(AddTimestampedLogin(&db_, "3", "foo3", now));
549 EXPECT_TRUE(AddTimestampedLogin(&db_, "4", "foo4", now + one_day));
551 // Verify inserts worked.
552 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
553 EXPECT_EQ(4U, result.size());
554 ClearResults(&result);
556 // Get everything from today's date and on.
557 EXPECT_TRUE(db_.GetLoginsCreatedBetween(now, base::Time(), &result));
558 EXPECT_EQ(2U, result.size());
559 ClearResults(&result);
561 // Delete everything from today's date and on.
562 db_.RemoveLoginsCreatedBetween(now, base::Time());
564 // Should have deleted half of what we inserted.
565 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
566 EXPECT_EQ(2U, result.size());
567 ClearResults(&result);
569 // Delete with 0 date (should delete all).
570 db_.RemoveLoginsCreatedBetween(base::Time(), base::Time());
572 // Verify nothing is left.
573 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
574 EXPECT_EQ(0U, result.size());
577 TEST_F(LoginDatabaseTest, BlacklistedLogins) {
578 std::vector<PasswordForm*> result;
580 // Verify the database is empty.
581 EXPECT_TRUE(db_.GetBlacklistLogins(&result));
582 ASSERT_EQ(0U, result.size());
584 // Save a form as blacklisted.
585 PasswordForm form;
586 form.origin = GURL("http://accounts.google.com/LoginAuth");
587 form.action = GURL("http://accounts.google.com/Login");
588 form.username_element = ASCIIToUTF16("Email");
589 form.password_element = ASCIIToUTF16("Passwd");
590 form.submit_element = ASCIIToUTF16("signIn");
591 form.signon_realm = "http://www.google.com/";
592 form.ssl_valid = false;
593 form.preferred = true;
594 form.blacklisted_by_user = true;
595 form.scheme = PasswordForm::SCHEME_HTML;
596 EXPECT_TRUE(db_.AddLogin(form));
598 // Get all non-blacklisted logins (should be none).
599 EXPECT_TRUE(db_.GetAutofillableLogins(&result));
600 ASSERT_EQ(0U, result.size());
602 // GetLogins should give the blacklisted result.
603 EXPECT_TRUE(db_.GetLogins(form, &result));
604 EXPECT_EQ(1U, result.size());
605 ClearResults(&result);
607 // So should GetAllBlacklistedLogins.
608 EXPECT_TRUE(db_.GetBlacklistLogins(&result));
609 EXPECT_EQ(1U, result.size());
610 ClearResults(&result);
613 TEST_F(LoginDatabaseTest, VectorSerialization) {
614 // Empty vector.
615 std::vector<base::string16> vec;
616 Pickle temp = SerializeVector(vec);
617 std::vector<base::string16> output = DeserializeVector(temp);
618 EXPECT_THAT(output, Eq(vec));
620 // Normal data.
621 vec.push_back(ASCIIToUTF16("first"));
622 vec.push_back(ASCIIToUTF16("second"));
623 vec.push_back(ASCIIToUTF16("third"));
625 temp = SerializeVector(vec);
626 output = DeserializeVector(temp);
627 EXPECT_THAT(output, Eq(vec));
630 #if defined(OS_POSIX)
631 // Only the current user has permission to read the database.
633 // Only POSIX because GetPosixFilePermissions() only exists on POSIX.
634 // This tests that sql::Connection::set_restrict_to_user() was called,
635 // and that function is a noop on non-POSIX platforms in any case.
636 TEST_F(LoginDatabaseTest, FilePermissions) {
637 int mode = base::FILE_PERMISSION_MASK;
638 EXPECT_TRUE(base::GetPosixFilePermissions(file_, &mode));
639 EXPECT_EQ((mode & base::FILE_PERMISSION_USER_MASK), mode);
641 #endif // defined(OS_POSIX)