1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/values.h"
12 #include "components/search_engines/search_terms_data.h"
13 #include "components/search_engines/template_url.h"
14 #include "components/search_engines/template_url_service.h"
15 #include "components/search_engines/util.h"
16 #include "testing/gtest/include/gtest/gtest.h"
20 std::unique_ptr<TemplateURLData> CreatePrepopulateTemplateURLData(
22 const std::string& keyword) {
23 return std::make_unique<TemplateURLData>(
24 u"Search engine name", base::ASCIIToUTF16(keyword), "https://search.url",
25 "" /* suggest_url */, "" /* image_url */, "" /* image_translate_url */,
26 "" /* new_tab_url */, "" /* contextual_search_url */, "" /* logo_url */,
27 "" /* doodle_url */, "" /* search_url_post_params */,
28 "" /* suggest_url_post_params */, "" /* image_url_post_params */,
29 "" /* side_search_param */, "" /* side_image_search_param */,
30 "" /* image_translate_source_language_param_key */,
31 "" /* image_translate_target_language_param_key */,
32 std::vector<std::string>() /* search_intent_params */,
33 "" /* favicon_url */, "UTF-8", u"" /* image_search_branding_label */,
34 base::Value::List() /* alternate_urls_list */,
35 false /* preconnect_to_search_url */,
36 false /* prefetch_likely_navigations */, prepopulate_id);
39 // Creates a TemplateURL with default values except for the prepopulate ID,
40 // keyword and TemplateURLID. Only use this in tests if your tests do not
41 // care about other fields.
42 std::unique_ptr<TemplateURL> CreatePrepopulateTemplateURL(
44 const std::string& keyword,
46 bool is_play_api_turl = false) {
47 std::unique_ptr<TemplateURLData> data =
48 CreatePrepopulateTemplateURLData(prepopulate_id, keyword);
50 data->created_from_play_api = is_play_api_turl;
51 return std::make_unique<TemplateURL>(*data);
56 TEST(TemplateURLServiceUtilTest, RemoveDuplicatePrepopulateIDs) {
57 std::vector<std::unique_ptr<TemplateURLData>> prepopulated_turls;
58 TemplateURLService::OwnedTemplateURLVector local_turls;
60 prepopulated_turls.push_back(CreatePrepopulateTemplateURLData(1, "winner4"));
61 prepopulated_turls.push_back(CreatePrepopulateTemplateURLData(2, "xxx"));
62 prepopulated_turls.push_back(CreatePrepopulateTemplateURLData(3, "yyy"));
64 // Create a sets of different TURLs grouped by prepopulate ID. Each group
65 // will test a different heuristic of RemoveDuplicatePrepopulateIDs.
66 // Ignored set - These should be left alone as they do not have valid
68 local_turls.push_back(CreatePrepopulateTemplateURL(0, "winner1", 4));
69 local_turls.push_back(CreatePrepopulateTemplateURL(0, "winner2", 5));
70 local_turls.push_back(CreatePrepopulateTemplateURL(0, "winner3", 6));
71 size_t num_non_prepopulated_urls = local_turls.size();
73 // Keyword match set - Prefer the one that matches the keyword of the
75 local_turls.push_back(CreatePrepopulateTemplateURL(1, "loser1", 7));
76 local_turls.push_back(CreatePrepopulateTemplateURL(1, "loser2", 8));
77 local_turls.push_back(CreatePrepopulateTemplateURL(1, "winner4", 9));
79 // Default set - Prefer the default search engine over all other criteria.
80 // The last one is the default. It will be passed as the
81 // default_search_provider parameter to RemoveDuplicatePrepopulateIDs.
82 local_turls.push_back(CreatePrepopulateTemplateURL(2, "loser3", 10));
83 local_turls.push_back(CreatePrepopulateTemplateURL(2, "xxx", 11));
84 local_turls.push_back(CreatePrepopulateTemplateURL(2, "winner5", 12));
85 TemplateURL* default_turl = local_turls.back().get();
87 // ID set - Prefer the lowest TemplateURLID if the keywords don't match and if
88 // none are the default.
89 local_turls.push_back(CreatePrepopulateTemplateURL(3, "winner6", 13));
90 local_turls.push_back(CreatePrepopulateTemplateURL(3, "loser5", 14));
91 local_turls.push_back(CreatePrepopulateTemplateURL(3, "loser6", 15));
93 RemoveDuplicatePrepopulateIDs(nullptr, prepopulated_turls, default_turl,
94 &local_turls, SearchTermsData(), nullptr);
96 // Verify that the expected local TURLs survived the process.
97 EXPECT_EQ(local_turls.size(),
98 prepopulated_turls.size() + num_non_prepopulated_urls);
99 for (const auto& turl : local_turls) {
100 EXPECT_TRUE(base::StartsWith(turl->keyword(), u"winner",
101 base::CompareCase::SENSITIVE));
105 // Tests correct interaction of Play API search engine during prepopulated list
107 TEST(TemplateURLServiceUtilTest, MergeEnginesFromPrepopulateData_PlayAPI) {
108 std::vector<std::unique_ptr<TemplateURLData>> prepopulated_turls;
109 TemplateURLService::OwnedTemplateURLVector local_turls;
111 // Start with single search engine created from Play API data.
112 local_turls.push_back(CreatePrepopulateTemplateURL(0, "play", 1, true));
114 // Test that prepopulated search engine with matching keyword is merged with
115 // Play API search engine. Search URL should come from Play API search engine.
116 const std::string prepopulated_search_url = "http://prepopulated.url";
117 prepopulated_turls.push_back(CreatePrepopulateTemplateURLData(1, "play"));
118 prepopulated_turls.back()->SetURL(prepopulated_search_url);
119 MergeEnginesFromPrepopulateData(nullptr, &prepopulated_turls, &local_turls,
121 ASSERT_EQ(local_turls.size(), 1U);
122 // Merged search engine should have both Play API flag and valid
124 EXPECT_TRUE(local_turls[0]->created_from_play_api());
125 EXPECT_EQ(1, local_turls[0]->prepopulate_id());
126 EXPECT_NE(prepopulated_search_url, local_turls[0]->url());
128 // Test that merging prepopulated search engine with matching prepopulate_id
129 // preserves keyword of Play API search engine.
130 prepopulated_turls.clear();
131 prepopulated_turls.push_back(CreatePrepopulateTemplateURLData(1, "play2"));
132 MergeEnginesFromPrepopulateData(nullptr, &prepopulated_turls, &local_turls,
134 ASSERT_EQ(local_turls.size(), 1U);
135 EXPECT_TRUE(local_turls[0]->created_from_play_api());
136 EXPECT_EQ(local_turls[0]->keyword(), u"play");
138 // Test that removing search engine from prepopulated list doesn't delete Play
139 // API search engine record.
140 prepopulated_turls.clear();
141 MergeEnginesFromPrepopulateData(nullptr, &prepopulated_turls, &local_turls,
143 ASSERT_EQ(local_turls.size(), 1U);
144 EXPECT_TRUE(local_turls[0]->created_from_play_api());
145 EXPECT_EQ(local_turls[0]->prepopulate_id(), 0);
148 // Tests that user modified fields are preserved and overwritten appropriately
149 // in MergeIntoEngineData().
150 TEST(TemplateURLServiceUtilTest, MergeIntoEngineData) {
151 std::unique_ptr<TemplateURLData> original_turl_data =
152 CreatePrepopulateTemplateURLData(1, "google");
153 std::unique_ptr<TemplateURLData> url_to_update =
154 CreatePrepopulateTemplateURLData(1, "google");
156 // Modify the keyword and title for original_turl and set safe_for_autoreplace
157 // to false to simulate a "user edited" template url.
158 original_turl_data->SetShortName(u"modified name");
159 original_turl_data->SetKeyword(u"new keyword");
160 original_turl_data->safe_for_autoreplace = false;
162 std::unique_ptr<TemplateURL> original_turl =
163 std::make_unique<TemplateURL>(*original_turl_data);
165 // Set `merge_options` to kOverwriteUserEdits. This should NOT preserve the
166 // modified fields. `url_to_update` should keep the default keyword and name
167 // values as well as safe_for_autoreplace being true.
168 MergeIntoEngineData(original_turl.get(), url_to_update.get(),
169 TemplateURLMergeOption::kOverwriteUserEdits);
171 EXPECT_TRUE(url_to_update->safe_for_autoreplace);
172 EXPECT_EQ(url_to_update->short_name(), u"Search engine name");
173 EXPECT_EQ(url_to_update->keyword(), u"google");
175 // Set `merge_options` to kDefault. This should preserve the modified
176 // keyword and title fields from original_turl and update url_to_update
178 MergeIntoEngineData(original_turl.get(), url_to_update.get(),
179 TemplateURLMergeOption::kDefault);
181 EXPECT_FALSE(url_to_update->safe_for_autoreplace);
182 EXPECT_EQ(url_to_update->short_name(), u"modified name");
183 EXPECT_EQ(url_to_update->keyword(), u"new keyword");