diff options
author | skrul@chromium.org <skrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-23 17:36:34 +0000 |
---|---|---|
committer | skrul@chromium.org <skrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-23 17:36:34 +0000 |
commit | b30cc9b857649093b7a64580fb148e5f33e4d9ed (patch) | |
tree | bc37e6ec0cc18e3077ba38d33f9043c223eb4daf /chrome/browser | |
parent | 0d042152a8807390262609f20c04ba26773f1d7c (diff) | |
download | chromium_src-b30cc9b857649093b7a64580fb148e5f33e4d9ed.zip chromium_src-b30cc9b857649093b7a64580fb148e5f33e4d9ed.tar.gz chromium_src-b30cc9b857649093b7a64580fb148e5f33e4d9ed.tar.bz2 |
Landing this patch on behalf of Mark Hahnenberg <mhahnenb(at)gmail.com>
Added a vector of Time objects to the AutofillEntry object for storingthe results retrieved from the date_created field of the autofill_datestable corresponding to the AutofillKey retrieved from the autofill table.
Also modified the old GetAllAutofillEntries test to account for this newlystored data.
BUG=35230
TEST=WebDatabaseTest.GetAllAutofillEntries
Review URL: http://codereview.chromium.org/600070
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39742 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/webdata/autofill_entry.h | 10 | ||||
-rw-r--r-- | chrome/browser/webdata/web_database.cc | 46 | ||||
-rw-r--r-- | chrome/browser/webdata/web_database.h | 5 | ||||
-rw-r--r-- | chrome/browser/webdata/web_database_unittest.cc | 219 |
4 files changed, 230 insertions, 50 deletions
diff --git a/chrome/browser/webdata/autofill_entry.h b/chrome/browser/webdata/autofill_entry.h index add7201..850f93b 100644 --- a/chrome/browser/webdata/autofill_entry.h +++ b/chrome/browser/webdata/autofill_entry.h @@ -5,7 +5,9 @@ #ifndef CHROME_BROWSER_WEBDATA_AUTOFILL_ENTRY_H__ #define CHROME_BROWSER_WEBDATA_AUTOFILL_ENTRY_H__ +#include <vector> #include "base/string16.h" +#include "base/time.h" class AutofillKey { public: @@ -29,13 +31,19 @@ class AutofillKey { class AutofillEntry { public: - explicit AutofillEntry(const AutofillKey& key) : key_(key) {} + AutofillEntry(const AutofillKey& key, + const std::vector<base::Time>& timestamps) + : key_(key), + timestamps_(timestamps) {} const AutofillKey& key() const { return key_; } + const std::vector<base::Time>& timestamps() const { return timestamps_; } bool operator==(const AutofillEntry& entry) const; + private: AutofillKey key_; + std::vector<base::Time> timestamps_; }; #endif // CHROME_BROWSER_WEBDATA_AUTOFILL_ENTRY_H__ diff --git a/chrome/browser/webdata/web_database.cc b/chrome/browser/webdata/web_database.cc index 6642529..252113e 100644 --- a/chrome/browser/webdata/web_database.cc +++ b/chrome/browser/webdata/web_database.cc @@ -987,17 +987,55 @@ bool WebDatabase::GetCountOfFormElement(int64 pair_id, int* count) { bool WebDatabase::GetAllAutofillEntries(std::vector<AutofillEntry>* entries) { DCHECK(entries); - sql::Statement s(db_.GetUniqueStatement("SELECT name, value FROM autofill")); + sql::Statement s(db_.GetUniqueStatement( + "SELECT name, value, date_created FROM autofill a JOIN " + "autofill_dates ad ON a.pair_id=ad.pair_id")); + if (!s) { NOTREACHED() << "Statement prepare failed"; return false; } + bool first_entry = true; + AutofillKey* current_key_ptr; + std::vector<base::Time>* timestamps_ptr; + string16 name, value; + base::Time time; while (s.Step()) { - AutofillKey key(UTF8ToUTF16(s.ColumnString(0)), - UTF8ToUTF16(s.ColumnString(1))); - AutofillEntry entry(key); + name = ASCIIToUTF16(s.ColumnString(0)); + value = ASCIIToUTF16(s.ColumnString(1)); + time = Time::FromTimeT(s.ColumnInt64(2)); + + if (first_entry) { + current_key_ptr = new AutofillKey(name, value); + + timestamps_ptr = new std::vector<base::Time>; + timestamps_ptr->push_back(time); + + first_entry = false; + } else { + // we've encountered the next entry + if (current_key_ptr->name().compare(name) != 0 || + current_key_ptr->value().compare(value) != 0) { + AutofillEntry entry(*current_key_ptr, *timestamps_ptr); + entries->push_back(entry); + + delete current_key_ptr; + delete timestamps_ptr; + + current_key_ptr = new AutofillKey(name, value); + timestamps_ptr = new std::vector<base::Time>; + } + timestamps_ptr->push_back(time); + } + } + // If there is at least one result returned, first_entry will be false. + // For this case we need to do a final cleanup step. + if (!first_entry) { + AutofillEntry entry(*current_key_ptr, *timestamps_ptr); entries->push_back(entry); + delete current_key_ptr; + delete timestamps_ptr; } return s.Succeeded(); diff --git a/chrome/browser/webdata/web_database.h b/chrome/browser/webdata/web_database.h index d3ece62..c383610 100644 --- a/chrome/browser/webdata/web_database.h +++ b/chrome/browser/webdata/web_database.h @@ -20,6 +20,7 @@ class AutofillEntry; class AutoFillProfile; class CreditCard; class FilePath; +class WebDatabaseTest; namespace base { class Time; @@ -255,7 +256,9 @@ class WebDatabase { FRIEND_TEST(WebDatabaseTest, Autofill); FRIEND_TEST(WebDatabaseTest, Autofill_AddChanges); FRIEND_TEST(WebDatabaseTest, Autofill_RemoveBetweenChanges); - + FRIEND_TEST(WebDatabaseTest, Autofill_GetAllAutofillEntries_OneResult); + FRIEND_TEST(WebDatabaseTest, Autofill_GetAllAutofillEntries_TwoDistinct); + FRIEND_TEST(WebDatabaseTest, Autofill_GetAllAutofillEntries_TwoSame); // Methods for adding autofill entries at a specified time. For // testing only. bool AddFormFieldValuesTime( diff --git a/chrome/browser/webdata/web_database_unittest.cc b/chrome/browser/webdata/web_database_unittest.cc index 6881365..68cf00e 100644 --- a/chrome/browser/webdata/web_database_unittest.cc +++ b/chrome/browser/webdata/web_database_unittest.cc @@ -59,6 +59,10 @@ std::ostream& operator<<(std::ostream& os, const AutofillChange& change) { class WebDatabaseTest : public testing::Test { protected: typedef std::vector<AutofillChange> AutofillChangeList; + typedef std::set<AutofillEntry, + bool (*)(const AutofillEntry&, const AutofillEntry&)> AutofillEntrySet; + typedef std::set<AutofillEntry, bool (*)(const AutofillEntry&, + const AutofillEntry&)>::iterator AutofillEntrySetIterator; virtual void SetUp() { PathService::Get(chrome::DIR_TEST_DATA, &file_); const std::string test_db = "TestWebDatabase" + @@ -1020,72 +1024,199 @@ TEST_F(WebDatabaseTest, CreditCard) { &db_creditcard)); } -TEST_F(WebDatabaseTest, GetAllAutofillEntries) { +bool CompareAutofillEntries(const AutofillEntry& a, const AutofillEntry& b) { + string16 aNameValue = a.key().name() + a.key().value(); + string16 bNameValue = b.key().name() + b.key().value(); + + std::set<base::Time> timestamps1(a.timestamps().begin(), + a.timestamps().end()); + std::set<base::Time> timestamps2(b.timestamps().begin(), + b.timestamps().end()); + + int compVal = a.key().name().compare(b.key().name()); + if (compVal != 0) { + return compVal < 0; + } + + compVal = a.key().value().compare(b.key().value()); + if (compVal != 0) { + return compVal < 0; + } + + if (timestamps1.size() != timestamps2.size()) { + return timestamps1.size() < timestamps2.size(); + } + + std::set<base::Time>::iterator it; + for (it = timestamps1.begin(); it != timestamps1.end(); it++) { + timestamps2.erase(*it); + } + + return timestamps2.size() != 0U; +} + +TEST_F(WebDatabaseTest, Autofill_GetAllAutofillEntries_NoResults) { + WebDatabase db; + + ASSERT_EQ(sql::INIT_OK, db.Init(file_)); + + std::vector<AutofillEntry> entries; + ASSERT_TRUE(db.GetAllAutofillEntries(&entries)); + + EXPECT_EQ(0U, entries.size()); +} + +TEST_F(WebDatabaseTest, Autofill_GetAllAutofillEntries_OneResult) { WebDatabase db; ASSERT_EQ(sql::INIT_OK, db.Init(file_)); - // Simulate the submission of a handful of entries in a field called "Name", - // some more often than others. AutofillChangeList changes; - EXPECT_TRUE(db.AddFormFieldValue( + std::map<std::string, std::vector<base::Time> > name_value_times_map; + + time_t start = 0; + std::vector<base::Time> timestamps1; + EXPECT_TRUE(db.AddFormFieldValueTime( FormField(string16(), ASCIIToUTF16("Name"), ASCIIToUTF16("Superman"), string16(), WebKit::WebInputElement::Text), - &changes)); - for (int i = 0; i < 5; i++) { - EXPECT_TRUE(db.AddFormFieldValue( - FormField(string16(), - ASCIIToUTF16("Name"), - ASCIIToUTF16("Clark Kent"), - string16(), - WebKit::WebInputElement::Text), - &changes)); + &changes, + Time::FromTimeT(start))); + timestamps1.push_back(Time::FromTimeT(start)); + std::string key1("NameSuperman"); + name_value_times_map.insert(std::pair<std::string, + std::vector<base::Time> > (key1, timestamps1)); + + AutofillEntrySet expected_entries(CompareAutofillEntries); + AutofillKey ak1(ASCIIToUTF16("Name"), ASCIIToUTF16("Superman")); + AutofillEntry ae1(ak1, timestamps1); + + expected_entries.insert(ae1); + + std::vector<AutofillEntry> entries; + ASSERT_TRUE(db.GetAllAutofillEntries(&entries)); + AutofillEntrySet entry_set(entries.begin(), entries.end(), + CompareAutofillEntries); + + // make sure the lists of entries match + ASSERT_EQ(expected_entries.size(), entry_set.size()); + AutofillEntrySetIterator it; + for (it = entry_set.begin(); it != entry_set.end(); it++) { + expected_entries.erase(*it); } - for (int i = 0; i < 3; i++) { - EXPECT_TRUE(db.AddFormFieldValue( - FormField(string16(), - ASCIIToUTF16("Name"), - ASCIIToUTF16("Clark Sutter"), - string16(), - WebKit::WebInputElement::Text), - &changes)); + + EXPECT_EQ(0U, expected_entries.size()); +} + +TEST_F(WebDatabaseTest, Autofill_GetAllAutofillEntries_TwoDistinct) { + WebDatabase db; + + ASSERT_EQ(sql::INIT_OK, db.Init(file_)); + + AutofillChangeList changes; + std::map<std::string, std::vector<base::Time> > name_value_times_map; + time_t start = 0; + + std::vector<base::Time> timestamps1; + EXPECT_TRUE(db.AddFormFieldValueTime( + FormField(string16(), + ASCIIToUTF16("Name"), + ASCIIToUTF16("Superman"), + string16(), + WebKit::WebInputElement::Text), + &changes, + Time::FromTimeT(start))); + timestamps1.push_back(Time::FromTimeT(start)); + std::string key1("NameSuperman"); + name_value_times_map.insert(std::pair<std::string, + std::vector<base::Time> > (key1, timestamps1)); + + start++; + std::vector<base::Time> timestamps2; + EXPECT_TRUE(db.AddFormFieldValueTime( + FormField(string16(), + ASCIIToUTF16("Name"), + ASCIIToUTF16("Clark Kent"), + string16(), + WebKit::WebInputElement::Text), + &changes, + Time::FromTimeT(start))); + timestamps2.push_back(Time::FromTimeT(start)); + std::string key2("NameClark Kent"); + name_value_times_map.insert(std::pair<std::string, + std::vector<base::Time> > (key2, timestamps2)); + + AutofillEntrySet expected_entries(CompareAutofillEntries); + AutofillKey ak1(ASCIIToUTF16("Name"), ASCIIToUTF16("Superman")); + AutofillKey ak2(ASCIIToUTF16("Name"), ASCIIToUTF16("Clark Kent")); + AutofillEntry ae1(ak1, timestamps1); + AutofillEntry ae2(ak2, timestamps2); + + expected_entries.insert(ae1); + expected_entries.insert(ae2); + + std::vector<AutofillEntry> entries; + ASSERT_TRUE(db.GetAllAutofillEntries(&entries)); + AutofillEntrySet entry_set(entries.begin(), entries.end(), + CompareAutofillEntries); + + // make sure the lists of entries match + ASSERT_EQ(expected_entries.size(), entry_set.size()); + AutofillEntrySetIterator it; + for (it = entry_set.begin(); it != entry_set.end(); it++) { + expected_entries.erase(*it); } + + EXPECT_EQ(0U, expected_entries.size()); +} + +TEST_F(WebDatabaseTest, Autofill_GetAllAutofillEntries_TwoSame) { + WebDatabase db; + + ASSERT_EQ(sql::INIT_OK, db.Init(file_)); + + AutofillChangeList changes; + std::map<std::string, std::vector<base::Time> > name_value_times_map; + + time_t start = 0; + std::vector<base::Time> timestamps; for (int i = 0; i < 2; i++) { - EXPECT_TRUE(db.AddFormFieldValue( + EXPECT_TRUE(db.AddFormFieldValueTime( FormField(string16(), - ASCIIToUTF16("Favorite Color"), - ASCIIToUTF16("Green"), + ASCIIToUTF16("Name"), + ASCIIToUTF16("Superman"), string16(), WebKit::WebInputElement::Text), - &changes)); + &changes, + Time::FromTimeT(start))); + timestamps.push_back(Time::FromTimeT(start)); + start++; } - // we should get something along the lines of: [("Name", "Superman"), - // ("Name", "Clark Kent"), ("Name", "Clark Sutter"), - // ("Favorite Color", "Green")] - std::list<AutofillEntry> expected_entries; + std::string key("NameSuperman"); + name_value_times_map.insert(std::pair<std::string, + std::vector<base::Time> > (key, timestamps)); + + AutofillEntrySet expected_entries(CompareAutofillEntries); AutofillKey ak1(ASCIIToUTF16("Name"), ASCIIToUTF16("Superman")); - AutofillKey ak2(ASCIIToUTF16("Name"), ASCIIToUTF16("Clark Kent")); - AutofillKey ak3(ASCIIToUTF16("Name"), ASCIIToUTF16("Clark Sutter")); - AutofillKey ak4(ASCIIToUTF16("Favorite Color"), ASCIIToUTF16("Green")); - AutofillEntry ae1(ak1); - AutofillEntry ae2(ak2); - AutofillEntry ae3(ak3); - AutofillEntry ae4(ak4); - expected_entries.push_back(ae1); - expected_entries.push_back(ae2); - expected_entries.push_back(ae3); - expected_entries.push_back(ae4); + AutofillEntry ae1(ak1, timestamps); - std::vector<AutofillEntry> entries; - EXPECT_TRUE(db.GetAllAutofillEntries(&entries)); + expected_entries.insert(ae1); - for (unsigned int i = 0; i < entries.size(); i++) { - expected_entries.remove(entries[i]); + std::vector<AutofillEntry> entries; + ASSERT_TRUE(db.GetAllAutofillEntries(&entries)); + AutofillEntrySet entry_set(entries.begin(), entries.end(), + CompareAutofillEntries); + + // make sure the lists of entries match + ASSERT_EQ(expected_entries.size(), entry_set.size()); + AutofillEntrySetIterator it; + for (it = entry_set.begin(); it != entry_set.end(); it++) { + expected_entries.erase(*it); } EXPECT_EQ(0U, expected_entries.size()); } + |