| // 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 <vector> |
| |
| #include "base/file_util.h" |
| #include "base/path_service.h" |
| #include "base/scoped_temp_dir.h" |
| #include "base/stl_util.h" |
| #include "base/string_number_conversions.h" |
| #include "base/time.h" |
| #include "base/utf_string_conversions.h" |
| #include "chrome/common/chrome_paths.h" |
| #include "chrome/browser/search_engines/template_url.h" |
| #include "chrome/browser/webdata/keyword_table.h" |
| #include "chrome/browser/webdata/web_database.h" |
| #include "sql/statement.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using base::Time; |
| using base::TimeDelta; |
| |
| class KeywordTableTest : public testing::Test { |
| public: |
| KeywordTableTest() {} |
| virtual ~KeywordTableTest() {} |
| |
| protected: |
| virtual void SetUp() { |
| ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| file_ = temp_dir_.path().AppendASCII("TestWebDatabase"); |
| } |
| |
| FilePath file_; |
| ScopedTempDir temp_dir_; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(KeywordTableTest); |
| }; |
| |
| |
| TEST_F(KeywordTableTest, Keywords) { |
| WebDatabase db; |
| ASSERT_EQ(sql::INIT_OK, db.Init(file_)); |
| KeywordTable* keyword_table = db.GetKeywordTable(); |
| |
| TemplateURLData keyword; |
| keyword.short_name = ASCIIToUTF16("short_name"); |
| keyword.SetKeyword(ASCIIToUTF16("keyword")); |
| keyword.SetURL("http://url/"); |
| keyword.instant_url = "http://instant/"; |
| keyword.favicon_url = GURL("http://favicon.url/"); |
| keyword.originating_url = GURL("http://google.com/"); |
| keyword.show_in_default_list = true; |
| keyword.safe_for_autoreplace = true; |
| keyword.input_encodings.push_back("UTF-8"); |
| keyword.input_encodings.push_back("UTF-16"); |
| keyword.id = 1; |
| keyword.date_created = Time::Now(); |
| keyword.last_modified = keyword.date_created + TimeDelta::FromSeconds(10); |
| keyword.created_by_policy = true; |
| keyword.usage_count = 32; |
| keyword.prepopulate_id = 10; |
| EXPECT_TRUE(keyword_table->AddKeyword(keyword)); |
| |
| KeywordTable::Keywords keywords; |
| EXPECT_TRUE(keyword_table->GetKeywords(&keywords)); |
| EXPECT_EQ(1U, keywords.size()); |
| const TemplateURLData& restored_keyword = keywords.front(); |
| |
| EXPECT_EQ(keyword.short_name, restored_keyword.short_name); |
| EXPECT_EQ(keyword.keyword(), restored_keyword.keyword()); |
| EXPECT_EQ(keyword.url(), restored_keyword.url()); |
| EXPECT_EQ(keyword.suggestions_url, restored_keyword.suggestions_url); |
| EXPECT_EQ(keyword.instant_url, restored_keyword.instant_url); |
| EXPECT_EQ(keyword.favicon_url, restored_keyword.favicon_url); |
| EXPECT_EQ(keyword.originating_url, restored_keyword.originating_url); |
| EXPECT_EQ(keyword.show_in_default_list, |
| restored_keyword.show_in_default_list); |
| EXPECT_EQ(keyword.safe_for_autoreplace, |
| restored_keyword.safe_for_autoreplace); |
| EXPECT_EQ(keyword.input_encodings, restored_keyword.input_encodings); |
| EXPECT_EQ(keyword.id, restored_keyword.id); |
| // The database stores time only at the resolution of a second. |
| EXPECT_EQ(keyword.date_created.ToTimeT(), |
| restored_keyword.date_created.ToTimeT()); |
| EXPECT_EQ(keyword.last_modified.ToTimeT(), |
| restored_keyword.last_modified.ToTimeT()); |
| EXPECT_EQ(keyword.created_by_policy, restored_keyword.created_by_policy); |
| EXPECT_EQ(keyword.usage_count, restored_keyword.usage_count); |
| EXPECT_EQ(keyword.prepopulate_id, restored_keyword.prepopulate_id); |
| |
| EXPECT_TRUE(keyword_table->RemoveKeyword(restored_keyword.id)); |
| |
| KeywordTable::Keywords empty_keywords; |
| EXPECT_TRUE(keyword_table->GetKeywords(&empty_keywords)); |
| EXPECT_EQ(0U, empty_keywords.size()); |
| } |
| |
| TEST_F(KeywordTableTest, KeywordMisc) { |
| WebDatabase db; |
| ASSERT_EQ(sql::INIT_OK, db.Init(file_)); |
| KeywordTable* keyword_table = db.GetKeywordTable(); |
| |
| EXPECT_EQ(kInvalidTemplateURLID, keyword_table->GetDefaultSearchProviderID()); |
| EXPECT_EQ(0, keyword_table->GetBuiltinKeywordVersion()); |
| |
| TemplateURLData keyword; |
| keyword.short_name = ASCIIToUTF16("short_name"); |
| keyword.SetKeyword(ASCIIToUTF16("keyword")); |
| keyword.SetURL("http://url/"); |
| keyword.instant_url = "http://instant/"; |
| keyword.favicon_url = GURL("http://favicon.url/"); |
| keyword.originating_url = GURL("http://google.com/"); |
| keyword.show_in_default_list = true; |
| keyword.safe_for_autoreplace = true; |
| keyword.input_encodings.push_back("UTF-8"); |
| keyword.input_encodings.push_back("UTF-16"); |
| keyword.id = 10; |
| keyword.date_created = Time::Now(); |
| keyword.last_modified = keyword.date_created + TimeDelta::FromSeconds(10); |
| keyword.created_by_policy = true; |
| keyword.usage_count = 32; |
| keyword.prepopulate_id = 10; |
| EXPECT_TRUE(keyword_table->AddKeyword(keyword)); |
| |
| EXPECT_TRUE(keyword_table->SetDefaultSearchProviderID(10)); |
| EXPECT_TRUE(keyword_table->SetBuiltinKeywordVersion(11)); |
| |
| EXPECT_EQ(10, keyword_table->GetDefaultSearchProviderID()); |
| EXPECT_EQ(11, keyword_table->GetBuiltinKeywordVersion()); |
| } |
| |
| TEST_F(KeywordTableTest, DefaultSearchProviderBackup) { |
| // TODO(ivankr): suppress keyword_table.cc ERROR logs. |
| WebDatabase db; |
| ASSERT_EQ(sql::INIT_OK, db.Init(file_)); |
| KeywordTable* keyword_table = db.GetKeywordTable(); |
| |
| EXPECT_EQ(kInvalidTemplateURLID, keyword_table->GetDefaultSearchProviderID()); |
| |
| TemplateURLData keyword; |
| keyword.short_name = ASCIIToUTF16("short_name"); |
| keyword.SetKeyword(ASCIIToUTF16("keyword")); |
| keyword.SetURL("http://url/"); |
| keyword.suggestions_url = "url2"; |
| keyword.favicon_url = GURL("http://favicon.url/"); |
| keyword.show_in_default_list = true; |
| keyword.safe_for_autoreplace = true; |
| keyword.id = 1; |
| EXPECT_TRUE(keyword_table->AddKeyword(keyword)); |
| |
| EXPECT_TRUE(keyword_table->SetDefaultSearchProviderID(1)); |
| EXPECT_TRUE(keyword_table->IsBackupSignatureValid( |
| WebDatabase::kCurrentVersionNumber)); |
| EXPECT_EQ(1, keyword_table->GetDefaultSearchProviderID()); |
| |
| TemplateURLData backup; |
| EXPECT_TRUE(keyword_table->GetDefaultSearchProviderBackup(&backup)); |
| // Backup URL should have an invalid ID. |
| EXPECT_EQ(kInvalidTemplateURLID, backup.id); |
| EXPECT_EQ(keyword.short_name, backup.short_name); |
| EXPECT_EQ(keyword.keyword(), backup.keyword()); |
| EXPECT_EQ(keyword.url(), backup.url()); |
| EXPECT_EQ(keyword.favicon_url, backup.favicon_url); |
| EXPECT_EQ(keyword.suggestions_url, backup.suggestions_url); |
| EXPECT_EQ(keyword.show_in_default_list, backup.show_in_default_list); |
| EXPECT_EQ(keyword.safe_for_autoreplace, backup.safe_for_autoreplace); |
| EXPECT_FALSE(keyword_table->DidDefaultSearchProviderChange()); |
| |
| // Change the actual setting. |
| EXPECT_TRUE(keyword_table->meta_table_->SetValue( |
| KeywordTable::kDefaultSearchProviderKey, 2)); |
| EXPECT_TRUE(keyword_table->IsBackupSignatureValid( |
| WebDatabase::kCurrentVersionNumber)); |
| EXPECT_EQ(2, keyword_table->GetDefaultSearchProviderID()); |
| |
| EXPECT_TRUE(keyword_table->GetDefaultSearchProviderBackup(&backup)); |
| EXPECT_EQ(kInvalidTemplateURLID, backup.id); |
| EXPECT_EQ(keyword.short_name, backup.short_name); |
| EXPECT_EQ(keyword.keyword(), backup.keyword()); |
| EXPECT_EQ(keyword.url(), backup.url()); |
| EXPECT_EQ(keyword.favicon_url, backup.favicon_url); |
| EXPECT_EQ(keyword.suggestions_url, backup.suggestions_url); |
| EXPECT_EQ(keyword.show_in_default_list, backup.show_in_default_list); |
| EXPECT_EQ(keyword.safe_for_autoreplace, backup.safe_for_autoreplace); |
| EXPECT_TRUE(keyword_table->DidDefaultSearchProviderChange()); |
| |
| // Change the backup. |
| EXPECT_TRUE(keyword_table->meta_table_->SetValue( |
| KeywordTable::kDefaultSearchProviderKey, 1)); |
| EXPECT_TRUE(keyword_table->meta_table_->SetValue( |
| KeywordTable::kDefaultSearchIDBackupKey, 2)); |
| EXPECT_FALSE(keyword_table->IsBackupSignatureValid( |
| WebDatabase::kCurrentVersionNumber)); |
| EXPECT_EQ(1, keyword_table->GetDefaultSearchProviderID()); |
| EXPECT_FALSE(keyword_table->GetDefaultSearchProviderBackup(&backup)); |
| EXPECT_TRUE(keyword_table->DidDefaultSearchProviderChange()); |
| |
| // Change the signature. |
| EXPECT_TRUE(keyword_table->meta_table_->SetValue( |
| KeywordTable::kDefaultSearchIDBackupKey, 1)); |
| EXPECT_TRUE(keyword_table->meta_table_->SetValue( |
| KeywordTable::kBackupSignatureKey, std::string())); |
| EXPECT_FALSE(keyword_table->IsBackupSignatureValid( |
| WebDatabase::kCurrentVersionNumber)); |
| EXPECT_EQ(1, keyword_table->GetDefaultSearchProviderID()); |
| EXPECT_FALSE(keyword_table->GetDefaultSearchProviderBackup(&backup)); |
| EXPECT_TRUE(keyword_table->DidDefaultSearchProviderChange()); |
| |
| // Change keywords. |
| EXPECT_TRUE(keyword_table->UpdateBackupSignature( |
| WebDatabase::kCurrentVersionNumber)); |
| sql::Statement remove_keyword(keyword_table->db_->GetUniqueStatement( |
| "DELETE FROM keywords WHERE id=1")); |
| EXPECT_TRUE(remove_keyword.Run()); |
| EXPECT_TRUE(keyword_table->IsBackupSignatureValid( |
| WebDatabase::kCurrentVersionNumber)); |
| EXPECT_EQ(1, keyword_table->GetDefaultSearchProviderID()); |
| |
| EXPECT_TRUE(keyword_table->GetDefaultSearchProviderBackup(&backup)); |
| EXPECT_EQ(kInvalidTemplateURLID, backup.id); |
| EXPECT_EQ(keyword.short_name, backup.short_name); |
| EXPECT_EQ(keyword.keyword(), backup.keyword()); |
| EXPECT_EQ(keyword.url(), backup.url()); |
| EXPECT_EQ(keyword.suggestions_url, backup.suggestions_url); |
| EXPECT_EQ(keyword.favicon_url, backup.favicon_url); |
| EXPECT_EQ(keyword.show_in_default_list, backup.show_in_default_list); |
| EXPECT_EQ(keyword.safe_for_autoreplace, backup.safe_for_autoreplace); |
| EXPECT_TRUE(keyword_table->DidDefaultSearchProviderChange()); |
| |
| // Change keywords backup. |
| sql::Statement remove_keyword_backup(keyword_table->db_->GetUniqueStatement( |
| "DELETE FROM keywords_backup WHERE id=1")); |
| EXPECT_TRUE(remove_keyword_backup.Run()); |
| EXPECT_FALSE(keyword_table->IsBackupSignatureValid( |
| WebDatabase::kCurrentVersionNumber)); |
| EXPECT_EQ(1, keyword_table->GetDefaultSearchProviderID()); |
| EXPECT_FALSE(keyword_table->GetDefaultSearchProviderBackup(&backup)); |
| EXPECT_TRUE(keyword_table->DidDefaultSearchProviderChange()); |
| } |
| |
| TEST_F(KeywordTableTest, GetTableContents) { |
| WebDatabase db; |
| ASSERT_EQ(sql::INIT_OK, db.Init(file_)); |
| KeywordTable* keyword_table = db.GetKeywordTable(); |
| |
| TemplateURLData keyword; |
| keyword.short_name = ASCIIToUTF16("short_name"); |
| keyword.SetKeyword(ASCIIToUTF16("keyword")); |
| keyword.SetURL("http://url/"); |
| keyword.suggestions_url = "url2"; |
| keyword.favicon_url = GURL("http://favicon.url/"); |
| keyword.show_in_default_list = true; |
| keyword.safe_for_autoreplace = true; |
| keyword.id = 1; |
| keyword.date_created = base::Time::UnixEpoch(); |
| keyword.last_modified = base::Time::UnixEpoch(); |
| keyword.sync_guid = "1234-5678-90AB-CDEF"; |
| EXPECT_TRUE(keyword_table->AddKeyword(keyword)); |
| |
| keyword.SetKeyword(ASCIIToUTF16("url")); |
| keyword.instant_url = "http://instant2/"; |
| keyword.originating_url = GURL("http://originating.url/"); |
| keyword.input_encodings.push_back("Shift_JIS"); |
| keyword.id = 2; |
| keyword.prepopulate_id = 5; |
| keyword.sync_guid = "FEDC-BA09-8765-4321"; |
| EXPECT_TRUE(keyword_table->AddKeyword(keyword)); |
| |
| const char kTestContents[] = "1short_namekeywordhttp://favicon.url/" |
| "http://url/1001url20001234-5678-90AB-CDEF2short_nameurl" |
| "http://favicon.url/http://url/1http://originating.url/00Shift_JIS1url250" |
| "http://instant2/0FEDC-BA09-8765-4321"; |
| |
| std::string contents; |
| EXPECT_TRUE(keyword_table->GetTableContents("keywords", |
| WebDatabase::kCurrentVersionNumber, &contents)); |
| EXPECT_EQ(kTestContents, contents); |
| |
| EXPECT_TRUE(keyword_table->GetTableContents("keywords_backup", |
| WebDatabase::kCurrentVersionNumber, &contents)); |
| EXPECT_EQ(kTestContents, contents); |
| } |
| |
| TEST_F(KeywordTableTest, GetTableContentsOrdering) { |
| WebDatabase db; |
| ASSERT_EQ(sql::INIT_OK, db.Init(file_)); |
| KeywordTable* keyword_table = db.GetKeywordTable(); |
| |
| TemplateURLData keyword; |
| keyword.short_name = ASCIIToUTF16("short_name"); |
| keyword.SetKeyword(ASCIIToUTF16("keyword")); |
| keyword.SetURL("http://url/"); |
| keyword.suggestions_url = "url2"; |
| keyword.favicon_url = GURL("http://favicon.url/"); |
| keyword.show_in_default_list = true; |
| keyword.safe_for_autoreplace = true; |
| keyword.id = 2; |
| keyword.date_created = base::Time::UnixEpoch(); |
| keyword.last_modified = base::Time::UnixEpoch(); |
| keyword.sync_guid = "1234-5678-90AB-CDEF"; |
| EXPECT_TRUE(keyword_table->AddKeyword(keyword)); |
| |
| keyword.SetKeyword(ASCIIToUTF16("url")); |
| keyword.instant_url = "http://instant2/"; |
| keyword.originating_url = GURL("http://originating.url/"); |
| keyword.input_encodings.push_back("Shift_JIS"); |
| keyword.id = 1; |
| keyword.prepopulate_id = 5; |
| keyword.sync_guid = "FEDC-BA09-8765-4321"; |
| EXPECT_TRUE(keyword_table->AddKeyword(keyword)); |
| |
| const char kTestContents[] = "1short_nameurlhttp://favicon.url/http://url/1" |
| "http://originating.url/00Shift_JIS1url250http://instant2/0" |
| "FEDC-BA09-8765-43212short_namekeywordhttp://favicon.url/http://url/1001" |
| "url20001234-5678-90AB-CDEF"; |
| |
| std::string contents; |
| EXPECT_TRUE(keyword_table->GetTableContents("keywords", |
| WebDatabase::kCurrentVersionNumber, &contents)); |
| EXPECT_EQ(kTestContents, contents); |
| |
| EXPECT_TRUE(keyword_table->GetTableContents("keywords_backup", |
| WebDatabase::kCurrentVersionNumber, &contents)); |
| EXPECT_EQ(kTestContents, contents); |
| } |
| |
| TEST_F(KeywordTableTest, UpdateKeyword) { |
| WebDatabase db; |
| ASSERT_EQ(sql::INIT_OK, db.Init(file_)); |
| KeywordTable* keyword_table = db.GetKeywordTable(); |
| |
| TemplateURLData keyword; |
| keyword.short_name = ASCIIToUTF16("short_name"); |
| keyword.SetKeyword(ASCIIToUTF16("keyword")); |
| keyword.SetURL("http://url/"); |
| keyword.suggestions_url = "url2"; |
| keyword.favicon_url = GURL("http://favicon.url/"); |
| keyword.show_in_default_list = true; |
| keyword.safe_for_autoreplace = true; |
| keyword.id = 1; |
| EXPECT_TRUE(keyword_table->AddKeyword(keyword)); |
| |
| keyword.SetKeyword(ASCIIToUTF16("url")); |
| keyword.instant_url = "http://instant2/"; |
| keyword.originating_url = GURL("http://originating.url/"); |
| keyword.input_encodings.push_back("Shift_JIS"); |
| keyword.prepopulate_id = 5; |
| EXPECT_TRUE(keyword_table->UpdateKeyword(keyword)); |
| |
| KeywordTable::Keywords keywords; |
| EXPECT_TRUE(keyword_table->GetKeywords(&keywords)); |
| EXPECT_EQ(1U, keywords.size()); |
| const TemplateURLData& restored_keyword = keywords.front(); |
| |
| EXPECT_EQ(keyword.short_name, restored_keyword.short_name); |
| EXPECT_EQ(keyword.keyword(), restored_keyword.keyword()); |
| EXPECT_EQ(keyword.suggestions_url, restored_keyword.suggestions_url); |
| EXPECT_EQ(keyword.instant_url, restored_keyword.instant_url); |
| EXPECT_EQ(keyword.favicon_url, restored_keyword.favicon_url); |
| EXPECT_EQ(keyword.originating_url, restored_keyword.originating_url); |
| EXPECT_EQ(keyword.show_in_default_list, |
| restored_keyword.show_in_default_list); |
| EXPECT_EQ(keyword.safe_for_autoreplace, |
| restored_keyword.safe_for_autoreplace); |
| EXPECT_EQ(keyword.input_encodings, restored_keyword.input_encodings); |
| EXPECT_EQ(keyword.id, restored_keyword.id); |
| EXPECT_EQ(keyword.prepopulate_id, restored_keyword.prepopulate_id); |
| } |
| |
| TEST_F(KeywordTableTest, KeywordWithNoFavicon) { |
| WebDatabase db; |
| ASSERT_EQ(sql::INIT_OK, db.Init(file_)); |
| KeywordTable* keyword_table = db.GetKeywordTable(); |
| |
| TemplateURLData keyword; |
| keyword.short_name = ASCIIToUTF16("short_name"); |
| keyword.SetKeyword(ASCIIToUTF16("keyword")); |
| keyword.SetURL("http://url/"); |
| keyword.safe_for_autoreplace = true; |
| keyword.id = -100; |
| EXPECT_TRUE(keyword_table->AddKeyword(keyword)); |
| |
| KeywordTable::Keywords keywords; |
| EXPECT_TRUE(keyword_table->GetKeywords(&keywords)); |
| EXPECT_EQ(1U, keywords.size()); |
| const TemplateURLData& restored_keyword = keywords.front(); |
| |
| EXPECT_EQ(keyword.short_name, restored_keyword.short_name); |
| EXPECT_EQ(keyword.keyword(), restored_keyword.keyword()); |
| EXPECT_EQ(keyword.favicon_url, restored_keyword.favicon_url); |
| EXPECT_EQ(keyword.safe_for_autoreplace, |
| restored_keyword.safe_for_autoreplace); |
| EXPECT_EQ(keyword.id, restored_keyword.id); |
| } |
| |
| TEST_F(KeywordTableTest, SanitizeURLs) { |
| WebDatabase db; |
| ASSERT_EQ(sql::INIT_OK, db.Init(file_)); |
| KeywordTable* keyword_table = db.GetKeywordTable(); |
| |
| TemplateURLData keyword; |
| keyword.short_name = ASCIIToUTF16("legit"); |
| keyword.SetKeyword(ASCIIToUTF16("legit")); |
| keyword.SetURL("http://url/"); |
| keyword.id = 1000; |
| EXPECT_TRUE(keyword_table->AddKeyword(keyword)); |
| |
| keyword.short_name = ASCIIToUTF16("bogus"); |
| keyword.SetKeyword(ASCIIToUTF16("bogus")); |
| keyword.id = 2000; |
| EXPECT_TRUE(keyword_table->AddKeyword(keyword)); |
| |
| KeywordTable::Keywords keywords; |
| EXPECT_TRUE(keyword_table->GetKeywords(&keywords)); |
| EXPECT_EQ(2U, keywords.size()); |
| keywords.clear(); |
| |
| // Erase the URL field for the second keyword to simulate having bogus data |
| // previously saved into the database. |
| sql::Statement s(keyword_table->db_->GetUniqueStatement( |
| "UPDATE keywords SET url=? WHERE id=?")); |
| s.BindString16(0, string16()); |
| s.BindInt64(1, 2000); |
| EXPECT_TRUE(s.Run()); |
| EXPECT_TRUE(keyword_table->UpdateBackupSignature( |
| WebDatabase::kCurrentVersionNumber)); |
| |
| // GetKeywords() should erase the entry with the empty URL field. |
| EXPECT_TRUE(keyword_table->GetKeywords(&keywords)); |
| EXPECT_EQ(1U, keywords.size()); |
| } |