blob: da10f26d487990748c5ac983595b2d685afb280c [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/api/search/search_api.h"
#include "base/memory/scoped_refptr.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/sessions/session_tab_helper_factory.h"
#include "chrome/test/base/search_test_utils.h"
#include "chrome/test/base/test_browser_window.h"
#include "components/search_engines/template_url_service.h"
#include "content/public/test/web_contents_tester.h"
#include "extensions/browser/api_test_utils.h"
#include "extensions/common/extension_builder.h"
namespace extensions {
namespace {
// Creates an extension with "search" permission.
scoped_refptr<const Extension> CreateSearchExtension() {
return ExtensionBuilder("Extension with search permission")
.AddPermission("search")
.Build();
}
scoped_refptr<SearchQueryFunction> CreateSearchFunction(
scoped_refptr<const Extension> extension) {
auto function = base::MakeRefCounted<SearchQueryFunction>();
function->set_extension(extension.get());
function->set_has_callback(true);
return function;
}
std::unique_ptr<content::WebContents> CreateWebContents(Browser* browser) {
GURL url("https://example.com");
std::unique_ptr<content::WebContents> contents(
content::WebContentsTester::CreateTestWebContents(browser->profile(),
nullptr));
content::WebContents* raw_contents = contents.get();
browser->tab_strip_model()->AppendWebContents(std::move(contents), true);
EXPECT_EQ(browser->tab_strip_model()->GetActiveWebContents(), raw_contents);
content::WebContentsTester* web_contents_tester =
content::WebContentsTester::For(raw_contents);
web_contents_tester->NavigateAndCommit(url);
CreateSessionServiceTabHelper(raw_contents);
return contents;
}
} // namespace
class SearchApiUnitTest : public ExtensionServiceTestBase {
protected:
SearchApiUnitTest() = default;
~SearchApiUnitTest() override = default;
Browser* browser() { return browser_.get(); }
TestBrowserWindow* browser_window() { return browser_window_.get(); }
TabStripModel* GetTabStripModel() { return browser_->tab_strip_model(); }
extensions::SearchQueryFunction* function() { return function_.get(); }
void RunFunctionAndExpectError(const std::string& input,
const base::StringPiece expected);
private:
void SetUp() override;
void TearDown() override;
// The browser (and accompanying window).
std::unique_ptr<TestBrowserWindow> browser_window_;
std::unique_ptr<Browser> browser_;
scoped_refptr<extensions::SearchQueryFunction> function_;
};
void SearchApiUnitTest::SetUp() {
ExtensionServiceTestBase::SetUp();
InitializeEmptyExtensionService();
// Force TabManager/TabLifecycleUnitSource creation.
g_browser_process->GetTabManager();
browser_window_ = std::make_unique<TestBrowserWindow>();
Browser::CreateParams params(profile(), /*user_gesture*/ true);
params.type = Browser::TYPE_NORMAL;
params.window = browser_window_.get();
browser_ = std::unique_ptr<Browser>(Browser::Create(params));
// Mock TemplateURLService.
auto* template_url_service = static_cast<TemplateURLService*>(
TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
profile(),
base::BindRepeating(&TemplateURLServiceFactory::BuildInstanceFor)));
search_test_utils::WaitForTemplateURLServiceToLoad(template_url_service);
scoped_refptr<const Extension> extension = CreateSearchExtension();
function_ = CreateSearchFunction(extension);
CreateWebContents(browser());
}
void SearchApiUnitTest::TearDown() {
browser_->tab_strip_model()->CloseAllTabs();
browser_ = nullptr;
browser_window_ = nullptr;
ExtensionServiceTestBase::TearDown();
}
void SearchApiUnitTest::RunFunctionAndExpectError(
const std::string& input,
const base::StringPiece expected) {
auto result = api_test_utils::RunFunctionAndReturnError(function(), input,
browser()->profile());
EXPECT_EQ(expected, result);
}
// Test for error if search field is empty string.
TEST_F(SearchApiUnitTest, QueryEmpty) {
RunFunctionAndExpectError(R"([{"text": ""}])", "Empty text parameter.");
}
// Test for error if both disposition and tabId are populated.
TEST_F(SearchApiUnitTest, DispositionAndTabIDValid) {
RunFunctionAndExpectError(
R"([{"text": "1", "disposition": "NEW_TAB", "tabId": 1}])",
"Cannot set both 'disposition' and 'tabId'.");
}
// Test for error if both disposition and tabId are populated.
TEST_F(SearchApiUnitTest, InvalidTabId) {
RunFunctionAndExpectError(R"([{"text": "1", "tabId": -1}])",
"No tab with id: -1.");
}
// Test for error if missing browser context.
TEST_F(SearchApiUnitTest, NoActiveBrowser) {
auto result = api_test_utils::RunFunctionAndReturnError(
function(), R"([{"text": "1"}])", nullptr);
EXPECT_EQ("No active browser.", result);
}
} // namespace extensions