| // 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 <memory> |
| #include <string> |
| |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/search_engines/template_url_service_factory.h" |
| #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_window.h" |
| #include "chrome/browser/ui/location_bar/location_bar.h" |
| #include "chrome/browser/ui/omnibox/omnibox_controller.h" |
| #include "chrome/browser/ui/omnibox/omnibox_edit_model.h" |
| #include "chrome/browser/ui/omnibox/omnibox_view.h" |
| #include "chrome/browser/ui/search/omnibox_utils.h" |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "chrome/test/base/search_test_utils.h" |
| #include "chrome/test/base/ui_test_utils.h" |
| #include "components/omnibox/browser/autocomplete_controller.h" |
| #include "components/omnibox/browser/autocomplete_input.h" |
| #include "components/omnibox/browser/autocomplete_match.h" |
| #include "components/omnibox/browser/autocomplete_result.h" |
| #include "components/omnibox/browser/enterprise_search_aggregator_suggestions_service.h" |
| #include "components/omnibox/common/omnibox_feature_configs.h" |
| #include "components/policy/core/browser/browser_policy_connector.h" |
| #include "components/policy/core/common/mock_configuration_policy_provider.h" |
| #include "components/policy/policy_constants.h" |
| #include "components/search_engines/enterprise/search_aggregator_policy_handler.h" |
| #include "components/search_engines/search_engine_type.h" |
| #include "components/search_engines/template_url_service.h" |
| #include "content/public/test/browser_test.h" |
| #include "net/test/embedded_test_server/controllable_http_response.h" |
| #include "third_party/metrics_proto/omnibox_event.pb.h" |
| |
| using testing::AllOf; |
| using testing::Field; |
| |
| namespace { |
| |
| using ui_test_utils::WaitForAutocompleteDone; |
| |
| const char kSearchAggregatorPolicyIconUrl[] = |
| "https://www.aggregator.com/icon.png"; |
| const char16_t kSearchAggregatorPolicyKeyword[] = u"aggregator"; |
| const char16_t kSearchAggregatorPolicyName[] = u"Aggregator"; |
| const char kSearchAggregatorPolicySearchUrl[] = |
| "https://www.aggregator.com/search?q={searchTerms}"; |
| const char kSearchAggregatorPolicySuggestUrl[] = |
| "https://www.aggregator.com/suggest"; |
| |
| const char kSearchAggregatorPolicySuggestPath[] = "/suggest"; |
| const std::u16string kSearchInput = u"@aggregator john d"; |
| |
| const std::string kGoodJsonResponse = base::StringPrintf( |
| R"({ |
| "querySuggestions": [ |
| { |
| "suggestion": "John's Demise", |
| "score": 0.1, |
| "dataStore": [] |
| } |
| ], |
| "peopleSuggestions": [ |
| { |
| "suggestion": "john@example.com", |
| "document": { |
| "name": "sundar", |
| "derivedStructData": { |
| "name": { |
| "display_name_lower": "john doe", |
| "familyName": "Doe", |
| "givenName": "John", |
| "given_name_lower": "john", |
| "family_name_lower": "doe", |
| "displayName": "John Doe", |
| "userName": "john" |
| }, |
| "emails": [ |
| { |
| "type": "primary", |
| "value": "john@example.com" |
| } |
| ], |
| "displayPhoto": { |
| "url": "https://example.com/image.png" |
| } |
| } |
| }, |
| "destinationUri": "https://www.example.com/people/john", |
| "score": 0.8, |
| "dataStore": "project 1" |
| } |
| ], |
| "contentSuggestions": [ |
| { |
| "suggestion": "John's Document", |
| "contentType": "THIRD_PARTY", |
| "document": { |
| "name": "Document 2", |
| "structData": { |
| "title": "John's Document", |
| "uri": "www.example.com" |
| }, |
| "derivedStructData": { |
| "source_type": "jira", |
| "entity_type": "issue", |
| "title": "John's Document", |
| "link": "https://www.example.co.uk" |
| } |
| }, |
| "destinationUri": "https://www.example.com/", |
| "score": 0.4, |
| "dataStore": "project2" |
| } |
| ] |
| })"); |
| |
| } // namespace |
| |
| class OmniboxSearchAggregatorTest : public InProcessBrowserTest { |
| public: |
| OmniboxSearchAggregatorTest() = default; |
| ~OmniboxSearchAggregatorTest() override = default; |
| |
| void SetUp() override { |
| policy_provider_.SetDefaultReturns( |
| /*is_initialization_complete_return=*/true, |
| /*is_first_policy_load_complete_return=*/true); |
| policy::BrowserPolicyConnector::SetPolicyProviderForTesting( |
| &policy_provider_); |
| InProcessBrowserTest::SetUp(); |
| } |
| |
| void SetUpOnMainThread() override { |
| InProcessBrowserTest::SetUpOnMainThread(); |
| |
| // The omnibox suggestion results depend on the TemplateURLService being |
| // loaded. Make sure it is loaded so that the autocomplete results are |
| // consistent. |
| search_test_utils::WaitForTemplateURLServiceToLoad( |
| TemplateURLServiceFactory::GetForProfile(browser()->profile())); |
| |
| // Prevent the stop timer from killing the hints fetch early, which might |
| // cause test flakiness due to timeout. |
| controller()->SetStartStopTimerDurationForTesting(base::Seconds(30)); |
| |
| // Setup an identity profile. |
| identity_test_env_adaptor_ = |
| std::make_unique<IdentityTestEnvironmentProfileAdaptor>( |
| browser()->profile()); |
| identity_test_env()->SetPrimaryAccount("test@mail.com", |
| signin::ConsentLevel::kSignin); |
| identity_test_env()->SetRefreshTokenForPrimaryAccount(); |
| identity_test_env()->SetAutomaticIssueOfAccessTokens(true); |
| |
| // Initial the HTTPS embedded test server. |
| https_test_server_ = std::make_unique<net::EmbeddedTestServer>( |
| net::EmbeddedTestServer::TYPE_HTTPS); |
| https_test_server_->RegisterRequestHandler(base::BindRepeating( |
| &OmniboxSearchAggregatorTest::HandleRequest, base::Unretained(this))); |
| } |
| |
| void SetUpInProcessBrowserTestFixture() override { |
| create_services_subscription_ = |
| BrowserContextDependencyManager::GetInstance() |
| ->RegisterCreateServicesCallbackForTesting( |
| base::BindRepeating(&OmniboxSearchAggregatorTest:: |
| OnWillCreateBrowserContextServices, |
| base::Unretained(this))); |
| } |
| |
| void OnWillCreateBrowserContextServices(content::BrowserContext* context) { |
| IdentityTestEnvironmentProfileAdaptor:: |
| SetIdentityTestEnvironmentFactoriesOnBrowserContext(context); |
| } |
| |
| protected: |
| std::unique_ptr<net::test_server::HttpResponse> HandleRequest( |
| const net::test_server::HttpRequest& request) { |
| // The kSuggestUrl will be hit by GET request from SearchProvider, we could |
| // ignore it for SearchAggregator tests. |
| if (request.relative_url == kSearchAggregatorPolicySuggestPath && |
| request.method == net::test_server::METHOD_GET) { |
| auto http_response = |
| std::make_unique<net::test_server::BasicHttpResponse>(); |
| http_response->set_code(net::HTTP_NOT_FOUND); |
| return std::move(http_response); |
| } |
| return nullptr; |
| } |
| |
| base::Value CreateEnterpriseSearchAggregatorPolicyValue( |
| const std::string& suggest_url = kSearchAggregatorPolicySuggestUrl) { |
| base::Value::Dict policy_value; |
| policy_value = base::Value::Dict() |
| .Set(policy::SearchAggregatorPolicyHandler::kIconUrl, |
| kSearchAggregatorPolicyIconUrl) |
| .Set(policy::SearchAggregatorPolicyHandler::kShortcut, |
| kSearchAggregatorPolicyKeyword) |
| .Set(policy::SearchAggregatorPolicyHandler::kName, |
| kSearchAggregatorPolicyName) |
| .Set(policy::SearchAggregatorPolicyHandler::kSearchUrl, |
| kSearchAggregatorPolicySearchUrl) |
| .Set(policy::SearchAggregatorPolicyHandler::kSuggestUrl, |
| suggest_url); |
| return base::Value(std::move(policy_value)); |
| } |
| |
| AutocompleteController* controller() { |
| return browser() |
| ->window() |
| ->GetLocationBar() |
| ->GetOmniboxView() |
| ->controller() |
| ->autocomplete_controller(); |
| } |
| |
| // Override embedded_test_server() with a variant that uses HTTPS. |
| net::EmbeddedTestServer* embedded_test_server() { |
| return https_test_server_.get(); |
| } |
| |
| policy::MockConfigurationPolicyProvider* policy_provider() { |
| return &policy_provider_; |
| } |
| |
| signin::IdentityTestEnvironment* identity_test_env() { |
| return identity_test_env_adaptor_->identity_test_env(); |
| } |
| |
| omnibox_feature_configs::ScopedConfigForTesting< |
| omnibox_feature_configs::SearchAggregatorProvider> |
| scoped_config_; |
| |
| private: |
| testing::NiceMock<policy::MockConfigurationPolicyProvider> policy_provider_; |
| // SearchAggregatorPolicy requires HTTPS scheme. |
| std::unique_ptr<net::EmbeddedTestServer> https_test_server_; |
| base::CallbackListSubscription create_services_subscription_; |
| std::unique_ptr<IdentityTestEnvironmentProfileAdaptor> |
| identity_test_env_adaptor_; |
| }; |
| |
| class OmniboxSearchAggregatorSingleRequestTest |
| : public OmniboxSearchAggregatorTest { |
| public: |
| void SetUp() override { |
| scoped_config_.Get().multiple_requests = false; |
| OmniboxSearchAggregatorTest::SetUp(); |
| } |
| }; |
| |
| // TODO(crbug.com/425120649) Flaky. |
| IN_PROC_BROWSER_TEST_F(OmniboxSearchAggregatorSingleRequestTest, |
| DISABLED_GoodJsonResponse) { |
| net::test_server::ControllableHttpResponse search_aggregator_response( |
| embedded_test_server(), kSearchAggregatorPolicySuggestPath); |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| |
| base::Value policy_value = CreateEnterpriseSearchAggregatorPolicyValue( |
| embedded_test_server() |
| ->GetURL(kSearchAggregatorPolicySuggestPath) |
| .spec()); |
| policy::PolicyMap policies; |
| policies.Set(policy::key::kEnterpriseSearchAggregatorSettings, |
| policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, |
| policy::POLICY_SOURCE_CLOUD, std::move(policy_value), nullptr); |
| policy_provider()->UpdateChromePolicy(policies); |
| |
| AutocompleteInput input( |
| kSearchInput, metrics::OmniboxEventProto::NTP, |
| ChromeAutocompleteSchemeClassifier(browser()->profile())); |
| input.set_keyword_mode_entry_method(metrics::OmniboxEventProto::TAB); |
| controller()->Start(input); |
| |
| // Respond for SearchAggregator request. |
| search_aggregator_response.WaitForRequest(); |
| EXPECT_EQ(search_aggregator_response.http_request()->method, |
| net::test_server::METHOD_POST); |
| EXPECT_EQ( |
| search_aggregator_response.http_request()->content, |
| base::StringPrintf(R"({"experimentIds":["%s"],)" |
| R"("query":"john d","suggestionTypes":[1,2,3,5]})", |
| kEnterpriseSearchAggregatorExperimentId)); |
| search_aggregator_response.Send(net::HTTP_OK, "application/json", |
| kGoodJsonResponse); |
| search_aggregator_response.Done(); |
| |
| // Wait for the autocomplete controller to finish. |
| WaitForAutocompleteDone(browser()); |
| EXPECT_TRUE(controller()->done()); |
| const AutocompleteResult& result = controller()->result(); |
| ASSERT_FALSE(result.empty()); |
| EXPECT_EQ(result.size(), 4u); |
| |
| EXPECT_THAT( |
| std::vector<AutocompleteMatch>(result.begin(), result.end()), |
| testing::ElementsAreArray(std::vector< |
| testing::Matcher<AutocompleteMatch>>({ |
| AllOf(Field(&AutocompleteMatch::type, |
| AutocompleteMatchType::SEARCH_OTHER_ENGINE), |
| Field(&AutocompleteMatch::contents, u"john d"), |
| Field(&AutocompleteMatch::description, u"Aggregator Search"), |
| Field(&AutocompleteMatch::destination_url, |
| GURL("https://www.aggregator.com/search?q=john+d"))), |
| AllOf( |
| Field(&AutocompleteMatch::type, |
| AutocompleteMatchType::SEARCH_SUGGEST), |
| Field(&AutocompleteMatch::contents, u"John's Demise"), |
| Field(&AutocompleteMatch::description, u""), |
| Field( |
| &AutocompleteMatch::destination_url, |
| GURL("https://www.aggregator.com/search?q=John%27s+Demise"))), |
| AllOf(Field(&AutocompleteMatch::type, |
| AutocompleteMatchType::NAVSUGGEST), |
| Field(&AutocompleteMatch::contents, u"Aggregator People"), |
| Field(&AutocompleteMatch::description, u"John Doe"), |
| Field(&AutocompleteMatch::destination_url, |
| GURL("https://www.example.com/people/john")), |
| Field(&AutocompleteMatch::image_url, |
| GURL("https://example.com/image.png"))), |
| AllOf(Field(&AutocompleteMatch::type, |
| AutocompleteMatchType::NAVSUGGEST), |
| Field(&AutocompleteMatch::contents, u"Jira Issue"), |
| Field(&AutocompleteMatch::description, u"John's Document"), |
| Field(&AutocompleteMatch::destination_url, |
| GURL("https://www.example.com/"))), |
| }))); |
| } |
| |
| // TODO(crbug.com/425120649): Flaky. |
| IN_PROC_BROWSER_TEST_F(OmniboxSearchAggregatorTest, |
| DISABLED_GoodJsonResponseMultipleRequests) { |
| std::vector<std::unique_ptr<net::test_server::ControllableHttpResponse>> |
| requests = {}; |
| for (size_t i = 0; i < 3; ++i) { |
| requests.push_back( |
| std::make_unique<net::test_server::ControllableHttpResponse>( |
| embedded_test_server(), kSearchAggregatorPolicySuggestPath)); |
| } |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| |
| base::Value policy_value = CreateEnterpriseSearchAggregatorPolicyValue( |
| embedded_test_server() |
| ->GetURL(kSearchAggregatorPolicySuggestPath) |
| .spec()); |
| policy::PolicyMap policies; |
| policies.Set(policy::key::kEnterpriseSearchAggregatorSettings, |
| policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, |
| policy::POLICY_SOURCE_CLOUD, std::move(policy_value), nullptr); |
| policy_provider()->UpdateChromePolicy(policies); |
| |
| AutocompleteInput input( |
| kSearchInput, metrics::OmniboxEventProto::NTP, |
| ChromeAutocompleteSchemeClassifier(browser()->profile())); |
| input.set_keyword_mode_entry_method(metrics::OmniboxEventProto::TAB); |
| controller()->Start(input); |
| |
| std::vector<std::string> request_bodies = {}; |
| for (auto& request : requests) { |
| request->WaitForRequest(); |
| EXPECT_EQ(request->http_request()->method, net::test_server::METHOD_POST); |
| request_bodies.push_back(request->http_request()->content); |
| } |
| constexpr char expected_request[] = |
| R"({"experimentIds":["%s"],)" |
| R"("query":"john d","suggestionTypes":[%s]})"; |
| // Expect unordered because there's no guarantee what order the service starts |
| // the requests. |
| EXPECT_THAT( |
| request_bodies, |
| testing::UnorderedElementsAre( |
| base::StringPrintf(expected_request, |
| kEnterpriseSearchAggregatorExperimentId, "1"), |
| base::StringPrintf(expected_request, |
| kEnterpriseSearchAggregatorExperimentId, "2"), |
| base::StringPrintf(expected_request, |
| kEnterpriseSearchAggregatorExperimentId, "3,5"))); |
| for (auto& request : requests) { |
| request->Send(net::HTTP_OK, "application/json", kGoodJsonResponse); |
| request->Done(); |
| } |
| |
| // Wait for the autocomplete controller to finish. |
| WaitForAutocompleteDone(browser()); |
| EXPECT_TRUE(controller()->done()); |
| const AutocompleteResult& result = controller()->result(); |
| ASSERT_FALSE(result.empty()); |
| |
| // When making multiple async requests, only check first match. |
| EXPECT_THAT( |
| std::vector<AutocompleteMatch>(result.begin(), result.begin() + 1), |
| testing::ElementsAreArray( |
| std::vector<testing::Matcher<AutocompleteMatch>>({ |
| AllOf( |
| Field(&AutocompleteMatch::type, |
| AutocompleteMatchType::SEARCH_OTHER_ENGINE), |
| Field(&AutocompleteMatch::contents, u"john d"), |
| Field(&AutocompleteMatch::description, u"Aggregator Search"), |
| Field(&AutocompleteMatch::destination_url, |
| GURL("https://www.aggregator.com/search?q=john+d"))), |
| }))); |
| } |
| |
| // TODO(crbug.com/425120649) Flaky. |
| IN_PROC_BROWSER_TEST_F(OmniboxSearchAggregatorSingleRequestTest, |
| DISABLED_RedirectedResponse) { |
| net::test_server::ControllableHttpResponse redirect_response( |
| embedded_test_server(), kSearchAggregatorPolicySuggestPath); |
| const std::string redirected_path = "/suggest-redirect"; |
| net::test_server::ControllableHttpResponse search_aggregator_response( |
| embedded_test_server(), redirected_path); |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| |
| base::Value policy_value = CreateEnterpriseSearchAggregatorPolicyValue( |
| embedded_test_server() |
| ->GetURL(kSearchAggregatorPolicySuggestPath) |
| .spec()); |
| policy::PolicyMap policies; |
| policies.Set(policy::key::kEnterpriseSearchAggregatorSettings, |
| policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, |
| policy::POLICY_SOURCE_CLOUD, std::move(policy_value), nullptr); |
| policy_provider()->UpdateChromePolicy(policies); |
| |
| AutocompleteInput input( |
| kSearchInput, metrics::OmniboxEventProto::NTP, |
| ChromeAutocompleteSchemeClassifier(browser()->profile())); |
| input.set_keyword_mode_entry_method(metrics::OmniboxEventProto::TAB); |
| controller()->Start(input); |
| |
| // Redirect response. |
| redirect_response.WaitForRequest(); |
| EXPECT_EQ(redirect_response.http_request()->method, |
| net::test_server::METHOD_POST); |
| redirect_response.Send(net::HTTP_MOVED_PERMANENTLY, "text/html", |
| /* content = */ "", /* cookies = */ {}, |
| {base::StrCat({"Location: ", redirected_path})}); |
| redirect_response.Done(); |
| // Respond for SearchAggregator request. |
| search_aggregator_response.WaitForRequest(); |
| EXPECT_EQ(search_aggregator_response.http_request()->method, |
| net::test_server::METHOD_GET); |
| search_aggregator_response.Send(net::HTTP_OK, "application/json", |
| kGoodJsonResponse); |
| search_aggregator_response.Done(); |
| |
| // Wait for the autocomplete controller to finish. |
| WaitForAutocompleteDone(browser()); |
| EXPECT_TRUE(controller()->done()); |
| const AutocompleteResult& result = controller()->result(); |
| ASSERT_FALSE(result.empty()); |
| EXPECT_EQ(result.size(), 4u); |
| } |
| |
| class OmniboxSearchAggregatorHTTPErrorTest |
| : public OmniboxSearchAggregatorTest, |
| public ::testing::WithParamInterface<net::HttpStatusCode> { |
| public: |
| net::HttpStatusCode GetHttpStatusCode() { return GetParam(); } |
| void SetUpOnMainThread() override { |
| OmniboxSearchAggregatorTest::SetUpOnMainThread(); |
| |
| // Handle search aggregator response |
| search_aggregator_people_response_ = |
| std::make_unique<net::test_server::ControllableHttpResponse>( |
| embedded_test_server(), kSearchAggregatorPolicySuggestPath); |
| search_aggregator_content_response_ = |
| std::make_unique<net::test_server::ControllableHttpResponse>( |
| embedded_test_server(), kSearchAggregatorPolicySuggestPath); |
| search_aggregator_query_response_ = |
| std::make_unique<net::test_server::ControllableHttpResponse>( |
| embedded_test_server(), kSearchAggregatorPolicySuggestPath); |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| |
| InitSearchAggregatorPolicyConfig(); |
| } |
| |
| protected: |
| void InitSearchAggregatorPolicyConfig() { |
| base::Value policy_value = CreateEnterpriseSearchAggregatorPolicyValue( |
| embedded_test_server() |
| ->GetURL(kSearchAggregatorPolicySuggestPath) |
| .spec()); |
| policy::PolicyMap policies; |
| policies.Set(policy::key::kEnterpriseSearchAggregatorSettings, |
| policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, |
| policy::POLICY_SOURCE_CLOUD, std::move(policy_value), nullptr); |
| policy_provider()->UpdateChromePolicy(policies); |
| } |
| |
| net::test_server::ControllableHttpResponse* |
| search_aggregator_people_response() { |
| return search_aggregator_people_response_.get(); |
| } |
| net::test_server::ControllableHttpResponse* |
| search_aggregator_content_response() { |
| return search_aggregator_content_response_.get(); |
| } |
| net::test_server::ControllableHttpResponse* |
| search_aggregator_query_response() { |
| return search_aggregator_query_response_.get(); |
| } |
| |
| private: |
| std::unique_ptr<net::test_server::ControllableHttpResponse> |
| search_aggregator_people_response_; |
| std::unique_ptr<net::test_server::ControllableHttpResponse> |
| search_aggregator_content_response_; |
| std::unique_ptr<net::test_server::ControllableHttpResponse> |
| search_aggregator_query_response_; |
| }; |
| |
| // TODO(crbug.com/421836646): Flaky on `BUILDFLAG(IS_WIN)` |
| // TODO(crbug.com/425120649): Flaky. |
| IN_PROC_BROWSER_TEST_P(OmniboxSearchAggregatorHTTPErrorTest, |
| DISABLED_HTTPErrorResponse) { |
| AutocompleteInput input( |
| kSearchInput, metrics::OmniboxEventProto::NTP, |
| ChromeAutocompleteSchemeClassifier(browser()->profile())); |
| input.set_keyword_mode_entry_method(metrics::OmniboxEventProto::TAB); |
| controller()->Start(input); |
| |
| // Respond to the first SearchAggregator request (1 - query). |
| search_aggregator_people_response()->WaitForRequest(); |
| EXPECT_EQ(search_aggregator_people_response()->http_request()->method, |
| net::test_server::METHOD_POST); |
| EXPECT_EQ(search_aggregator_people_response()->http_request()->content, |
| base::StringPrintf(R"({"experimentIds":["%s"],)" |
| R"("query":"john d","suggestionTypes":[1]})", |
| kEnterpriseSearchAggregatorExperimentId)); |
| search_aggregator_people_response()->Send(GetHttpStatusCode()); |
| search_aggregator_people_response()->Done(); |
| |
| // Respond to the second SearchAggregator request (2 - people). |
| search_aggregator_content_response()->WaitForRequest(); |
| EXPECT_EQ(search_aggregator_content_response()->http_request()->method, |
| net::test_server::METHOD_POST); |
| EXPECT_EQ(search_aggregator_content_response()->http_request()->content, |
| base::StringPrintf(R"({"experimentIds":["%s"],)" |
| R"("query":"john d","suggestionTypes":[2]})", |
| kEnterpriseSearchAggregatorExperimentId)); |
| search_aggregator_content_response()->Send(GetHttpStatusCode()); |
| search_aggregator_content_response()->Done(); |
| |
| // Respond to the third SearchAggregator request (3,5 - content/Google |
| // Workspace). |
| search_aggregator_query_response()->WaitForRequest(); |
| EXPECT_EQ(search_aggregator_query_response()->http_request()->method, |
| net::test_server::METHOD_POST); |
| EXPECT_EQ(search_aggregator_query_response()->http_request()->content, |
| base::StringPrintf(R"({"experimentIds":["%s"],)" |
| R"("query":"john d","suggestionTypes":[3,5]})", |
| kEnterpriseSearchAggregatorExperimentId)); |
| search_aggregator_query_response()->Send(GetHttpStatusCode()); |
| search_aggregator_query_response()->Done(); |
| |
| // Wait for the autocomplete controller to finish. |
| WaitForAutocompleteDone(browser()); |
| EXPECT_TRUE(controller()->done()); |
| const AutocompleteResult& result = controller()->result(); |
| ASSERT_FALSE(result.empty()); |
| EXPECT_EQ(result.size(), 1u); |
| EXPECT_THAT( |
| result.default_match(), |
| AllOf(Field(&AutocompleteMatch::type, |
| AutocompleteMatchType::SEARCH_OTHER_ENGINE), |
| Field(&AutocompleteMatch::contents, u"john d"), |
| Field(&AutocompleteMatch::description, u"Aggregator Search"), |
| Field(&AutocompleteMatch::destination_url, |
| GURL("https://www.aggregator.com/search?q=john+d")))); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P( |
| All, |
| OmniboxSearchAggregatorHTTPErrorTest, |
| ::testing::Values(net::HTTP_BAD_REQUEST, |
| net::HTTP_FORBIDDEN, |
| net::HTTP_NOT_FOUND, |
| net::HTTP_METHOD_NOT_ALLOWED, |
| net::HTTP_INTERNAL_SERVER_ERROR, |
| net::HTTP_BAD_GATEWAY), |
| [](const testing::TestParamInfo<net::HttpStatusCode>& info) { |
| return base::NumberToString(info.param); |
| }); |