blob: 6f5dad1c8b4d2f7fc59c86492a93cd922f094e53 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string>
#include "base/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/guid.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/browser/webdata/keyword_table.h"
#include "chrome/browser/webdata/logins_table.h"
#include "chrome/browser/webdata/web_apps_table.h"
#include "chrome/browser/webdata/web_intents_table.h"
#include "components/autofill/core/browser/autofill_country.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/webdata/autofill_change.h"
#include "components/autofill/core/browser/webdata/autofill_entry.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
#include "components/signin/core/browser/webdata/token_service_table.h"
#include "components/webdata/common/web_database.h"
#include "sql/statement.h"
#include "testing/gtest/include/gtest/gtest.h"
using autofill::AutofillProfile;
using autofill::AutofillTable;
using autofill::CreditCard;
using base::ASCIIToUTF16;
using base::Time;
namespace {
void AutofillProfile31FromStatement(const sql::Statement& s,
AutofillProfile* profile,
base::string16* label,
int* unique_id,
int64* date_modified) {
DCHECK(profile);
DCHECK(label);
DCHECK(unique_id);
DCHECK(date_modified);
*label = s.ColumnString16(0);
*unique_id = s.ColumnInt(1);
profile->SetRawInfo(autofill::NAME_FIRST, s.ColumnString16(2));
profile->SetRawInfo(autofill::NAME_MIDDLE, s.ColumnString16(3));
profile->SetRawInfo(autofill::NAME_LAST, s.ColumnString16(4));
profile->SetRawInfo(autofill::EMAIL_ADDRESS, s.ColumnString16(5));
profile->SetRawInfo(autofill::COMPANY_NAME, s.ColumnString16(6));
profile->SetRawInfo(autofill::ADDRESS_HOME_LINE1, s.ColumnString16(7));
profile->SetRawInfo(autofill::ADDRESS_HOME_LINE2, s.ColumnString16(8));
profile->SetRawInfo(autofill::ADDRESS_HOME_CITY, s.ColumnString16(9));
profile->SetRawInfo(autofill::ADDRESS_HOME_STATE, s.ColumnString16(10));
profile->SetRawInfo(autofill::ADDRESS_HOME_ZIP, s.ColumnString16(11));
profile->SetInfo(
autofill::AutofillType(autofill::ADDRESS_HOME_COUNTRY),
s.ColumnString16(12), "en-US");
profile->SetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER, s.ColumnString16(13));
*date_modified = s.ColumnInt64(15);
profile->set_guid(s.ColumnString(16));
EXPECT_TRUE(base::IsValidGUID(profile->guid()));
}
void AutofillProfile33FromStatement(const sql::Statement& s,
AutofillProfile* profile,
int64* date_modified) {
DCHECK(profile);
DCHECK(date_modified);
profile->set_guid(s.ColumnString(0));
EXPECT_TRUE(base::IsValidGUID(profile->guid()));
profile->SetRawInfo(autofill::COMPANY_NAME, s.ColumnString16(1));
profile->SetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS,
s.ColumnString16(2));
profile->SetRawInfo(autofill::ADDRESS_HOME_CITY, s.ColumnString16(3));
profile->SetRawInfo(autofill::ADDRESS_HOME_STATE, s.ColumnString16(4));
profile->SetRawInfo(autofill::ADDRESS_HOME_ZIP, s.ColumnString16(5));
profile->SetInfo(
autofill::AutofillType(autofill::ADDRESS_HOME_COUNTRY),
s.ColumnString16(6), "en-US");
*date_modified = s.ColumnInt64(7);
}
void CreditCard31FromStatement(const sql::Statement& s,
CreditCard* credit_card,
base::string16* label,
int* unique_id,
std::string* encrypted_number,
int64* date_modified) {
DCHECK(credit_card);
DCHECK(label);
DCHECK(unique_id);
DCHECK(encrypted_number);
DCHECK(date_modified);
*label = s.ColumnString16(0);
*unique_id = s.ColumnInt(1);
credit_card->SetRawInfo(autofill::CREDIT_CARD_NAME, s.ColumnString16(2));
credit_card->SetRawInfo(autofill::CREDIT_CARD_TYPE, s.ColumnString16(3));
credit_card->SetRawInfo(autofill::CREDIT_CARD_EXP_MONTH, s.ColumnString16(5));
credit_card->SetRawInfo(
autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR, s.ColumnString16(6));
int encrypted_number_len = s.ColumnByteLength(10);
if (encrypted_number_len) {
encrypted_number->resize(encrypted_number_len);
memcpy(&(*encrypted_number)[0], s.ColumnBlob(10), encrypted_number_len);
}
*date_modified = s.ColumnInt64(12);
credit_card->set_guid(s.ColumnString(13));
EXPECT_TRUE(base::IsValidGUID(credit_card->guid()));
}
void CreditCard32FromStatement(const sql::Statement& s,
CreditCard* credit_card,
std::string* encrypted_number,
int64* date_modified) {
DCHECK(credit_card);
DCHECK(encrypted_number);
DCHECK(date_modified);
credit_card->set_guid(s.ColumnString(0));
EXPECT_TRUE(base::IsValidGUID(credit_card->guid()));
credit_card->SetRawInfo(autofill::CREDIT_CARD_NAME, s.ColumnString16(1));
credit_card->SetRawInfo(autofill::CREDIT_CARD_EXP_MONTH, s.ColumnString16(2));
credit_card->SetRawInfo(
autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR, s.ColumnString16(3));
int encrypted_number_len = s.ColumnByteLength(4);
if (encrypted_number_len) {
encrypted_number->resize(encrypted_number_len);
memcpy(&(*encrypted_number)[0], s.ColumnBlob(4), encrypted_number_len);
}
*date_modified = s.ColumnInt64(5);
}
void CheckHasBackupData(sql::MetaTable* meta_table) {
std::string value;
EXPECT_TRUE(meta_table->GetValue(
"Default Search Provider ID Backup", &value));
EXPECT_TRUE(meta_table->GetValue(
"Default Search Provider ID Backup Signature", &value));
}
void CheckNoBackupData(const sql::Connection& connection,
sql::MetaTable* meta_table) {
std::string value;
EXPECT_FALSE(meta_table->GetValue(
"Default Search Provider ID Backup", &value));
EXPECT_FALSE(meta_table->GetValue(
"Default Search Provider ID Backup Signature", &value));
EXPECT_FALSE(connection.DoesTableExist("keywords_backup"));
}
std::string RemoveQuotes(const std::string& has_quotes) {
std::string no_quotes;
// SQLite quotes: http://www.sqlite.org/lang_keywords.html
base::RemoveChars(has_quotes, "\"[]`", &no_quotes);
return no_quotes;
}
} // anonymous namespace
// The WebDatabaseMigrationTest encapsulates testing of database migrations.
// Specifically, these tests are intended to exercise any schema changes in
// the WebDatabase and data migrations that occur in
// |WebDatabase::MigrateOldVersionsAsNeeded()|.
class WebDatabaseMigrationTest : public testing::Test {
public:
WebDatabaseMigrationTest() {}
virtual ~WebDatabaseMigrationTest() {}
virtual void SetUp() {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
}
// Load the database via the WebDatabase class and migrate the database to
// the current version.
void DoMigration() {
// TODO(joi): This whole unit test file needs to stay in //chrome
// for now, as it needs to know about all the different table
// types. Once all webdata datatypes have been componentized, this
// could move to components_unittests.
AutofillTable autofill_table("en-US");
KeywordTable keyword_table;
LoginsTable logins_table;
TokenServiceTable token_service_table;
WebAppsTable web_apps_table;
WebIntentsTable web_intents_table;
WebDatabase db;
db.AddTable(&autofill_table);
db.AddTable(&keyword_table);
db.AddTable(&logins_table);
db.AddTable(&token_service_table);
db.AddTable(&web_apps_table);
db.AddTable(&web_intents_table);
// This causes the migration to occur.
ASSERT_EQ(sql::INIT_OK, db.Init(GetDatabasePath()));
}
protected:
// Current tested version number. When adding a migration in
// |WebDatabase::MigrateOldVersionsAsNeeded()| and changing the version number
// |kCurrentVersionNumber| this value should change to reflect the new version
// number and a new migration test added below.
static const int kCurrentTestedVersionNumber;
base::FilePath GetDatabasePath() {
const base::FilePath::CharType kWebDatabaseFilename[] =
FILE_PATH_LITERAL("TestWebDatabase.sqlite3");
return temp_dir_.path().Append(base::FilePath(kWebDatabaseFilename));
}
// The textual contents of |file| are read from
// "components/test/data/web_database" and returned in the string |contents|.
// Returns true if the file exists and is read successfully, false otherwise.
bool GetWebDatabaseData(const base::FilePath& file, std::string* contents) {
base::FilePath source_path;
PathService::Get(base::DIR_SOURCE_ROOT, &source_path);
source_path = source_path.AppendASCII("components");
source_path = source_path.AppendASCII("test");
source_path = source_path.AppendASCII("data");
source_path = source_path.AppendASCII("web_database");
source_path = source_path.Append(file);
return base::PathExists(source_path) &&
base::ReadFileToString(source_path, contents);
}
static int VersionFromConnection(sql::Connection* connection) {
// Get version.
sql::Statement s(connection->GetUniqueStatement(
"SELECT value FROM meta WHERE key='version'"));
if (!s.Step())
return 0;
return s.ColumnInt(0);
}
// The sql files located in "chrome/test/data/web_database" were generated by
// launching the Chromium application prior to schema change, then using the
// sqlite3 command-line application to dump the contents of the "Web Data"
// database.
// Like this:
// > .output version_nn.sql
// > .dump
void LoadDatabase(const base::FilePath::StringType& file);
private:
base::ScopedTempDir temp_dir_;
DISALLOW_COPY_AND_ASSIGN(WebDatabaseMigrationTest);
};
const int WebDatabaseMigrationTest::kCurrentTestedVersionNumber = 57;
void WebDatabaseMigrationTest::LoadDatabase(
const base::FilePath::StringType& file) {
std::string contents;
ASSERT_TRUE(GetWebDatabaseData(base::FilePath(file), &contents));
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(connection.Execute(contents.data()));
}
// Tests that migrating from the golden files version_XX.sql results in the same
// schema as migrating from an empty database.
TEST_F(WebDatabaseMigrationTest, VersionXxSqlFilesAreGolden) {
DoMigration();
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
const std::string& expected_schema = RemoveQuotes(connection.GetSchema());
static const int kFirstVersion = 53;
for (int i = kFirstVersion; i < kCurrentTestedVersionNumber; ++i) {
connection.Raze();
const base::FilePath& file_name = base::FilePath::FromUTF8Unsafe(
"version_" + base::IntToString(i) + ".sql");
ASSERT_NO_FATAL_FAILURE(LoadDatabase(file_name.value()))
<< "Failed to load " << file_name.MaybeAsASCII();
DoMigration();
EXPECT_EQ(expected_schema, RemoveQuotes(connection.GetSchema()));
}
}
// Tests that the all migrations from an empty database succeed.
TEST_F(WebDatabaseMigrationTest, MigrateEmptyToCurrent) {
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// Check that expected tables are present.
EXPECT_TRUE(connection.DoesTableExist("autofill"));
// The autofill_dates table is obsolete. (It's been merged into the autofill
// table.)
EXPECT_FALSE(connection.DoesTableExist("autofill_dates"));
EXPECT_TRUE(connection.DoesTableExist("autofill_profiles"));
EXPECT_TRUE(connection.DoesTableExist("credit_cards"));
EXPECT_TRUE(connection.DoesTableExist("keywords"));
// The logins table is obsolete. (We used to store saved passwords here.)
EXPECT_FALSE(connection.DoesTableExist("logins"));
EXPECT_TRUE(connection.DoesTableExist("meta"));
EXPECT_TRUE(connection.DoesTableExist("token_service"));
EXPECT_TRUE(connection.DoesTableExist("web_app_icons"));
EXPECT_TRUE(connection.DoesTableExist("web_apps"));
EXPECT_TRUE(connection.DoesTableExist("web_intents"));
EXPECT_TRUE(connection.DoesTableExist("web_intents_defaults"));
}
}
// Tests that absent Autofill tables do not create any problems when migrating
// from a DB written by the earliest publicly released version of Chrome.
TEST_F(WebDatabaseMigrationTest, MigrateVersion20ToCurrent) {
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_20.sql")));
// Verify pre-conditions.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
EXPECT_FALSE(connection.DoesTableExist("autofill"));
EXPECT_FALSE(connection.DoesTableExist("autofill_profiles"));
EXPECT_FALSE(connection.DoesTableExist("credit_cards"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// Mostly this test just verifies that no SQL errors occur during migration;
// but might as well verify that the tables were created as well.
EXPECT_TRUE(connection.DoesTableExist("autofill"));
EXPECT_TRUE(connection.DoesTableExist("autofill_profiles"));
EXPECT_TRUE(connection.DoesTableExist("credit_cards"));
}
}
// Tests that rows with empty values get removed from the autofill tables.
TEST_F(WebDatabaseMigrationTest, MigrateVersion21ToCurrent) {
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_21.sql")));
// Verify pre-conditions.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Both empty and non-empty values are allowed in a version 21 database.
sql::Statement s_autofill(connection.GetUniqueStatement(
"SELECT name, value, value_lower, pair_id, count FROM autofill"));
sql::Statement s_dates(connection.GetUniqueStatement(
"SELECT pair_id, date_created FROM autofill_dates"));
// An entry with a non-empty value.
ASSERT_TRUE(s_autofill.Step());
EXPECT_EQ(ASCIIToUTF16("Name"), s_autofill.ColumnString16(0));
EXPECT_EQ(ASCIIToUTF16("John Doe"), s_autofill.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("john doe"), s_autofill.ColumnString16(2));
EXPECT_EQ(10, s_autofill.ColumnInt(3));
EXPECT_EQ(1, s_autofill.ColumnInt(4));
ASSERT_TRUE(s_dates.Step());
EXPECT_EQ(10, s_dates.ColumnInt(0));
EXPECT_EQ(1384299100, s_dates.ColumnInt64(1));
// An entry with an empty value.
ASSERT_TRUE(s_autofill.Step());
EXPECT_EQ(ASCIIToUTF16("Name"), s_autofill.ColumnString16(0));
EXPECT_EQ(base::string16(), s_autofill.ColumnString16(1));
EXPECT_EQ(base::string16(), s_autofill.ColumnString16(2));
EXPECT_EQ(11, s_autofill.ColumnInt(3));
EXPECT_EQ(1, s_autofill.ColumnInt(4));
ASSERT_TRUE(s_dates.Step());
EXPECT_EQ(11, s_dates.ColumnInt(0));
EXPECT_EQ(1384299200, s_dates.ColumnInt64(1));
// Another entry with a non-empty value.
ASSERT_TRUE(s_autofill.Step());
EXPECT_EQ(ASCIIToUTF16("Email"), s_autofill.ColumnString16(0));
EXPECT_EQ(ASCIIToUTF16("jane@example.com"), s_autofill.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("jane@example.com"), s_autofill.ColumnString16(2));
EXPECT_EQ(20, s_autofill.ColumnInt(3));
EXPECT_EQ(3, s_autofill.ColumnInt(4));
ASSERT_TRUE(s_dates.Step());
EXPECT_EQ(20, s_dates.ColumnInt(0));
EXPECT_EQ(1384299300, s_dates.ColumnInt64(1));
ASSERT_TRUE(s_dates.Step());
EXPECT_EQ(20, s_dates.ColumnInt(0));
EXPECT_EQ(1384299301, s_dates.ColumnInt64(1));
// Another entry with an empty value.
ASSERT_TRUE(s_autofill.Step());
EXPECT_EQ(ASCIIToUTF16("Email"), s_autofill.ColumnString16(0));
EXPECT_EQ(base::string16(), s_autofill.ColumnString16(1));
EXPECT_EQ(base::string16(), s_autofill.ColumnString16(2));
EXPECT_EQ(21, s_autofill.ColumnInt(3));
EXPECT_EQ(4, s_autofill.ColumnInt(4));
ASSERT_TRUE(s_dates.Step());
EXPECT_EQ(21, s_dates.ColumnInt(0));
EXPECT_EQ(1384299401, s_dates.ColumnInt64(1));
ASSERT_TRUE(s_dates.Step());
EXPECT_EQ(21, s_dates.ColumnInt(0));
EXPECT_EQ(1384299400, s_dates.ColumnInt64(1));
ASSERT_TRUE(s_dates.Step());
EXPECT_EQ(21, s_dates.ColumnInt(0));
EXPECT_EQ(1384299403, s_dates.ColumnInt64(1));
ASSERT_TRUE(s_dates.Step());
EXPECT_EQ(21, s_dates.ColumnInt(0));
EXPECT_EQ(1384299402, s_dates.ColumnInt64(1));
// No more entries expected.
ASSERT_FALSE(s_autofill.Step());
ASSERT_FALSE(s_dates.Step());
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// Entries with empty values should have been dropped. The remaining
// entries should have been preserved.
sql::Statement s(
connection.GetUniqueStatement(
"SELECT name, value, value_lower, date_created, date_last_used,"
" count "
"FROM autofill "
"ORDER BY name, value ASC"));
// "jane@example.com"
ASSERT_TRUE(s.Step());
EXPECT_EQ(ASCIIToUTF16("Email"), s.ColumnString16(0));
EXPECT_EQ(ASCIIToUTF16("jane@example.com"), s.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("jane@example.com"), s.ColumnString16(2));
EXPECT_EQ(1384299300, s.ColumnInt64(3));
EXPECT_EQ(1384299301, s.ColumnInt64(4));
EXPECT_EQ(3, s.ColumnInt(5));
// "John Doe"
ASSERT_TRUE(s.Step());
EXPECT_EQ(ASCIIToUTF16("Name"), s.ColumnString16(0));
EXPECT_EQ(ASCIIToUTF16("John Doe"), s.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("john doe"), s.ColumnString16(2));
EXPECT_EQ(1384299100, s.ColumnInt64(3));
EXPECT_EQ(1384299100, s.ColumnInt64(4));
EXPECT_EQ(1, s.ColumnInt(5));
// No more entries expected.
ASSERT_FALSE(s.Step());
}
}
// Tests that the |credit_card| table gets added to the schema for a version 22
// database.
TEST_F(WebDatabaseMigrationTest, MigrateVersion22ToCurrent) {
// This schema is taken from a build prior to the addition of the
// |credit_card| table. Version 22 of the schema. Contrast this with the
// corrupt version below.
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_22.sql")));
// Verify pre-conditions.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// No |credit_card| table prior to version 23.
ASSERT_FALSE(connection.DoesColumnExist("credit_cards", "guid"));
ASSERT_FALSE(
connection.DoesColumnExist("credit_cards", "card_number_encrypted"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// |credit_card| table now exists.
EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "guid"));
EXPECT_TRUE(
connection.DoesColumnExist("credit_cards", "card_number_encrypted"));
}
}
// Tests that the |credit_card| table gets added to the schema for a corrupt
// version 22 database. The corruption is that the |credit_cards| table exists
// but the schema version number was not set correctly to 23 or later. This
// test exercises code introduced to fix bug http://crbug.com/50699 that
// resulted from the corruption.
TEST_F(WebDatabaseMigrationTest, MigrateVersion22CorruptedToCurrent) {
// This schema is taken from a build after the addition of the |credit_card|
// table. Due to a bug in the migration logic the version is set incorrectly
// to 22 (it should have been updated to 23 at least).
ASSERT_NO_FATAL_FAILURE(
LoadDatabase(FILE_PATH_LITERAL("version_22_corrupt.sql")));
// Verify pre-conditions. These are expectations for corrupt version 22 of
// the database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Columns existing and not existing before current version.
ASSERT_TRUE(connection.DoesColumnExist("credit_cards", "unique_id"));
ASSERT_TRUE(
connection.DoesColumnExist("credit_cards", "card_number_encrypted"));
ASSERT_TRUE(connection.DoesColumnExist("keywords", "id"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// Columns existing and not existing before version 25.
EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "unique_id"));
EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "guid"));
EXPECT_TRUE(
connection.DoesColumnExist("credit_cards", "card_number_encrypted"));
EXPECT_TRUE(connection.DoesColumnExist("keywords", "id"));
}
}
// Tests that the |keywords| |created_by_policy| column gets added to the schema
// for a version 25 database.
TEST_F(WebDatabaseMigrationTest, MigrateVersion25ToCurrent) {
// This schema is taken from a build prior to the addition of the |keywords|
// |created_by_policy| column.
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_25.sql")));
// Verify pre-conditions. These are expectations for version 25 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// |keywords| |created_by_policy| column should have been added.
EXPECT_TRUE(connection.DoesColumnExist("keywords", "id"));
EXPECT_TRUE(connection.DoesColumnExist("keywords", "created_by_policy"));
}
}
// Tests that the credit_cards.billing_address column is changed from a string
// to an int whilst preserving the associated billing address. This version of
// the test makes sure a stored label is converted to an ID.
TEST_F(WebDatabaseMigrationTest, MigrateVersion26ToCurrentStringLabels) {
// This schema is taken from a build prior to the change of column type for
// credit_cards.billing_address from string to int.
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_26.sql")));
// Verify pre-conditions. These are expectations for version 26 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Columns existing and not existing before current version.
EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "billing_address"));
std::string stmt = "INSERT INTO autofill_profiles"
"(label, unique_id, first_name, middle_name, last_name, email,"
" company_name, address_line_1, address_line_2, city, state, zipcode,"
" country, phone, fax)"
"VALUES ('Home',1,'','','','','','','','','','','','','')";
sql::Statement s(connection.GetUniqueStatement(stmt.c_str()));
ASSERT_TRUE(s.Run());
// Insert a CC linked to an existing address.
std::string stmt2 = "INSERT INTO credit_cards"
"(label, unique_id, name_on_card, type, card_number,"
" expiration_month, expiration_year, verification_code, billing_address,"
" shipping_address, card_number_encrypted, verification_code_encrypted)"
"VALUES ('label',2,'Jack','Visa','1234',2,2012,'','Home','','','')";
sql::Statement s2(connection.GetUniqueStatement(stmt2.c_str()));
ASSERT_TRUE(s2.Run());
// |billing_address| is a string.
std::string stmt3 = "SELECT billing_address FROM credit_cards";
sql::Statement s3(connection.GetUniqueStatement(stmt3.c_str()));
ASSERT_TRUE(s3.Step());
EXPECT_EQ(s3.ColumnType(0), sql::COLUMN_TYPE_TEXT);
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "billing_address"));
// Verify the credit card data is converted.
sql::Statement s(connection.GetUniqueStatement(
"SELECT guid, name_on_card, expiration_month, expiration_year, "
"card_number_encrypted, date_modified "
"FROM credit_cards"));
ASSERT_TRUE(s.Step());
EXPECT_EQ("Jack", s.ColumnString(1));
EXPECT_EQ(2, s.ColumnInt(2));
EXPECT_EQ(2012, s.ColumnInt(3));
// Column 5 is encrypted number blob.
// Column 6 is date_modified.
}
}
// Tests that the credit_cards.billing_address column is changed from a string
// to an int whilst preserving the associated billing address. This version of
// the test makes sure a stored string ID is converted to an integer ID.
TEST_F(WebDatabaseMigrationTest, MigrateVersion26ToCurrentStringIDs) {
// This schema is taken from a build prior to the change of column type for
// credit_cards.billing_address from string to int.
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_26.sql")));
// Verify pre-conditions. These are expectations for version 26 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "billing_address"));
std::string stmt = "INSERT INTO autofill_profiles"
"(label, unique_id, first_name, middle_name, last_name, email,"
" company_name, address_line_1, address_line_2, city, state, zipcode,"
" country, phone, fax)"
"VALUES ('Home',1,'','','','','','','','','','','','','')";
sql::Statement s(connection.GetUniqueStatement(stmt.c_str()));
ASSERT_TRUE(s.Run());
// Insert a CC linked to an existing address.
std::string stmt2 = "INSERT INTO credit_cards"
"(label, unique_id, name_on_card, type, card_number,"
" expiration_month, expiration_year, verification_code, billing_address,"
" shipping_address, card_number_encrypted, verification_code_encrypted)"
"VALUES ('label',2,'Jack','Visa','1234',2,2012,'','1','','','')";
sql::Statement s2(connection.GetUniqueStatement(stmt2.c_str()));
ASSERT_TRUE(s2.Run());
// |billing_address| is a string.
std::string stmt3 = "SELECT billing_address FROM credit_cards";
sql::Statement s3(connection.GetUniqueStatement(stmt3.c_str()));
ASSERT_TRUE(s3.Step());
EXPECT_EQ(s3.ColumnType(0), sql::COLUMN_TYPE_TEXT);
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// |keywords| |created_by_policy| column should have been added.
EXPECT_TRUE(connection.DoesColumnExist("keywords", "id"));
EXPECT_TRUE(connection.DoesColumnExist("keywords", "created_by_policy"));
EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "billing_address"));
// Verify the credit card data is converted.
sql::Statement s(connection.GetUniqueStatement(
"SELECT guid, name_on_card, expiration_month, expiration_year, "
"card_number_encrypted, date_modified "
"FROM credit_cards"));
ASSERT_TRUE(s.Step());
EXPECT_EQ("Jack", s.ColumnString(1));
EXPECT_EQ(2, s.ColumnInt(2));
EXPECT_EQ(2012, s.ColumnInt(3));
// Column 5 is encrypted credit card number blo b.
// Column 6 is date_modified.
}
}
// Makes sure instant_url is added correctly to keywords.
TEST_F(WebDatabaseMigrationTest, MigrateVersion27ToCurrent) {
// Initialize the database.
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_27.sql")));
// Verify pre-conditions. These are expectations for version 27 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_FALSE(connection.DoesColumnExist("keywords", "instant_url"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// Make sure supports_instant (added in Version 28) was ultimately dropped
// again and instant_url was added.
EXPECT_FALSE(connection.DoesColumnExist("keywords", "supports_instant"));
EXPECT_TRUE(connection.DoesColumnExist("keywords", "instant_url"));
// Check that instant_url is empty.
std::string stmt = "SELECT instant_url FROM keywords";
sql::Statement s(connection.GetUniqueStatement(stmt.c_str()));
ASSERT_TRUE(s.Step());
EXPECT_EQ(std::string(), s.ColumnString(0));
// Verify the data made it over.
stmt = "SELECT " + KeywordTable::GetKeywordColumns() + " FROM keywords";
sql::Statement s2(connection.GetUniqueStatement(stmt.c_str()));
ASSERT_TRUE(s2.Step());
EXPECT_EQ(2, s2.ColumnInt(0));
EXPECT_EQ("Google", s2.ColumnString(1));
EXPECT_EQ("google.com", s2.ColumnString(2));
EXPECT_EQ("http://www.google.com/favicon.ico", s2.ColumnString(3));
EXPECT_EQ("{google:baseURL}search?{google:RLZ}{google:acceptedSuggestion}"\
"{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}"\
"&q={searchTerms}",
s2.ColumnString(4));
EXPECT_TRUE(s2.ColumnBool(5));
EXPECT_EQ(std::string(), s2.ColumnString(6));
EXPECT_EQ(0, s2.ColumnInt(7));
EXPECT_EQ(0, s2.ColumnInt(8));
EXPECT_EQ(std::string("UTF-8"), s2.ColumnString(9));
EXPECT_TRUE(s2.ColumnBool(10));
EXPECT_EQ(std::string("{google:baseSuggestURL}search?client=chrome&hl="
"{language}&q={searchTerms}"), s2.ColumnString(11));
EXPECT_EQ(1, s2.ColumnInt(12));
EXPECT_FALSE(s2.ColumnBool(13));
EXPECT_EQ(std::string(), s2.ColumnString(14));
EXPECT_EQ(0, s2.ColumnInt(15));
EXPECT_EQ(std::string(), s2.ColumnString(16));
}
}
// Makes sure date_modified is added correctly to autofill_profiles and
// credit_cards.
TEST_F(WebDatabaseMigrationTest, MigrateVersion29ToCurrent) {
// Initialize the database.
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_29.sql")));
// Verify pre-conditions. These are expectations for version 29 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles",
"date_modified"));
EXPECT_FALSE(connection.DoesColumnExist("credit_cards",
"date_modified"));
}
Time pre_creation_time = Time::Now();
DoMigration();
Time post_creation_time = Time::Now();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// Check that the columns were created.
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles",
"date_modified"));
EXPECT_TRUE(connection.DoesColumnExist("credit_cards",
"date_modified"));
sql::Statement s_profiles(connection.GetUniqueStatement(
"SELECT date_modified FROM autofill_profiles "));
ASSERT_TRUE(s_profiles.is_valid());
while (s_profiles.Step()) {
EXPECT_GE(s_profiles.ColumnInt64(0),
pre_creation_time.ToTimeT());
EXPECT_LE(s_profiles.ColumnInt64(0),
post_creation_time.ToTimeT());
}
EXPECT_TRUE(s_profiles.Succeeded());
sql::Statement s_credit_cards(connection.GetUniqueStatement(
"SELECT date_modified FROM credit_cards "));
ASSERT_TRUE(s_credit_cards.is_valid());
while (s_credit_cards.Step()) {
EXPECT_GE(s_credit_cards.ColumnInt64(0),
pre_creation_time.ToTimeT());
EXPECT_LE(s_credit_cards.ColumnInt64(0),
post_creation_time.ToTimeT());
}
EXPECT_TRUE(s_credit_cards.Succeeded());
}
}
// Makes sure guids are added to autofill_profiles and credit_cards tables.
TEST_F(WebDatabaseMigrationTest, MigrateVersion30ToCurrent) {
// Initialize the database.
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_30.sql")));
// Verify pre-conditions. These are expectations for version 29 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "guid"));
EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "guid"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
ASSERT_TRUE(connection.DoesColumnExist("autofill_profiles", "guid"));
ASSERT_TRUE(connection.DoesColumnExist("credit_cards", "guid"));
// Check that guids are non-null, non-empty, conforms to guid format, and
// are different.
sql::Statement s(
connection.GetUniqueStatement("SELECT guid FROM autofill_profiles"));
ASSERT_TRUE(s.Step());
std::string guid1 = s.ColumnString(0);
EXPECT_TRUE(base::IsValidGUID(guid1));
ASSERT_TRUE(s.Step());
std::string guid2 = s.ColumnString(0);
EXPECT_TRUE(base::IsValidGUID(guid2));
EXPECT_NE(guid1, guid2);
}
}
// Removes unique IDs and make GUIDs the primary key. Also removes unused
// columns.
TEST_F(WebDatabaseMigrationTest, MigrateVersion31ToCurrent) {
// Initialize the database.
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_31.sql")));
// Verify pre-conditions. These are expectations for version 30 of the
// database.
AutofillProfile profile;
base::string16 profile_label;
int profile_unique_id = 0;
int64 profile_date_modified = 0;
CreditCard credit_card;
base::string16 cc_label;
int cc_unique_id = 0;
std::string cc_number_encrypted;
int64 cc_date_modified = 0;
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Verify existence of columns we'll be changing.
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "guid"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "unique_id"));
EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "guid"));
EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "unique_id"));
EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "type"));
EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "card_number"));
EXPECT_TRUE(connection.DoesColumnExist("credit_cards",
"verification_code"));
EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "billing_address"));
EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "shipping_address"));
EXPECT_TRUE(connection.DoesColumnExist("credit_cards",
"verification_code_encrypted"));
// Fetch data in the database prior to migration.
sql::Statement s1(
connection.GetUniqueStatement(
"SELECT label, unique_id, first_name, middle_name, last_name, "
"email, company_name, address_line_1, address_line_2, city, state, "
"zipcode, country, phone, fax, date_modified, guid "
"FROM autofill_profiles"));
ASSERT_TRUE(s1.Step());
EXPECT_NO_FATAL_FAILURE(AutofillProfile31FromStatement(
s1, &profile, &profile_label, &profile_unique_id,
&profile_date_modified));
sql::Statement s2(
connection.GetUniqueStatement(
"SELECT label, unique_id, name_on_card, type, card_number, "
"expiration_month, expiration_year, verification_code, "
"billing_address, shipping_address, card_number_encrypted, "
"verification_code_encrypted, date_modified, guid "
"FROM credit_cards"));
ASSERT_TRUE(s2.Step());
EXPECT_NO_FATAL_FAILURE(CreditCard31FromStatement(s2,
&credit_card,
&cc_label,
&cc_unique_id,
&cc_number_encrypted,
&cc_date_modified));
EXPECT_NE(profile_unique_id, cc_unique_id);
EXPECT_NE(profile.guid(), credit_card.guid());
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// Verify existence of columns we'll be changing.
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "guid"));
EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "unique_id"));
EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "guid"));
EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "unique_id"));
EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "type"));
EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "card_number"));
EXPECT_FALSE(connection.DoesColumnExist("credit_cards",
"verification_code"));
EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "billing_address"));
EXPECT_FALSE(connection.DoesColumnExist("credit_cards",
"shipping_address"));
EXPECT_FALSE(connection.DoesColumnExist("credit_cards",
"verification_code_encrypted"));
// Verify data in the database after the migration.
sql::Statement s1(
connection.GetUniqueStatement(
"SELECT guid, company_name, street_address, city, state, zipcode,"
" country_code, date_modified "
"FROM autofill_profiles"));
ASSERT_TRUE(s1.Step());
AutofillProfile profile_a;
int64 profile_date_modified_a = 0;
EXPECT_NO_FATAL_FAILURE(AutofillProfile33FromStatement(
s1, &profile_a, &profile_date_modified_a));
EXPECT_EQ(profile.guid(), profile_a.guid());
EXPECT_EQ(profile.GetRawInfo(autofill::COMPANY_NAME),
profile_a.GetRawInfo(autofill::COMPANY_NAME));
EXPECT_EQ(profile.GetRawInfo(autofill::ADDRESS_HOME_LINE1),
profile_a.GetRawInfo(autofill::ADDRESS_HOME_LINE1));
EXPECT_EQ(profile.GetRawInfo(autofill::ADDRESS_HOME_LINE2),
profile_a.GetRawInfo(autofill::ADDRESS_HOME_LINE2));
EXPECT_EQ(profile.GetRawInfo(autofill::ADDRESS_HOME_CITY),
profile_a.GetRawInfo(autofill::ADDRESS_HOME_CITY));
EXPECT_EQ(profile.GetRawInfo(autofill::ADDRESS_HOME_STATE),
profile_a.GetRawInfo(autofill::ADDRESS_HOME_STATE));
EXPECT_EQ(profile.GetRawInfo(autofill::ADDRESS_HOME_ZIP),
profile_a.GetRawInfo(autofill::ADDRESS_HOME_ZIP));
EXPECT_EQ(profile.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY),
profile_a.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY));
EXPECT_EQ(profile_date_modified, profile_date_modified_a);
sql::Statement s2(
connection.GetUniqueStatement(
"SELECT guid, name_on_card, expiration_month, "
"expiration_year, card_number_encrypted, date_modified "
"FROM credit_cards"));
ASSERT_TRUE(s2.Step());
CreditCard credit_card_a;
base::string16 cc_label_a;
std::string cc_number_encrypted_a;
int64 cc_date_modified_a = 0;
EXPECT_NO_FATAL_FAILURE(CreditCard32FromStatement(s2,
&credit_card_a,
&cc_number_encrypted_a,
&cc_date_modified_a));
EXPECT_EQ(credit_card, credit_card_a);
EXPECT_EQ(cc_label, cc_label_a);
EXPECT_EQ(cc_number_encrypted, cc_number_encrypted_a);
EXPECT_EQ(cc_date_modified, cc_date_modified_a);
}
}
// Factor |autofill_profiles| address information separately from name, email,
// and phone.
TEST_F(WebDatabaseMigrationTest, MigrateVersion32ToCurrent) {
// Initialize the database.
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_32.sql")));
// Verify pre-conditions. These are expectations for version 32 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Verify existence of columns we'll be changing.
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "guid"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "label"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "first_name"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "middle_name"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "last_name"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "email"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles",
"company_name"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles",
"address_line_1"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles",
"address_line_2"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "city"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "state"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "zipcode"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "country"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "phone"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "fax"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles",
"date_modified"));
EXPECT_FALSE(connection.DoesTableExist("autofill_profile_names"));
EXPECT_FALSE(connection.DoesTableExist("autofill_profile_emails"));
EXPECT_FALSE(connection.DoesTableExist("autofill_profile_phones"));
EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "label"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// Verify changes to columns.
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "guid"));
EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "label"));
EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "first_name"));
EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles",
"middle_name"));
EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "last_name"));
EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "email"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles",
"company_name"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles",
"street_address"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "city"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "state"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "zipcode"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles",
"country_code"));
EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "phone"));
EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "fax"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles",
"date_modified"));
// New "names" table.
EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_names", "guid"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_names",
"first_name"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_names",
"middle_name"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_names",
"last_name"));
// New "emails" table.
EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_emails", "guid"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_emails", "email"));
// New "phones" table.
EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_phones", "guid"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_phones",
"number"));
EXPECT_FALSE(connection.DoesColumnExist("credit_cards", "label"));
// Verify data in the database after the migration.
sql::Statement s1(
connection.GetUniqueStatement(
"SELECT guid, company_name, street_address, city, state, zipcode, "
" country_code, date_modified "
"FROM autofill_profiles"));
// John Doe.
ASSERT_TRUE(s1.Step());
EXPECT_EQ("00580526-FF81-EE2A-0546-1AC593A32E2F", s1.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("Doe Enterprises"), s1.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("1 Main St\n"
"Apt 1"),
s1.ColumnString16(2));
EXPECT_EQ(ASCIIToUTF16("Los Altos"), s1.ColumnString16(3));
EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(4));
EXPECT_EQ(ASCIIToUTF16("94022"), s1.ColumnString16(5));
EXPECT_EQ(ASCIIToUTF16("US"), s1.ColumnString16(6));
EXPECT_EQ(1297882100L, s1.ColumnInt64(7));
// John P. Doe.
// Gets merged during migration from 35 to 37 due to multi-valued fields.
// Dave Smith.
ASSERT_TRUE(s1.Step());
EXPECT_EQ("4C74A9D8-7EEE-423E-F9C2-E7FA70ED1396", s1.ColumnString(0));
EXPECT_EQ(base::string16(), s1.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("2 Main Street"), s1.ColumnString16(2));
EXPECT_EQ(ASCIIToUTF16("Los Altos"), s1.ColumnString16(3));
EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(4));
EXPECT_EQ(ASCIIToUTF16("94022"), s1.ColumnString16(5));
EXPECT_EQ(ASCIIToUTF16("US"), s1.ColumnString16(6));
EXPECT_EQ(1297882100L, s1.ColumnInt64(7));
// Dave Smith (Part 2).
ASSERT_TRUE(s1.Step());
EXPECT_EQ("722DF5C4-F74A-294A-46F0-31FFDED0D635", s1.ColumnString(0));
EXPECT_EQ(base::string16(), s1.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("2 Main St"), s1.ColumnString16(2));
EXPECT_EQ(ASCIIToUTF16("Los Altos"), s1.ColumnString16(3));
EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(4));
EXPECT_EQ(ASCIIToUTF16("94022"), s1.ColumnString16(5));
EXPECT_EQ(ASCIIToUTF16("US"), s1.ColumnString16(6));
EXPECT_EQ(1297882100L, s1.ColumnInt64(7));
// Alfred E Newman.
// Gets culled during migration from 35 to 36 due to incomplete address.
// 3 Main St.
ASSERT_TRUE(s1.Step());
EXPECT_EQ("9E5FE298-62C7-83DF-6293-381BC589183F", s1.ColumnString(0));
EXPECT_EQ(base::string16(), s1.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("3 Main St"), s1.ColumnString16(2));
EXPECT_EQ(ASCIIToUTF16("Los Altos"), s1.ColumnString16(3));
EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(4));
EXPECT_EQ(ASCIIToUTF16("94022"), s1.ColumnString16(5));
EXPECT_EQ(ASCIIToUTF16("US"), s1.ColumnString16(6));
EXPECT_EQ(1297882100L, s1.ColumnInt64(7));
// That should be all.
EXPECT_FALSE(s1.Step());
sql::Statement s2(
connection.GetUniqueStatement(
"SELECT guid, first_name, middle_name, last_name "
"FROM autofill_profile_names"));
// John Doe.
ASSERT_TRUE(s2.Step());
EXPECT_EQ("00580526-FF81-EE2A-0546-1AC593A32E2F", s2.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("John"), s2.ColumnString16(1));
EXPECT_EQ(base::string16(), s2.ColumnString16(2));
EXPECT_EQ(ASCIIToUTF16("Doe"), s2.ColumnString16(3));
// John P. Doe. Note same guid as above due to merging of multi-valued
// fields.
ASSERT_TRUE(s2.Step());
EXPECT_EQ("00580526-FF81-EE2A-0546-1AC593A32E2F", s2.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("John"), s2.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("P."), s2.ColumnString16(2));
EXPECT_EQ(ASCIIToUTF16("Doe"), s2.ColumnString16(3));
// Dave Smith.
ASSERT_TRUE(s2.Step());
EXPECT_EQ("4C74A9D8-7EEE-423E-F9C2-E7FA70ED1396", s2.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("Dave"), s2.ColumnString16(1));
EXPECT_EQ(base::string16(), s2.ColumnString16(2));
EXPECT_EQ(ASCIIToUTF16("Smith"), s2.ColumnString16(3));
// Dave Smith (Part 2).
ASSERT_TRUE(s2.Step());
EXPECT_EQ("722DF5C4-F74A-294A-46F0-31FFDED0D635", s2.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("Dave"), s2.ColumnString16(1));
EXPECT_EQ(base::string16(), s2.ColumnString16(2));
EXPECT_EQ(ASCIIToUTF16("Smith"), s2.ColumnString16(3));
// Alfred E Newman.
// Gets culled during migration from 35 to 36 due to incomplete address.
// 3 Main St.
ASSERT_TRUE(s2.Step());
EXPECT_EQ("9E5FE298-62C7-83DF-6293-381BC589183F", s2.ColumnString(0));
EXPECT_EQ(base::string16(), s2.ColumnString16(1));
EXPECT_EQ(base::string16(), s2.ColumnString16(2));
EXPECT_EQ(base::string16(), s2.ColumnString16(3));
// Should be all.
EXPECT_FALSE(s2.Step());
sql::Statement s3(
connection.GetUniqueStatement(
"SELECT guid, email "
"FROM autofill_profile_emails"));
// John Doe.
ASSERT_TRUE(s3.Step());
EXPECT_EQ("00580526-FF81-EE2A-0546-1AC593A32E2F", s3.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("john@doe.com"), s3.ColumnString16(1));
// John P. Doe.
// Gets culled during migration from 35 to 37 due to merging of John Doe and
// John P. Doe addresses.
// 2 Main Street.
ASSERT_TRUE(s3.Step());
EXPECT_EQ("4C74A9D8-7EEE-423E-F9C2-E7FA70ED1396", s3.ColumnString(0));
EXPECT_EQ(base::string16(), s3.ColumnString16(1));
// 2 Main St.
ASSERT_TRUE(s3.Step());
EXPECT_EQ("722DF5C4-F74A-294A-46F0-31FFDED0D635", s3.ColumnString(0));
EXPECT_EQ(base::string16(), s3.ColumnString16(1));
// Alfred E Newman.
// Gets culled during migration from 35 to 36 due to incomplete address.
// 3 Main St.
ASSERT_TRUE(s3.Step());
EXPECT_EQ("9E5FE298-62C7-83DF-6293-381BC589183F", s3.ColumnString(0));
EXPECT_EQ(base::string16(), s3.ColumnString16(1));
// Should be all.
EXPECT_FALSE(s3.Step());
sql::Statement s4(
connection.GetUniqueStatement(
"SELECT guid, number "
"FROM autofill_profile_phones"));
// John Doe phone.
ASSERT_TRUE(s4.Step());
EXPECT_EQ("00580526-FF81-EE2A-0546-1AC593A32E2F", s4.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("4151112222"), s4.ColumnString16(1));
// John Doe fax.
// Gets culled after fax type removed.
// John P. Doe phone.
// Gets culled during migration from 35 to 37 due to merging of John Doe and
// John P. Doe addresses.
// John P. Doe fax.
// Gets culled during migration from 35 to 37 due to merging of John Doe and
// John P. Doe addresses.
// 2 Main Street phone.
ASSERT_TRUE(s4.Step());
EXPECT_EQ("4C74A9D8-7EEE-423E-F9C2-E7FA70ED1396", s4.ColumnString(0));
EXPECT_EQ(base::string16(), s4.ColumnString16(1));
// 2 Main Street fax.
// Gets culled after fax type removed.
// 2 Main St phone.
ASSERT_TRUE(s4.Step());
EXPECT_EQ("722DF5C4-F74A-294A-46F0-31FFDED0D635", s4.ColumnString(0));
EXPECT_EQ(0, s4.ColumnInt(1)); // 0 means phone.
EXPECT_EQ(base::string16(), s4.ColumnString16(2));
// 2 Main St fax.
// Gets culled after fax type removed.
// Note no phone or fax for Alfred E Newman.
// 3 Main St phone.
ASSERT_TRUE(s4.Step());
EXPECT_EQ("9E5FE298-62C7-83DF-6293-381BC589183F", s4.ColumnString(0));
EXPECT_EQ(base::string16(), s4.ColumnString16(1));
// 2 Main St fax.
// Gets culled after fax type removed.
// Should be all.
EXPECT_FALSE(s4.Step());
}
}
// Adds a column for the autofill profile's country code.
TEST_F(WebDatabaseMigrationTest, MigrateVersion33ToCurrent) {
// Initialize the database.
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_33.sql")));
// Verify pre-conditions. These are expectations for version 33 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles",
"country_code"));
// Check that the country value is the one we expect.
sql::Statement s(
connection.GetUniqueStatement("SELECT country FROM autofill_profiles"));
ASSERT_TRUE(s.Step());
std::string country = s.ColumnString(0);
EXPECT_EQ("United States", country);
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
ASSERT_TRUE(connection.DoesColumnExist("autofill_profiles",
"country_code"));
// Check that the country code is properly converted.
sql::Statement s(connection.GetUniqueStatement(
"SELECT country_code FROM autofill_profiles"));
ASSERT_TRUE(s.Step());
std::string country_code = s.ColumnString(0);
EXPECT_EQ("US", country_code);
}
}
// Cleans up bad country code "UK" in favor of good country code "GB".
TEST_F(WebDatabaseMigrationTest, MigrateVersion34ToCurrent) {
// Initialize the database.
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_34.sql")));
// Verify pre-conditions. These are expectations for version 34 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles",
"country_code"));
// Check that the country_code value is the one we expect.
sql::Statement s(
connection.GetUniqueStatement("SELECT country_code "
"FROM autofill_profiles"));
ASSERT_TRUE(s.Step());
std::string country_code = s.ColumnString(0);
EXPECT_EQ("UK", country_code);
// Should have only one.
ASSERT_FALSE(s.Step());
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
ASSERT_TRUE(connection.DoesColumnExist("autofill_profiles",
"country_code"));
// Check that the country_code code is properly converted.
sql::Statement s(connection.GetUniqueStatement(
"SELECT country_code FROM autofill_profiles"));
ASSERT_TRUE(s.Step());
std::string country_code = s.ColumnString(0);
EXPECT_EQ("GB", country_code);
// Should have only one.
ASSERT_FALSE(s.Step());
}
}
// Cleans up invalid profiles based on more agressive merging. Filters out
// profiles that are subsets of other profiles, and profiles with invalid email,
// state, and incomplete address.
TEST_F(WebDatabaseMigrationTest, MigrateVersion35ToCurrent) {
// Initialize the database.
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_35.sql")));
// Verify pre-conditions. These are expectations for version 34 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
EXPECT_FALSE(connection.DoesTableExist("autofill_profiles_trash"));
ASSERT_TRUE(connection.DoesColumnExist("autofill_profiles", "guid"));
// Check that there are 6 profiles prior to merge.
sql::Statement s(
connection.GetUniqueStatement("SELECT guid FROM autofill_profiles"));
int i = 0;
while (s.Step())
++i;
EXPECT_EQ(6, i);
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
ASSERT_TRUE(connection.DoesTableExist("autofill_profiles_trash"));
ASSERT_TRUE(connection.DoesColumnExist("autofill_profiles_trash", "guid"));
ASSERT_TRUE(connection.DoesColumnExist("autofill_profiles", "guid"));
// Verify data in the database after the migration.
sql::Statement s1(
connection.GetUniqueStatement(
"SELECT guid, company_name, street_address, city, state, zipcode,"
" country_code, date_modified "
"FROM autofill_profiles"));
// John Doe.
ASSERT_TRUE(s1.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000001", s1.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("Acme Inc."), s1.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("1 Main Street\n"
"Apt 2"),
s1.ColumnString16(2));
EXPECT_EQ(ASCIIToUTF16("San Francisco"), s1.ColumnString16(3));
EXPECT_EQ(ASCIIToUTF16("CA"), s1.ColumnString16(4));
EXPECT_EQ(ASCIIToUTF16("94102"), s1.ColumnString16(5));
EXPECT_EQ(ASCIIToUTF16("US"), s1.ColumnString16(6));
EXPECT_EQ(1300131704, s1.ColumnInt64(7));
// That should be it.
ASSERT_FALSE(s1.Step());
// Check that there 5 trashed profile after the merge.
sql::Statement s2(
connection.GetUniqueStatement("SELECT guid "
"FROM autofill_profiles_trash"));
ASSERT_TRUE(s2.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000002", s2.ColumnString(0));
ASSERT_TRUE(s2.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000003", s2.ColumnString(0));
ASSERT_TRUE(s2.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000004", s2.ColumnString(0));
ASSERT_TRUE(s2.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000005", s2.ColumnString(0));
ASSERT_TRUE(s2.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000006", s2.ColumnString(0));
// That should be it.
ASSERT_FALSE(s2.Step());
}
}
// Tests that the |keywords| |last_modified| column gets added to the schema for
// a version 37 database.
TEST_F(WebDatabaseMigrationTest, MigrateVersion37ToCurrent) {
// This schema is taken from a build prior to the addition of the |keywords|
// |last_modified| column.
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_37.sql")));
// Verify pre-conditions. These are expectations for version 37 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Columns existing and not existing before current version.
ASSERT_TRUE(connection.DoesColumnExist("keywords", "id"));
ASSERT_FALSE(connection.DoesColumnExist("keywords", "last_modified"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// |keywords| |last_modified| column should have been added.
EXPECT_TRUE(connection.DoesColumnExist("keywords", "id"));
EXPECT_TRUE(connection.DoesColumnExist("keywords", "last_modified"));
}
}
// Tests that the |keywords| |sync_guid| column gets added to the schema for
// a version 38 database.
TEST_F(WebDatabaseMigrationTest, MigrateVersion38ToCurrent) {
// This schema is taken from a build prior to the addition of the |keywords|
// |sync_guid| column.
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_38.sql")));
// Verify pre-conditions. These are expectations for version 38 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Columns existing and not existing before current version.
ASSERT_TRUE(connection.DoesColumnExist("keywords", "id"));
ASSERT_FALSE(connection.DoesColumnExist("keywords", "sync_guid"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// |keywords| |sync_guid| column should have been added.
EXPECT_TRUE(connection.DoesColumnExist("keywords", "id"));
EXPECT_TRUE(connection.DoesColumnExist("keywords", "sync_guid"));
}
}
// Tests that no backup data is added to a version 39 database.
TEST_F(WebDatabaseMigrationTest, MigrateVersion39ToCurrent) {
// This schema is taken from a build prior to the addition of the default
// search provider backup field to the meta table.
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_39.sql")));
// Verify pre-conditions. These are expectations for version 39 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, 39, 39));
int64 default_search_provider_id = 0;
EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey,
&default_search_provider_id));
EXPECT_NO_FATAL_FAILURE(CheckNoBackupData(connection, &meta_table));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, kCurrentTestedVersionNumber,
kCurrentTestedVersionNumber));
int64 default_search_provider_id = 0;
EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey,
&default_search_provider_id));
EXPECT_NE(0, default_search_provider_id);
EXPECT_NO_FATAL_FAILURE(CheckNoBackupData(connection, &meta_table));
}
}
// Tests that the backup data is removed from the database.
TEST_F(WebDatabaseMigrationTest, MigrateVersion40ToCurrent) {
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_40.sql")));
// Verify pre-conditions. These are expectations for version 40 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, 40, 40));
int64 default_search_provider_id = 0;
EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey,
&default_search_provider_id));
EXPECT_NO_FATAL_FAILURE(CheckHasBackupData(&meta_table));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, kCurrentTestedVersionNumber,
kCurrentTestedVersionNumber));
int64 default_search_provider_id = 0;
EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey,
&default_search_provider_id));
EXPECT_NE(0, default_search_provider_id);
EXPECT_NO_FATAL_FAILURE(CheckNoBackupData(connection, &meta_table));
}
}
// Tests that the backup data is removed from the database.
TEST_F(WebDatabaseMigrationTest, MigrateVersion41ToCurrent) {
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_41.sql")));
// Verify pre-conditions. These are expectations for version 41 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, 41, 41));
int64 default_search_provider_id = 0;
EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey,
&default_search_provider_id));
EXPECT_NO_FATAL_FAILURE(CheckHasBackupData(&meta_table));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, kCurrentTestedVersionNumber,
kCurrentTestedVersionNumber));
int64 default_search_provider_id = 0;
EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey,
&default_search_provider_id));
EXPECT_NE(0, default_search_provider_id);
EXPECT_NO_FATAL_FAILURE(CheckNoBackupData(connection, &meta_table));
}
}
// Tests that the backup data is removed from the database.
TEST_F(WebDatabaseMigrationTest, MigrateVersion42ToCurrent) {
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_42.sql")));
// Verify pre-conditions. These are expectations for version 42 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, 42, 42));
int64 default_search_provider_id = 0;
EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey,
&default_search_provider_id));
EXPECT_NO_FATAL_FAILURE(CheckHasBackupData(&meta_table));
EXPECT_FALSE(connection.DoesTableExist("keywords_backup"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, kCurrentTestedVersionNumber,
kCurrentTestedVersionNumber));
int64 default_search_provider_id = 0;
EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey,
&default_search_provider_id));
EXPECT_NE(0, default_search_provider_id);
EXPECT_NO_FATAL_FAILURE(CheckNoBackupData(connection, &meta_table));
}
}
// Tests that the backup data is removed from the database.
TEST_F(WebDatabaseMigrationTest, MigrateVersion43ToCurrent) {
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_43.sql")));
int64 previous_default_search_provider_id;
// Verify pre-conditions. These are expectations for version 43 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, 43, 43));
int64 default_search_provider_id = 0;
EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey,
&default_search_provider_id));
EXPECT_NE(default_search_provider_id, 0);
previous_default_search_provider_id = default_search_provider_id;
EXPECT_NO_FATAL_FAILURE(CheckHasBackupData(&meta_table));
EXPECT_TRUE(connection.DoesTableExist("keywords_backup"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(
&connection,
kCurrentTestedVersionNumber,
kCurrentTestedVersionNumber));
int64 default_search_provider_id = 0;
EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey,
&default_search_provider_id));
// Default search provider ID should not change.
EXPECT_EQ(previous_default_search_provider_id, default_search_provider_id);
EXPECT_NO_FATAL_FAILURE(CheckNoBackupData(connection, &meta_table));
}
}
// Tests that the |autogenerate_keyword| and |logo_id| columns get removed from
// the keyword table schema for a version 45 database.
TEST_F(WebDatabaseMigrationTest, MigrateVersion44ToCurrent) {
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_44.sql")));
// Verify pre-conditions. These are expectations for version 44 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, 44, 44));
ASSERT_TRUE(connection.DoesColumnExist("keywords", "autogenerate_keyword"));
ASSERT_TRUE(connection.DoesColumnExist("keywords", "logo_id"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, kCurrentTestedVersionNumber,
kCurrentTestedVersionNumber));
// We should have removed this obsolete key.
std::string default_search_provider_backup;
EXPECT_FALSE(meta_table.GetValue("Default Search Provider Backup",
&default_search_provider_backup));
// Two columns should have been removed.
EXPECT_FALSE(connection.DoesColumnExist("keywords",
"autogenerate_keyword"));
EXPECT_FALSE(connection.DoesColumnExist("keywords", "logo_id"));
// Backup data should have been removed.
EXPECT_NO_FATAL_FAILURE(CheckNoBackupData(connection, &meta_table));
}
}
// Tests that the web_intents and web_intents_defaults tables are
// modified to include "scheme" columns.
TEST_F(WebDatabaseMigrationTest, MigrateVersion45ToCurrent) {
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_45.sql")));
// Verify pre-conditions. These are expectations for version 45 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, 45, 45));
ASSERT_FALSE(connection.DoesColumnExist("scheme", "web_intents"));
ASSERT_FALSE(connection.DoesColumnExist(
"scheme", "web_intents_defaults"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(
&connection,
kCurrentTestedVersionNumber,
kCurrentTestedVersionNumber));
// A new "scheme" column should have been added to each web_intents table.
EXPECT_TRUE(connection.DoesColumnExist("web_intents", "scheme"));
EXPECT_TRUE(connection.DoesColumnExist("web_intents_defaults", "scheme"));
// Verify existing user data was copied.
sql::Statement s1(
connection.GetUniqueStatement("SELECT * FROM web_intents"));
ASSERT_TRUE(s1.Step());
EXPECT_EQ("http://poodles.com/fuzzer", s1.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("fuzz"), s1.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("poodle/*"), s1.ColumnString16(2));
EXPECT_EQ(ASCIIToUTF16("Poodle Fuzzer"), s1.ColumnString16(3));
EXPECT_EQ(ASCIIToUTF16("window"), s1.ColumnString16(4));
EXPECT_EQ(ASCIIToUTF16(""), s1.ColumnString16(5));
ASSERT_FALSE(s1.Step());
// Now we want to verify existing user data was copied
sql::Statement s2(
connection.GetUniqueStatement("SELECT * FROM web_intents_defaults"));
ASSERT_TRUE(s2.Step());
EXPECT_EQ("fuzz", s2.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("poodle/*"), s2.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16(""), s2.ColumnString16(2));
EXPECT_EQ(0, s2.ColumnInt(3));
EXPECT_EQ(0, s2.ColumnInt(4));
EXPECT_EQ(ASCIIToUTF16("http://poodles.com/fuzzer"), s2.ColumnString16(5));
EXPECT_EQ(ASCIIToUTF16(""), s2.ColumnString16(6));
ASSERT_FALSE(s2.Step());
// finally ensure the migration code cleaned up after itself
EXPECT_FALSE(connection.DoesTableExist("old_web_intents"));
EXPECT_FALSE(connection.DoesTableExist("old_web_intents_defaults"));
}
}
// Tests that the web_intents and web_intents_defaults tables are
// modified to include "scheme" columns.
TEST_F(WebDatabaseMigrationTest, MigrateVersion45InvalidToCurrent) {
ASSERT_NO_FATAL_FAILURE(
LoadDatabase(FILE_PATH_LITERAL("version_45_invalid.sql")));
// Verify pre-conditions. These are expectations for version 45 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, 45, 45));
ASSERT_FALSE(connection.DoesColumnExist("scheme", "web_intents"));
ASSERT_FALSE(connection.DoesColumnExist(
"scheme", "web_intents_defaults"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(
&connection,
kCurrentTestedVersionNumber,
kCurrentTestedVersionNumber));
// A new "scheme" column should have been added to each web_intents table.
EXPECT_TRUE(connection.DoesColumnExist("web_intents", "scheme"));
EXPECT_TRUE(connection.DoesColumnExist("web_intents_defaults", "scheme"));
// Verify existing user data was copied.
sql::Statement s1(
connection.GetUniqueStatement("SELECT * FROM web_intents"));
ASSERT_FALSE(s1.Step()); // Basically should be empty at this point.
// Now we want to verify existing user data was copied
sql::Statement s2(
connection.GetUniqueStatement("SELECT * FROM web_intents_defaults"));
// We were able to create the new tables, but unable to copy any data
// Given the initial bad state of the tables.
ASSERT_FALSE(s2.Step());
// Finally ensure the migration code cleaned up after itself.
EXPECT_FALSE(connection.DoesTableExist("old_web_intents"));
EXPECT_FALSE(connection.DoesTableExist("old_web_intents_defaults"));
}
}
// Check that current version is forced to compatible version before migration,
// if the former is smaller.
TEST_F(WebDatabaseMigrationTest, MigrateVersion45CompatibleToCurrent) {
ASSERT_NO_FATAL_FAILURE(
LoadDatabase(FILE_PATH_LITERAL("version_45_compatible.sql")));
// Verify pre-conditions. These are expectations for version 45 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
sql::MetaTable meta_table;
// Database is actually version 45 but the version field states 40.
ASSERT_TRUE(meta_table.Init(&connection, 40, 45));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
EXPECT_LE(45, VersionFromConnection(&connection));
}
}
// Tests that the |alternate_urls| column is added to the keyword table schema
// for a version 47 database.
TEST_F(WebDatabaseMigrationTest, MigrateVersion46ToCurrent) {
ASSERT_NO_FATAL_FAILURE(
LoadDatabase(FILE_PATH_LITERAL("version_46.sql")));
// Verify pre-conditions. These are expectations for version 46 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, 46, 46));
ASSERT_FALSE(connection.DoesColumnExist("keywords", "alternate_urls"));
ASSERT_FALSE(connection.DoesColumnExist("keywords_backup",
"alternate_urls"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// A new column should have been created.
EXPECT_TRUE(connection.DoesColumnExist("keywords", "alternate_urls"));
}
}
// Tests that the backup data is removed from the database.
TEST_F(WebDatabaseMigrationTest, MigrateVersion47ToCurrent) {
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_47.sql")));
// Verify pre-conditions. These are expectations for version 47 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, 47, 47));
int64 default_search_provider_id = 0;
EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey,
&default_search_provider_id));
EXPECT_NE(0, default_search_provider_id);
EXPECT_NO_FATAL_FAILURE(CheckHasBackupData(&meta_table));
EXPECT_TRUE(connection.DoesTableExist("keywords_backup"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, kCurrentTestedVersionNumber,
kCurrentTestedVersionNumber));
int64 default_search_provider_id = 0;
EXPECT_TRUE(meta_table.GetValue(KeywordTable::kDefaultSearchProviderKey,
&default_search_provider_id));
EXPECT_NE(0, default_search_provider_id);
EXPECT_NO_FATAL_FAILURE(CheckNoBackupData(connection, &meta_table));
}
}
// Tests that the |search_terms_replacement_key| column is added to the keyword
// table schema for a version 49 database.
TEST_F(WebDatabaseMigrationTest, MigrateVersion48ToCurrent) {
ASSERT_NO_FATAL_FAILURE(
LoadDatabase(FILE_PATH_LITERAL("version_48.sql")));
// Verify pre-conditions. These are expectations for version 48 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, 48, 48));
ASSERT_FALSE(connection.DoesColumnExist("keywords",
"search_terms_replacement_key"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// A new column should have been created.
EXPECT_TRUE(connection.DoesColumnExist("keywords",
"search_terms_replacement_key"));
}
}
// Tests that the |origin| column is added to the autofill_profiles and
// credit_cards table schemas for a version 50 database.
TEST_F(WebDatabaseMigrationTest, MigrateVersion49ToCurrent) {
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_49.sql")));
// Verify pre-conditions. These are expectations for version 49 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_FALSE(connection.DoesColumnExist("autofill_profiles", "origin"));
ASSERT_FALSE(connection.DoesColumnExist("credit_cards", "origin"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// A new column should have been created in both tables.
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "origin"));
EXPECT_TRUE(connection.DoesColumnExist("credit_cards", "origin"));
}
}
// Tests that the columns |image_url|, |search_url_post_params|,
// |suggest_url_post_params|, |instant_url_post_params|, and
// |image_url_post_params| are added to the keyword table schema for a version
// 50 database.
TEST_F(WebDatabaseMigrationTest, MigrateVersion50ToCurrent) {
ASSERT_NO_FATAL_FAILURE(
LoadDatabase(FILE_PATH_LITERAL("version_50.sql")));
// Verify pre-conditions. These are expectations for version 50 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, 50, 50));
ASSERT_FALSE(connection.DoesColumnExist("keywords", "image_url"));
ASSERT_FALSE(connection.DoesColumnExist("keywords",
"search_url_post_params"));
ASSERT_FALSE(connection.DoesColumnExist("keywords",
"suggest_url_post_params"));
ASSERT_FALSE(connection.DoesColumnExist("keywords",
"instant_url_post_params"));
ASSERT_FALSE(connection.DoesColumnExist("keywords",
"image_url_post_params"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// New columns should have been created.
EXPECT_TRUE(connection.DoesColumnExist("keywords", "image_url"));
EXPECT_TRUE(connection.DoesColumnExist("keywords",
"search_url_post_params"));
EXPECT_TRUE(connection.DoesColumnExist("keywords",
"suggest_url_post_params"));
EXPECT_TRUE(connection.DoesColumnExist("keywords",
"instant_url_post_params"));
EXPECT_TRUE(connection.DoesColumnExist("keywords",
"image_url_post_params"));
}
}
// Tests that the column |new_tab_url| is added to the keyword table schema for
// a version 52 database.
TEST_F(WebDatabaseMigrationTest, MigrateVersion52ToCurrent) {
ASSERT_NO_FATAL_FAILURE(
LoadDatabase(FILE_PATH_LITERAL("version_52.sql")));
// Verify pre-conditions. These are expectations for version 52 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
sql::MetaTable meta_table;
ASSERT_TRUE(meta_table.Init(&connection, 52, 52));
ASSERT_FALSE(connection.DoesColumnExist("keywords", "new_tab_url"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// New columns should have been created.
EXPECT_TRUE(connection.DoesColumnExist("keywords", "new_tab_url"));
}
}
// Tests that for a version 54 database,
// (a) The street_address, dependent_locality, and sorting_code columns are
// added to the autofill_profiles table schema.
// (b) The address_line1, address_line2, and country columns are dropped from
// the autofill_profiles table schema.
// (c) The type column is dropped from the autofill_profile_phones schema.
TEST_F(WebDatabaseMigrationTest, MigrateVersion53ToCurrent) {
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_53.sql")));
// Verify pre-conditions. These are expectations for version 53 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
EXPECT_TRUE(
connection.DoesColumnExist("autofill_profiles", "address_line_1"));
EXPECT_TRUE(
connection.DoesColumnExist("autofill_profiles", "address_line_2"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profiles", "country"));
EXPECT_FALSE(
connection.DoesColumnExist("autofill_profiles", "street_address"));
EXPECT_FALSE(
connection.DoesColumnExist("autofill_profiles", "dependent_locality"));
EXPECT_FALSE(
connection.DoesColumnExist("autofill_profiles", "sorting_code"));
EXPECT_TRUE(connection.DoesColumnExist("autofill_profile_phones", "type"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// Columns should have been added and removed appropriately.
EXPECT_FALSE(
connection.DoesColumnExist("autofill_profiles", "address_line1"));
EXPECT_FALSE(
connection.DoesColumnExist("autofill_profiles", "address_line2"));
EXPECT_FALSE(connection.DoesColumnExist("autofill_profiles", "country"));
EXPECT_TRUE(
connection.DoesColumnExist("autofill_profiles", "street_address"));
EXPECT_TRUE(
connection.DoesColumnExist("autofill_profiles", "dependent_locality"));
EXPECT_TRUE(
connection.DoesColumnExist("autofill_profiles", "sorting_code"));
EXPECT_FALSE(connection.DoesColumnExist("autofill_profile_phones", "type"));
// Data should have been preserved.
sql::Statement s_profiles(
connection.GetUniqueStatement(
"SELECT guid, company_name, street_address, dependent_locality,"
" city, state, zipcode, sorting_code, country_code, date_modified,"
" origin "
"FROM autofill_profiles"));
// Address lines 1 and 2.
ASSERT_TRUE(s_profiles.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000001",
s_profiles.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("Google, Inc."), s_profiles.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("1950 Charleston Rd.\n"
"(2nd floor)"),
s_profiles.ColumnString16(2));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(3));
EXPECT_EQ(ASCIIToUTF16("Mountain View"), s_profiles.ColumnString16(4));
EXPECT_EQ(ASCIIToUTF16("CA"), s_profiles.ColumnString16(5));
EXPECT_EQ(ASCIIToUTF16("94043"), s_profiles.ColumnString16(6));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(7));
EXPECT_EQ(ASCIIToUTF16("US"), s_profiles.ColumnString16(8));
EXPECT_EQ(1386046731, s_profiles.ColumnInt(9));
EXPECT_EQ(ASCIIToUTF16("Chrome settings"), s_profiles.ColumnString16(10));
// Only address line 1.
ASSERT_TRUE(s_profiles.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000002",
s_profiles.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("Google!"), s_profiles.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("1600 Amphitheatre Pkwy."),
s_profiles.ColumnString16(2));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(3));
EXPECT_EQ(ASCIIToUTF16("Mtn. View"), s_profiles.ColumnString16(4));
EXPECT_EQ(ASCIIToUTF16("California"), s_profiles.ColumnString16(5));
EXPECT_EQ(ASCIIToUTF16("94043-1234"), s_profiles.ColumnString16(6));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(7));
EXPECT_EQ(ASCIIToUTF16("US"), s_profiles.ColumnString16(8));
EXPECT_EQ(1386046800, s_profiles.ColumnInt(9));
EXPECT_EQ(ASCIIToUTF16("Chrome settings"), s_profiles.ColumnString16(10));
// Only address line 2.
ASSERT_TRUE(s_profiles.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000003",
s_profiles.ColumnString(0));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("\nOnly line 2???"), s_profiles.ColumnString16(2));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(3));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(4));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(5));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(6));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(7));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(8));
EXPECT_EQ(1386046834, s_profiles.ColumnInt(9));
EXPECT_EQ(ASCIIToUTF16("Chrome settings"), s_profiles.ColumnString16(10));
// No address lines.
ASSERT_TRUE(s_profiles.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000004",
s_profiles.ColumnString(0));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(1));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(2));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(3));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(4));
EXPECT_EQ(ASCIIToUTF16("Texas"), s_profiles.ColumnString16(5));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(6));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(7));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(8));
EXPECT_EQ(1386046847, s_profiles.ColumnInt(9));
EXPECT_EQ(ASCIIToUTF16("Chrome settings"), s_profiles.ColumnString16(10));
// That should be it.
EXPECT_FALSE(s_profiles.Step());
// Verify the phone number data as well.
sql::Statement s_phones(
connection.GetUniqueStatement(
"SELECT guid, number FROM autofill_profile_phones"));
ASSERT_TRUE(s_phones.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000001", s_phones.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("1.800.555.1234"), s_phones.ColumnString16(1));
ASSERT_TRUE(s_phones.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000001", s_phones.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("+1 (800) 555-4321"), s_phones.ColumnString16(1));
ASSERT_TRUE(s_phones.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000002", s_phones.ColumnString(0));
EXPECT_EQ(base::string16(), s_phones.ColumnString16(1));
ASSERT_TRUE(s_phones.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000003", s_phones.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("6505557890"), s_phones.ColumnString16(1));
ASSERT_TRUE(s_phones.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000004", s_phones.ColumnString(0));
EXPECT_EQ(base::string16(), s_phones.ColumnString16(1));
EXPECT_FALSE(s_phones.Step());
}
}
// Tests that migrating from version 54 to version 55 drops the autofill_dates
// table, and merges the appropriate dates into the autofill table.
TEST_F(WebDatabaseMigrationTest, MigrateVersion54ToCurrent) {
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_54.sql")));
// Verify pre-conditions. These are expectations for version 54 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
EXPECT_TRUE(connection.DoesTableExist("autofill_dates"));
EXPECT_FALSE(connection.DoesColumnExist("autofill", "date_created"));
EXPECT_FALSE(connection.DoesColumnExist("autofill", "date_last_used"));
// Verify the incoming data.
sql::Statement s_autofill(connection.GetUniqueStatement(
"SELECT name, value, value_lower, pair_id, count FROM autofill"));
sql::Statement s_dates(connection.GetUniqueStatement(
"SELECT pair_id, date_created FROM autofill_dates"));
// An entry with one timestamp.
ASSERT_TRUE(s_autofill.Step());
EXPECT_EQ(ASCIIToUTF16("Name"), s_autofill.ColumnString16(0));
EXPECT_EQ(ASCIIToUTF16("John Doe"), s_autofill.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("john doe"), s_autofill.ColumnString16(2));
EXPECT_EQ(10, s_autofill.ColumnInt(3));
EXPECT_EQ(1, s_autofill.ColumnInt(4));
ASSERT_TRUE(s_dates.Step());
EXPECT_EQ(10, s_dates.ColumnInt(0));
EXPECT_EQ(1384299100, s_dates.ColumnInt64(1));
// Another entry with one timestamp, differing from the previous one in case
// only.
ASSERT_TRUE(s_autofill.Step());
EXPECT_EQ(ASCIIToUTF16("Name"), s_autofill.ColumnString16(0));
EXPECT_EQ(ASCIIToUTF16("john doe"), s_autofill.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("john doe"), s_autofill.ColumnString16(2));
EXPECT_EQ(11, s_autofill.ColumnInt(3));
EXPECT_EQ(1, s_autofill.ColumnInt(4));
ASSERT_TRUE(s_dates.Step());
EXPECT_EQ(11, s_dates.ColumnInt(0));
EXPECT_EQ(1384299200, s_dates.ColumnInt64(1));
// An entry with two timestamps (with count > 2; this is realistic).
ASSERT_TRUE(s_autofill.Step());
EXPECT_EQ(ASCIIToUTF16("Email"), s_autofill.ColumnString16(0));
EXPECT_EQ(ASCIIToUTF16("jane@example.com"), s_autofill.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("jane@example.com"), s_autofill.ColumnString16(2));
EXPECT_EQ(20, s_autofill.ColumnInt(3));
EXPECT_EQ(3, s_autofill.ColumnInt(4));
ASSERT_TRUE(s_dates.Step());
EXPECT_EQ(20, s_dates.ColumnInt(0));
EXPECT_EQ(1384299300, s_dates.ColumnInt64(1));
ASSERT_TRUE(s_dates.Step());
EXPECT_EQ(20, s_dates.ColumnInt(0));
EXPECT_EQ(1384299301, s_dates.ColumnInt64(1));
// An entry with more than two timestamps, which are stored out of order.
ASSERT_TRUE(s_autofill.Step());
EXPECT_EQ(ASCIIToUTF16("Email"), s_autofill.ColumnString16(0));
EXPECT_EQ(ASCIIToUTF16("jane.doe@example.org"),
s_autofill.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("jane.doe@example.org"),
s_autofill.ColumnString16(2));
EXPECT_EQ(21, s_autofill.ColumnInt(3));
EXPECT_EQ(4, s_autofill.ColumnInt(4));
ASSERT_TRUE(s_dates.Step());
EXPECT_EQ(21, s_dates.ColumnInt(0));
EXPECT_EQ(1384299401, s_dates.ColumnInt64(1));
ASSERT_TRUE(s_dates.Step());
EXPECT_EQ(21, s_dates.ColumnInt(0));
EXPECT_EQ(1384299400, s_dates.ColumnInt64(1));
ASSERT_TRUE(s_dates.Step());
EXPECT_EQ(21, s_dates.ColumnInt(0));
EXPECT_EQ(1384299403, s_dates.ColumnInt64(1));
ASSERT_TRUE(s_dates.Step());
EXPECT_EQ(21, s_dates.ColumnInt(0));
EXPECT_EQ(1384299402, s_dates.ColumnInt64(1));
// No more entries expected.
ASSERT_FALSE(s_autofill.Step());
ASSERT_FALSE(s_dates.Step());
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// The autofill_dates table should have been dropped, and its columns should
// have been migrated to the autofill table.
EXPECT_FALSE(connection.DoesTableExist("autofill_dates"));
EXPECT_TRUE(connection.DoesColumnExist("autofill", "date_created"));
EXPECT_TRUE(connection.DoesColumnExist("autofill", "date_last_used"));
// Data should have been preserved. Note that it appears out of order
// relative to the previous table, as it's been alphabetized. That's ok.
sql::Statement s(
connection.GetUniqueStatement(
"SELECT name, value, value_lower, date_created, date_last_used,"
" count "
"FROM autofill "
"ORDER BY name, value ASC"));
// "jane.doe@example.org": Timestamps should be parsed correctly, and only
// the first and last should be kept.
ASSERT_TRUE(s.Step());
EXPECT_EQ(ASCIIToUTF16("Email"), s.ColumnString16(0));
EXPECT_EQ(ASCIIToUTF16("jane.doe@example.org"), s.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("jane.doe@example.org"), s.ColumnString16(2));
EXPECT_EQ(1384299400, s.ColumnInt64(3));
EXPECT_EQ(1384299403, s.ColumnInt64(4));
EXPECT_EQ(4, s.ColumnInt(5));
// "jane@example.com": Timestamps should be parsed correctly.
ASSERT_TRUE(s.Step());
EXPECT_EQ(ASCIIToUTF16("Email"), s.ColumnString16(0));
EXPECT_EQ(ASCIIToUTF16("jane@example.com"), s.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("jane@example.com"), s.ColumnString16(2));
EXPECT_EQ(1384299300, s.ColumnInt64(3));
EXPECT_EQ(1384299301, s.ColumnInt64(4));
EXPECT_EQ(3, s.ColumnInt(5));
// "John Doe": The single timestamp should be assigned as both the creation
// and the last use timestamp.
ASSERT_TRUE(s.Step());
EXPECT_EQ(ASCIIToUTF16("Name"), s.ColumnString16(0));
EXPECT_EQ(ASCIIToUTF16("John Doe"), s.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("john doe"), s.ColumnString16(2));
EXPECT_EQ(1384299100, s.ColumnInt64(3));
EXPECT_EQ(1384299100, s.ColumnInt64(4));
EXPECT_EQ(1, s.ColumnInt(5));
// "john doe": Should not be merged with "John Doe" (case-sensitivity).
ASSERT_TRUE(s.Step());
EXPECT_EQ(ASCIIToUTF16("Name"), s.ColumnString16(0));
EXPECT_EQ(ASCIIToUTF16("john doe"), s.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("john doe"), s.ColumnString16(2));
EXPECT_EQ(1384299200, s.ColumnInt64(3));
EXPECT_EQ(1384299200, s.ColumnInt64(4));
EXPECT_EQ(1, s.ColumnInt(5));
// No more entries expected.
ASSERT_FALSE(s.Step());
}
}
// Tests that migrating from version 55 to version 56 adds the language_code
// column to autofill_profiles table.
TEST_F(WebDatabaseMigrationTest, MigrateVersion55ToCurrent) {
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_55.sql")));
// Verify pre-conditions. These are expectations for version 55 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
EXPECT_FALSE(
connection.DoesColumnExist("autofill_profiles", "language_code"));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// The language_code column should have been added to autofill_profiles
// table.
EXPECT_TRUE(
connection.DoesColumnExist("autofill_profiles", "language_code"));
// Data should have been preserved. Language code should have been set to
// empty string.
sql::Statement s_profiles(
connection.GetUniqueStatement(
"SELECT guid, company_name, street_address, dependent_locality,"
" city, state, zipcode, sorting_code, country_code, date_modified,"
" origin, language_code "
"FROM autofill_profiles"));
ASSERT_TRUE(s_profiles.Step());
EXPECT_EQ("00000000-0000-0000-0000-000000000001",
s_profiles.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("Google Inc"), s_profiles.ColumnString16(1));
EXPECT_EQ(ASCIIToUTF16("340 Main St"),
s_profiles.ColumnString16(2));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(3));
EXPECT_EQ(ASCIIToUTF16("Los Angeles"), s_profiles.ColumnString16(4));
EXPECT_EQ(ASCIIToUTF16("CA"), s_profiles.ColumnString16(5));
EXPECT_EQ(ASCIIToUTF16("90291"), s_profiles.ColumnString16(6));
EXPECT_EQ(base::string16(), s_profiles.ColumnString16(7));
EXPECT_EQ(ASCIIToUTF16("US"), s_profiles.ColumnString16(8));
EXPECT_EQ(1395948829, s_profiles.ColumnInt(9));
EXPECT_EQ(ASCIIToUTF16("Chrome settings"), s_profiles.ColumnString16(10));
EXPECT_EQ(std::string(), s_profiles.ColumnString(11));
// No more entries expected.
ASSERT_FALSE(s_profiles.Step());
}
}
// Tests that migrating from version 56 to version 57 adds the full_name
// column to autofill_profile_names table.
TEST_F(WebDatabaseMigrationTest, MigrateVersion56ToCurrent) {
ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_56.sql")));
// Verify pre-conditions. These are expectations for version 56 of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
EXPECT_FALSE(
connection.DoesColumnExist("autofill_profile_names", "full_name"));
// Verify the starting data.
sql::Statement s_names(
connection.GetUniqueStatement(
"SELECT guid, first_name, middle_name, last_name "
"FROM autofill_profile_names"));
ASSERT_TRUE(s_names.Step());
EXPECT_EQ("B41FE6E0-B13E-2A2A-BF0B-29FCE2C3ADBD", s_names.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("Jon"), s_names.ColumnString16(1));
EXPECT_EQ(base::string16(), s_names.ColumnString16(2));
EXPECT_EQ(ASCIIToUTF16("Smith"), s_names.ColumnString16(3));
}
DoMigration();
// Verify post-conditions. These are expectations for current version of the
// database.
{
sql::Connection connection;
ASSERT_TRUE(connection.Open(GetDatabasePath()));
ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
// Check version.
EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
// The full_name column should have been added to autofill_profile_names
// table.
EXPECT_TRUE(
connection.DoesColumnExist("autofill_profile_names", "full_name"));
// Data should have been preserved. Full name should have been set to the
// empty string.
sql::Statement s_names(
connection.GetUniqueStatement(
"SELECT guid, first_name, middle_name, last_name, full_name "
"FROM autofill_profile_names"));
ASSERT_TRUE(s_names.Step());
EXPECT_EQ("B41FE6E0-B13E-2A2A-BF0B-29FCE2C3ADBD", s_names.ColumnString(0));
EXPECT_EQ(ASCIIToUTF16("Jon"), s_names.ColumnString16(1));
EXPECT_EQ(base::string16(), s_names.ColumnString16(2));
EXPECT_EQ(ASCIIToUTF16("Smith"), s_names.ColumnString16(3));
EXPECT_EQ(base::string16(), s_names.ColumnString16(4));
// No more entries expected.
ASSERT_FALSE(s_names.Step());
}
}