| // Copyright 2025 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/search_engines/ui_utils.h" |
| |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "components/omnibox/common/omnibox_feature_configs.h" |
| #include "components/omnibox/common/omnibox_features.h" |
| #include "components/search_engines/template_url.h" |
| #include "components/search_engines/template_url_data.h" |
| #include "components/search_engines/template_url_data_util.h" |
| #include "components/search_engines/template_url_service.h" |
| #include "components/search_engines/template_url_service_test_util.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/icu/source/common/unicode/locid.h" |
| #include "third_party/icu/source/i18n/unicode/coll.h" |
| |
| namespace { |
| |
| // Helper function to create a TemplateURL with specified properties |
| std::unique_ptr<TemplateURL> CreateTemplateURL(const std::u16string& short_name, |
| const std::u16string& keyword, |
| const std::string& url, |
| bool created_by_policy = false, |
| int prepopulate_id = 0) { |
| TemplateURLData data; |
| data.SetShortName(short_name); |
| data.SetKeyword(keyword); |
| data.SetURL(url); |
| data.is_active = TemplateURLData::ActiveStatus::kTrue; |
| data.policy_origin = created_by_policy |
| ? TemplateURLData::PolicyOrigin::kSiteSearch |
| : TemplateURLData::PolicyOrigin::kNoPolicy; |
| data.prepopulate_id = prepopulate_id; |
| return std::make_unique<TemplateURL>(data); |
| } |
| |
| } // namespace |
| |
| // Test fixture for the internal sorting logic |
| class OrderTemplateUrlsByManagedAndAlphabeticallyTest : public testing::Test { |
| public: |
| OrderTemplateUrlsByManagedAndAlphabeticallyTest() = default; |
| ~OrderTemplateUrlsByManagedAndAlphabeticallyTest() override = default; |
| |
| protected: |
| void SetUp() override { |
| comparator_ = std::make_unique< |
| internal::OrderTemplateUrlsByManagedAndAlphabetically>(); |
| } |
| |
| std::unique_ptr<internal::OrderTemplateUrlsByManagedAndAlphabetically> |
| comparator_; |
| }; |
| |
| // Test basic alphabetical sorting |
| TEST_F(OrderTemplateUrlsByManagedAndAlphabeticallyTest, |
| BasicAlphabeticalSorting) { |
| auto google = CreateTemplateURL(u"Google", u"google.com", |
| "https://google.com/search?q={searchTerms}"); |
| auto bing = CreateTemplateURL(u"Bing", u"bing.com", |
| "https://bing.com/search?q={searchTerms}"); |
| auto yahoo = CreateTemplateURL(u"Yahoo", u"yahoo.com", |
| "https://yahoo.com/search?q={searchTerms}"); |
| |
| // Bing should come before Google, Google before Yahoo |
| EXPECT_TRUE((*comparator_)(bing.get(), google.get())); |
| EXPECT_TRUE((*comparator_)(google.get(), yahoo.get())); |
| EXPECT_TRUE((*comparator_)(bing.get(), yahoo.get())); |
| |
| // Reverse comparisons should be false |
| EXPECT_FALSE((*comparator_)(google.get(), bing.get())); |
| EXPECT_FALSE((*comparator_)(yahoo.get(), google.get())); |
| EXPECT_FALSE((*comparator_)(yahoo.get(), bing.get())); |
| } |
| |
| // Test that managed engines come before non-managed engines |
| TEST_F(OrderTemplateUrlsByManagedAndAlphabeticallyTest, ManagedEnginesFirst) { |
| auto managed_yahoo = CreateTemplateURL( |
| u"Yahoo", u"yahoo.com", "https://yahoo.com/search?q={searchTerms}", true); |
| auto regular_bing = CreateTemplateURL( |
| u"Bing", u"bing.com", "https://bing.com/search?q={searchTerms}", false); |
| |
| // Even though Bing comes before Yahoo alphabetically, managed Yahoo should |
| // come first |
| EXPECT_TRUE((*comparator_)(managed_yahoo.get(), regular_bing.get())); |
| EXPECT_FALSE((*comparator_)(regular_bing.get(), managed_yahoo.get())); |
| } |
| |
| // Test sorting within managed and non-managed groups |
| TEST_F(OrderTemplateUrlsByManagedAndAlphabeticallyTest, SortingWithinGroups) { |
| auto managed_google = |
| CreateTemplateURL(u"Google", u"google.com", |
| "https://google.com/search?q={searchTerms}", true); |
| auto managed_bing = CreateTemplateURL( |
| u"Bing", u"bing.com", "https://bing.com/search?q={searchTerms}", true); |
| auto regular_yahoo = |
| CreateTemplateURL(u"Yahoo", u"yahoo.com", |
| "https://yahoo.com/search?q={searchTerms}", false); |
| auto regular_ask = CreateTemplateURL( |
| u"Ask", u"ask.com", "https://ask.com/search?q={searchTerms}", false); |
| |
| // Within managed group: Bing before Google |
| EXPECT_TRUE((*comparator_)(managed_bing.get(), managed_google.get())); |
| |
| // Within regular group: Ask before Yahoo |
| EXPECT_TRUE((*comparator_)(regular_ask.get(), regular_yahoo.get())); |
| |
| // Managed engines before regular engines |
| EXPECT_TRUE((*comparator_)(managed_google.get(), regular_ask.get())); |
| EXPECT_TRUE((*comparator_)(managed_bing.get(), regular_yahoo.get())); |
| } |
| |
| // Test case-insensitive sorting |
| TEST_F(OrderTemplateUrlsByManagedAndAlphabeticallyTest, |
| CaseInsensitiveSorting) { |
| auto lower_google = CreateTemplateURL( |
| u"google", u"google.com", "https://google.com/search?q={searchTerms}"); |
| auto upper_bing = CreateTemplateURL( |
| u"BING", u"bing.com", "https://bing.com/search?q={searchTerms}"); |
| |
| // Should still sort alphabetically regardless of case |
| EXPECT_TRUE((*comparator_)(upper_bing.get(), lower_google.get())); |
| EXPECT_FALSE((*comparator_)(lower_google.get(), upper_bing.get())); |
| } |
| |
| // Test Unicode string handling |
| TEST_F(OrderTemplateUrlsByManagedAndAlphabeticallyTest, UnicodeStringHandling) { |
| auto ascii_engine = CreateTemplateURL( |
| u"Google", u"google.com", "https://google.com/search?q={searchTerms}"); |
| auto unicode_engine = CreateTemplateURL( |
| u"Яндекс", u"yandex.ru", "https://yandex.ru/search?q={searchTerms}"); |
| auto accented_engine = CreateTemplateURL( |
| u"Écosía", u"ecosia.org", "https://ecosia.org/search?q={searchTerms}"); |
| |
| // The exact sorting order may depend on locale, but the function should not |
| // crash and should produce consistent results |
| bool result1 = (*comparator_)(ascii_engine.get(), unicode_engine.get()); |
| bool result2 = (*comparator_)(unicode_engine.get(), ascii_engine.get()); |
| EXPECT_NE(result1, result2); // One should be true, the other false |
| |
| bool result3 = (*comparator_)(ascii_engine.get(), accented_engine.get()); |
| bool result4 = (*comparator_)(accented_engine.get(), ascii_engine.get()); |
| EXPECT_NE(result3, result4); |
| } |
| |
| // Test fallback to keyword when short names are identical |
| TEST_F(OrderTemplateUrlsByManagedAndAlphabeticallyTest, FallbackToKeyword) { |
| auto engine1 = CreateTemplateURL( |
| u"Search", u"search1.com", "https://search1.com/search?q={searchTerms}"); |
| auto engine2 = CreateTemplateURL( |
| u"Search", u"search2.com", "https://search2.com/search?q={searchTerms}"); |
| |
| // Should sort by keyword when short names are identical |
| EXPECT_TRUE((*comparator_)(engine1.get(), engine2.get())); |
| EXPECT_FALSE((*comparator_)(engine2.get(), engine1.get())); |
| } |
| |
| // Test buffer overflow protection in GetShortNameSortKey |
| TEST_F(OrderTemplateUrlsByManagedAndAlphabeticallyTest, |
| BufferOverflowProtection) { |
| // Create a very long string that would exceed the 1000 byte buffer |
| std::u16string very_long_name; |
| // Use multi-byte Unicode characters to more easily exceed buffer |
| for (int i = 0; i < 500; i++) { |
| very_long_name += u"测试"; // Each character is 3 bytes in UTF-8 |
| } |
| |
| auto long_name_engine = |
| CreateTemplateURL(very_long_name, u"longname.com", |
| "https://longname.com/search?q={searchTerms}"); |
| auto short_name_engine = CreateTemplateURL( |
| u"Short", u"short.com", "https://short.com/search?q={searchTerms}"); |
| |
| // Should not crash even with very long names |
| bool result1 = |
| (*comparator_)(long_name_engine.get(), short_name_engine.get()); |
| bool result2 = |
| (*comparator_)(short_name_engine.get(), long_name_engine.get()); |
| |
| // Results should be consistent (one true, one false) |
| EXPECT_NE(result1, result2); |
| |
| // Test that GetShortNameSortKey doesn't crash with very long strings |
| std::string sort_key = |
| comparator_->GetShortNameSortKeyForTesting(very_long_name); |
| EXPECT_FALSE(sort_key.empty()); |
| |
| // The sort key should be truncated but still valid |
| EXPECT_LT(sort_key.length(), 1000u); |
| } |
| |
| // Test GetShortNameSortKey with various Unicode scenarios |
| TEST_F(OrderTemplateUrlsByManagedAndAlphabeticallyTest, |
| GetShortNameSortKeyUnicode) { |
| // Test with ASCII |
| std::string ascii_key = comparator_->GetShortNameSortKeyForTesting(u"Google"); |
| EXPECT_FALSE(ascii_key.empty()); |
| |
| // Test with Unicode |
| std::string unicode_key = |
| comparator_->GetShortNameSortKeyForTesting(u"Яндекс"); |
| EXPECT_FALSE(unicode_key.empty()); |
| |
| // Test with accented characters |
| std::string accented_key = |
| comparator_->GetShortNameSortKeyForTesting(u"Écosía"); |
| EXPECT_FALSE(accented_key.empty()); |
| |
| // Test with empty string |
| std::string empty_key = comparator_->GetShortNameSortKeyForTesting(u""); |
| // Empty string should produce empty or very short key |
| EXPECT_LE(empty_key.length(), 1u); |
| } |
| |
| // Test edge cases with special characters |
| TEST_F(OrderTemplateUrlsByManagedAndAlphabeticallyTest, SpecialCharacters) { |
| auto numeric_engine = |
| CreateTemplateURL(u"123Search", u"123search.com", |
| "https://123search.com/search?q={searchTerms}"); |
| auto symbol_engine = |
| CreateTemplateURL(u"@Search", u"atsearch.com", |
| "https://atsearch.com/search?q={searchTerms}"); |
| auto mixed_engine = |
| CreateTemplateURL(u"A1@Search", u"a1search.com", |
| "https://a1search.com/search?q={searchTerms}"); |
| |
| // Should handle special characters without crashing |
| bool result1 = (*comparator_)(numeric_engine.get(), symbol_engine.get()); |
| bool result2 = (*comparator_)(symbol_engine.get(), mixed_engine.get()); |
| bool result3 = (*comparator_)(numeric_engine.get(), mixed_engine.get()); |
| |
| // Results should be consistent |
| EXPECT_EQ(result1, |
| !(*comparator_)(symbol_engine.get(), numeric_engine.get())); |
| EXPECT_EQ(result2, !(*comparator_)(mixed_engine.get(), symbol_engine.get())); |
| EXPECT_EQ(result3, !(*comparator_)(mixed_engine.get(), numeric_engine.get())); |
| } |
| |
| // Test with extremely long Unicode sequences that could cause buffer issues |
| TEST_F(OrderTemplateUrlsByManagedAndAlphabeticallyTest, ExtremelyLongUnicode) { |
| // Create string with combining characters that could expand during |
| // normalization |
| std::u16string base_char = u"a"; |
| std::u16string combining_chars; |
| for (int i = 0; i < 200; i++) { |
| combining_chars += u"\u0301"; // Combining acute accent |
| } |
| std::u16string extreme_string = base_char + combining_chars; |
| |
| auto extreme_engine = |
| CreateTemplateURL(extreme_string, u"extreme.com", |
| "https://extreme.com/search?q={searchTerms}"); |
| auto normal_engine = CreateTemplateURL( |
| u"Normal", u"normal.com", "https://normal.com/search?q={searchTerms}"); |
| |
| // Should handle extreme Unicode without crashing |
| EXPECT_NO_FATAL_FAILURE({ |
| bool result = (*comparator_)(extreme_engine.get(), normal_engine.get()); |
| (void)result; // Suppress unused variable warning |
| }); |
| |
| // GetShortNameSortKey should handle this without crashing |
| EXPECT_NO_FATAL_FAILURE({ |
| std::string sort_key = |
| comparator_->GetShortNameSortKeyForTesting(extreme_string); |
| EXPECT_LE(sort_key.length(), 1000u); |
| }); |
| } |
| |
| // Test with exact buffer boundary conditions |
| TEST_F(OrderTemplateUrlsByManagedAndAlphabeticallyTest, |
| BufferBoundaryConditions) { |
| // Test string that should be exactly at buffer limit |
| std::u16string near_limit_string; |
| // Create a string that when converted to sort key approaches the 1000 byte |
| // limit |
| for (int i = 0; i < 100; i++) { |
| near_limit_string += u"abcdefghij"; // 10 ASCII chars per iteration |
| } |
| |
| auto near_limit_engine = |
| CreateTemplateURL(near_limit_string, u"nearlimit.com", |
| "https://nearlimit.com/search?q={searchTerms}"); |
| auto normal_engine = CreateTemplateURL( |
| u"Normal", u"normal.com", "https://normal.com/search?q={searchTerms}"); |
| |
| // Should handle near-limit strings without issues |
| EXPECT_NO_FATAL_FAILURE({ |
| bool result = (*comparator_)(near_limit_engine.get(), normal_engine.get()); |
| std::string sort_key = |
| comparator_->GetShortNameSortKeyForTesting(near_limit_string); |
| EXPECT_FALSE(sort_key.empty()); |
| EXPECT_LT(sort_key.length(), 1000u); |
| (void)result; // Suppress unused variable warning |
| }); |
| } |
| |
| class OrderTemplateUrlsByPrepopulatedAndManagedAndAlphabetically |
| : public testing::Test {}; |
| |
| // Test that regional prepopulated engines are added first, then non-regional |
| // ones, then custom ones. |
| TEST_F(OrderTemplateUrlsByPrepopulatedAndManagedAndAlphabetically, |
| PrepopulatedEnginesFirst) { |
| std::unique_ptr<TemplateURLData> bing_data = |
| TemplateURLDataFromPrepopulatedEngine(TemplateURLPrepopulateData::bing); |
| |
| auto bing_engine = CreateTemplateURL( |
| u"Bing", u"bing.com", "https://bing.com/search?q={searchTerms}", |
| /*created_by_policy=*/false, bing_data->prepopulate_id); |
| auto prepopulated_engine = CreateTemplateURL( |
| u"CustomPrepop", u"customprepop.com", |
| "https://customprepop.com/search?q={searchTerms}", |
| /*created_by_policy=*/false, bing_data->prepopulate_id + 1); |
| auto custom_engine = |
| CreateTemplateURL(u"A-Engine", u"aengine.com", |
| "https://aengine.com/search?q={searchTerms}"); |
| |
| std::vector<std::unique_ptr<TemplateURLData>> prepopulated_urls; |
| prepopulated_urls.push_back(std::move(bing_data)); |
| |
| auto comparator = std::make_unique< |
| internal::OrderTemplateUrlsByPrepopulatedAndManagedAndAlphabetically>( |
| std::move(prepopulated_urls)); |
| |
| // Even though the alphabetical order is different, the prepopulated engines |
| // are added first. |
| EXPECT_TRUE((*comparator)(bing_engine.get(), prepopulated_engine.get())); |
| EXPECT_FALSE((*comparator)(prepopulated_engine.get(), bing_engine.get())); |
| |
| EXPECT_TRUE((*comparator)(bing_engine.get(), custom_engine.get())); |
| EXPECT_FALSE((*comparator)(custom_engine.get(), bing_engine.get())); |
| |
| EXPECT_TRUE((*comparator)(prepopulated_engine.get(), custom_engine.get())); |
| EXPECT_FALSE((*comparator)(custom_engine.get(), prepopulated_engine.get())); |
| } |
| |
| // Test that prepopulated engines are added in the order of |
| // `prepopulated_engines`. |
| TEST_F(OrderTemplateUrlsByPrepopulatedAndManagedAndAlphabetically, |
| PrepopulatedEnginesSorted) { |
| std::unique_ptr<TemplateURLData> yahoo_data = |
| TemplateURLDataFromPrepopulatedEngine(TemplateURLPrepopulateData::yahoo); |
| std::unique_ptr<TemplateURLData> bing_data = |
| TemplateURLDataFromPrepopulatedEngine(TemplateURLPrepopulateData::bing); |
| std::unique_ptr<TemplateURLData> google_data = |
| TemplateURLDataFromPrepopulatedEngine(TemplateURLPrepopulateData::google); |
| |
| auto yahoo_engine = CreateTemplateURL( |
| u"Yahoo", u"yahoo.com", "https://yahoo.com/search?q={searchTerms}", |
| /*created_by_policy=*/false, yahoo_data->prepopulate_id); |
| auto bing_engine = CreateTemplateURL( |
| u"Bing", u"bing.com", "https://bing.com/search?q={searchTerms}", |
| /*created_by_policy=*/false, bing_data->prepopulate_id); |
| auto google_engine = CreateTemplateURL( |
| u"Google", u"google.com", "https://google.com/search?q={searchTerms}", |
| /*created_by_policy=*/false, google_data->prepopulate_id); |
| |
| std::vector<std::unique_ptr<TemplateURLData>> prepopulated_urls; |
| prepopulated_urls.push_back(std::move(yahoo_data)); |
| prepopulated_urls.push_back(std::move(bing_data)); |
| prepopulated_urls.push_back(std::move(google_data)); |
| |
| auto comparator = std::make_unique< |
| internal::OrderTemplateUrlsByPrepopulatedAndManagedAndAlphabetically>( |
| std::move(prepopulated_urls)); |
| |
| // Even though the alphabetical order is different, the engines are added in |
| // the order of `prepopulated_urls`. |
| EXPECT_TRUE((*comparator)(yahoo_engine.get(), bing_engine.get())); |
| EXPECT_FALSE((*comparator)(bing_engine.get(), yahoo_engine.get())); |
| |
| EXPECT_TRUE((*comparator)(yahoo_engine.get(), google_engine.get())); |
| EXPECT_FALSE((*comparator)(google_engine.get(), yahoo_engine.get())); |
| |
| EXPECT_TRUE((*comparator)(bing_engine.get(), google_engine.get())); |
| EXPECT_FALSE((*comparator)(google_engine.get(), bing_engine.get())); |
| } |
| |
| class SortAndFilterRecentlyVisitedURLsTest : public testing::Test { |
| protected: |
| std::unique_ptr<TemplateURL> CreateSearchEngineWithVisitTime( |
| base::Time last_visited) { |
| TemplateURLData data; |
| data.SetShortName(u"Test Engine"); |
| data.SetKeyword(u"test"); |
| data.SetURL("https://test.com/search?q={searchTerms}"); |
| data.last_visited = last_visited; |
| return std::make_unique<TemplateURL>(data); |
| } |
| }; |
| |
| // Test that search engines visited longer than 2 days ago are filtered out. |
| TEST_F(SortAndFilterRecentlyVisitedURLsTest, FiltersOutOldVisits) { |
| base::Time now = base::Time::Now(); |
| |
| auto engine_recent_1 = CreateSearchEngineWithVisitTime(now - base::Hours(1)); |
| auto engine_recent_2 = CreateSearchEngineWithVisitTime(now - base::Days(1)); |
| auto engine_expired_1 = |
| CreateSearchEngineWithVisitTime(now - base::Days(2) - base::Seconds(1)); |
| auto engine_expired_2 = CreateSearchEngineWithVisitTime(now - base::Days(10)); |
| |
| TemplateURL::TemplateURLVector recently_visited = { |
| engine_expired_1.get(), engine_recent_1.get(), engine_expired_2.get(), |
| engine_recent_2.get()}; |
| |
| internal::SortAndFilterRecentlyVisitedURLs(recently_visited); |
| |
| // Only the two non-expired engines should remain, sorted by recency. |
| ASSERT_EQ(recently_visited.size(), 2u); |
| EXPECT_EQ(recently_visited[0], engine_recent_1.get()); |
| EXPECT_EQ(recently_visited[1], engine_recent_2.get()); |
| } |
| |
| // Test that only the top 3 (kMaxCustomSearchEngines) most recently visited |
| // engines are kept. |
| TEST_F(SortAndFilterRecentlyVisitedURLsTest, LimitsToMaxThreeEngines) { |
| base::Time now = base::Time::Now(); |
| |
| // Create 5 engines, all within the valid 2-day window, with distinct visit |
| // times. |
| auto engine_1st = CreateSearchEngineWithVisitTime(now - base::Minutes(5)); |
| auto engine_2nd = CreateSearchEngineWithVisitTime(now - base::Hours(1)); |
| auto engine_3rd = CreateSearchEngineWithVisitTime(now - base::Hours(12)); |
| auto engine_4th = CreateSearchEngineWithVisitTime(now - base::Days(1)); |
| auto engine_5th = CreateSearchEngineWithVisitTime(now - base::Hours(36)); |
| |
| // Push them in an unsorted order |
| TemplateURL::TemplateURLVector recently_visited = { |
| engine_4th.get(), engine_2nd.get(), engine_5th.get(), engine_1st.get(), |
| engine_3rd.get()}; |
| |
| internal::SortAndFilterRecentlyVisitedURLs(recently_visited); |
| |
| // Vector must be capped to exactly 3 elements, sorted by most recent first. |
| ASSERT_EQ(recently_visited.size(), 3u); |
| EXPECT_EQ(recently_visited[0], engine_1st.get()); |
| EXPECT_EQ(recently_visited[1], engine_2nd.get()); |
| EXPECT_EQ(recently_visited[2], engine_3rd.get()); |
| } |
| |
| // Test that empty inputs do not cause crashes or unexpected behaviors. |
| TEST_F(SortAndFilterRecentlyVisitedURLsTest, HandlesEmptyVector) { |
| TemplateURL::TemplateURLVector recently_visited; |
| |
| internal::SortAndFilterRecentlyVisitedURLs(recently_visited); |
| |
| EXPECT_TRUE(recently_visited.empty()); |
| } |
| |
| // Test handling of vectors with fewer elements than the maximum allowed |
| // capacity. |
| TEST_F(SortAndFilterRecentlyVisitedURLsTest, HandlesFewerThanMaxEngines) { |
| base::Time now = base::Time::Now(); |
| |
| auto engine_newer = CreateSearchEngineWithVisitTime(now - base::Hours(2)); |
| auto engine_older = CreateSearchEngineWithVisitTime(now - base::Hours(10)); |
| |
| TemplateURL::TemplateURLVector recently_visited = {engine_older.get(), |
| engine_newer.get()}; |
| |
| internal::SortAndFilterRecentlyVisitedURLs(recently_visited); |
| |
| // Both should be kept because we are below the limit of 3, but sorted by |
| // recency. |
| ASSERT_EQ(recently_visited.size(), 2u); |
| EXPECT_EQ(recently_visited[0], engine_newer.get()); |
| EXPECT_EQ(recently_visited[1], engine_older.get()); |
| } |
| |
| class GetDisabledStarterPackIdsTest : public testing::Test {}; |
| |
| TEST_F(GetDisabledStarterPackIdsTest, AiMode) { |
| auto disabled_ids_with_ai = internal::GetDisabledStarterPackIds( |
| /*ai_mode_enabled=*/true, /*gemini_enabled=*/true); |
| EXPECT_FALSE(disabled_ids_with_ai.Has( |
| template_url_starter_pack_data::StarterPackId::kAiMode)); |
| |
| auto disabled_ids_without_ai = internal::GetDisabledStarterPackIds( |
| /*ai_mode_enabled=*/false, /*gemini_enabled=*/true); |
| EXPECT_TRUE(disabled_ids_without_ai.Has( |
| template_url_starter_pack_data::StarterPackId::kAiMode)); |
| } |
| |
| TEST_F(GetDisabledStarterPackIdsTest, GeminiWithStarterPackExpansion) { |
| base::test::ScopedFeatureList feature_list{omnibox::kStarterPackExpansion}; |
| |
| auto disabled_ids = internal::GetDisabledStarterPackIds( |
| /*ai_mode_enabled=*/true, /*gemini_enabled=*/true); |
| EXPECT_FALSE( |
| disabled_ids.Has(template_url_starter_pack_data::StarterPackId::kGemini)); |
| } |
| |
| TEST_F(GetDisabledStarterPackIdsTest, GeminiWithoutStarterPackExpansion) { |
| base::test::ScopedFeatureList feature_list; |
| feature_list.InitAndDisableFeature(omnibox::kStarterPackExpansion); |
| |
| auto disabled_ids = internal::GetDisabledStarterPackIds( |
| /*ai_mode_enabled=*/true, /*gemini_enabled=*/false); |
| EXPECT_TRUE( |
| disabled_ids.Has(template_url_starter_pack_data::StarterPackId::kGemini)); |
| } |
| |
| TEST_F(GetDisabledStarterPackIdsTest, PageWithStarterPackPage) { |
| omnibox_feature_configs::ScopedConfigForTesting< |
| omnibox_feature_configs::ContextualSearch> |
| scoped_config; |
| scoped_config.Get().starter_pack_page = true; |
| |
| auto disabled_ids = internal::GetDisabledStarterPackIds( |
| /*ai_mode_enabled=*/true, /*gemini_enabled=*/true); |
| EXPECT_FALSE( |
| disabled_ids.Has(template_url_starter_pack_data::StarterPackId::kPage)); |
| } |
| |
| TEST_F(GetDisabledStarterPackIdsTest, PageWithoutStarterPackPage) { |
| omnibox_feature_configs::ScopedConfigForTesting< |
| omnibox_feature_configs::ContextualSearch> |
| scoped_config; |
| scoped_config.Get().starter_pack_page = false; |
| |
| auto disabled_ids = internal::GetDisabledStarterPackIds( |
| /*ai_mode_enabled=*/true, /*gemini_enabled=*/true); |
| EXPECT_TRUE( |
| disabled_ids.Has(template_url_starter_pack_data::StarterPackId::kPage)); |
| } |