blob: 441523a9b7298d63d533ca065eee1c8c2a781584 [file] [log] [blame]
// Copyright 2020 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 "chrome/browser/ui/app_list/search/assistant_text_search_provider.h"
#include <string>
#include "ash/constants/ash_features.h"
#include "ash/public/cpp/app_list/app_list_features.h"
#include "ash/public/cpp/assistant/test_support/mock_assistant_controller.h"
#include "ash/public/cpp/assistant/test_support/mock_assistant_state.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/ui/app_list/app_list_test_util.h"
#include "chrome/browser/ui/app_list/search/chrome_search_result.h"
#include "chrome/browser/ui/app_list/search/test/test_search_controller.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "url/gurl.h"
namespace app_list {
namespace {
using chromeos::assistant::AssistantAllowedState;
// Parameterized by feature ProductivityLauncher.
class AssistantTextSearchProviderTest
: public AppListTestBase,
public ::testing::WithParamInterface<bool> {
public:
AssistantTextSearchProviderTest() {
feature_list_.InitWithFeatureState(ash::features::kProductivityLauncher,
GetParam());
auto search_provider = std::make_unique<AssistantTextSearchProvider>();
search_provider_ = search_provider.get();
search_controller_.AddProvider(0, std::move(search_provider));
}
AssistantTextSearchProviderTest(const AssistantTextSearchProviderTest&) =
delete;
AssistantTextSearchProviderTest& operator=(
const AssistantTextSearchProviderTest&) = delete;
~AssistantTextSearchProviderTest() override = default;
void SendText(const std::string& text) {
search_controller_.StartSearch(base::UTF8ToUTF16(text));
}
ash::MockAssistantState& assistant_state() { return assistant_state_; }
testing::NiceMock<ash::MockAssistantController>& assistant_controller() {
return assistant_controller_;
}
const SearchProvider::Results& LastResults() {
if (app_list_features::IsCategoricalSearchEnabled()) {
return search_controller_.last_results();
} else {
return search_provider_->results();
}
}
void VerifyResultAt(size_t index, const std::string& text) {
EXPECT_LT(index, LastResults().size());
auto* result = LastResults().at(0).get();
EXPECT_EQ(result->title(), base::UTF8ToUTF16(text));
EXPECT_EQ(result->id(), "googleassistant_text://" + text);
EXPECT_EQ(result->accessible_name(),
base::UTF8ToUTF16(text + ", Google Assistant"));
EXPECT_EQ(result->result_type(),
ash::AppListSearchResultType::kAssistantText);
EXPECT_EQ(result->display_type(), ash::SearchResultDisplayType::kList);
}
private:
base::test::ScopedFeatureList feature_list_;
ash::MockAssistantState assistant_state_;
testing::NiceMock<ash::MockAssistantController> assistant_controller_;
TestSearchController search_controller_;
AssistantTextSearchProvider* search_provider_ = nullptr;
};
INSTANTIATE_TEST_SUITE_P(ProductivityLauncher,
AssistantTextSearchProviderTest,
testing::Bool());
// Tests -----------------------------------------------------------------------
// TODO(crbug.com/1258415): Remove this test when the productivity launcher is
// enabled.
TEST_P(AssistantTextSearchProviderTest, ShouldNotProvideResultForEmptyQuery) {
EXPECT_TRUE(LastResults().empty());
SendText("testing");
// Should now have a search result with title "testing".
EXPECT_EQ(LastResults().size(), 1u);
VerifyResultAt(0, "testing");
// If the productivity launcher is enabled, search_provider_.Start() is
// guaranteed to be called with a non-empty query. So this test only applies
// to the classic launcher.
bool productivity_launcher_enabled = GetParam();
if (!productivity_launcher_enabled) {
SendText("");
// Should have no search results.
EXPECT_TRUE(LastResults().empty());
}
}
TEST_P(AssistantTextSearchProviderTest,
ShouldUpdateResultsWhenAssistantSettingsChange) {
SendText("testing");
EXPECT_EQ(LastResults().size(), 1u);
assistant_state().SetSettingsEnabled(false);
EXPECT_TRUE(LastResults().empty());
assistant_state().SetSettingsEnabled(true);
EXPECT_EQ(LastResults().size(), 1u);
}
TEST_P(AssistantTextSearchProviderTest,
ShouldUpdateResultsWhenAssistantAllowedStateChanges) {
SendText("testing");
// Test all possible Assistant allowed states.
for (int i = 0; i < static_cast<int>(AssistantAllowedState::MAX_VALUE); ++i) {
if (i == static_cast<int>(AssistantAllowedState::ALLOWED))
continue;
// When Assistant becomes not-allowed, results should be cleared.
assistant_state().SetAllowedState(static_cast<AssistantAllowedState>(i));
EXPECT_TRUE(LastResults().empty());
// When Assistant becomes allowed, we should again have a single result.
assistant_state().SetAllowedState(AssistantAllowedState::ALLOWED);
EXPECT_EQ(1u, LastResults().size());
}
}
TEST_P(AssistantTextSearchProviderTest, ShouldDeepLinkAssistantQuery) {
SendText("testing query");
GURL url;
bool in_background = true;
bool from_user = true;
EXPECT_CALL(assistant_controller(), OpenUrl)
.WillOnce(testing::DoAll(testing::SaveArg<0>(&url),
testing::SaveArg<1>(&in_background),
testing::SaveArg<2>(&from_user)));
LastResults().at(0)->Open(/*event_flags=*/0);
EXPECT_EQ(url, GURL("googleassistant://send-query?q=testing+query"));
EXPECT_FALSE(in_background);
EXPECT_FALSE(from_user);
}
} // namespace
} // namespace app_list