blob: c49ef68fdec2428a01d783f730937e84ddfe1533 [file] [log] [blame]
// Copyright 2021 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/help_app_zero_state_provider.h"
#include <memory>
#include <string>
#include "ash/constants/ash_features.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/ui/app_list/app_list_notifier_impl.h"
#include "chrome/browser/ui/app_list/app_list_notifier_impl_old.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 "chrome/browser/ui/app_list/test/test_app_list_controller.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_profile.h"
#include "chromeos/strings/grit/chromeos_strings.h"
#include "components/prefs/pref_service.h"
#include "ui/base/l10n/l10n_util.h"
namespace app_list {
namespace test {
namespace {
constexpr char kDiscoverTabResultId[] = "help-app://discover";
constexpr char kReleaseNotesResultId[] = "help-app://updates";
void ExpectDiscoverTabChip(ChromeSearchResult* result) {
EXPECT_EQ(kDiscoverTabResultId, result->id());
EXPECT_EQ(
l10n_util::GetStringUTF16(IDS_HELP_APP_DISCOVER_TAB_SUGGESTION_CHIP),
result->title());
EXPECT_EQ(ash::AppListSearchResultType::kZeroStateHelpApp,
result->result_type());
EXPECT_EQ(ash::SearchResultDisplayType::kChip, result->display_type());
}
void ExpectReleaseNotesChip(ChromeSearchResult* result,
int title_id,
ash::SearchResultDisplayType display_type) {
EXPECT_EQ(kReleaseNotesResultId, result->id());
EXPECT_EQ(l10n_util::GetStringUTF16(title_id), result->title());
EXPECT_EQ(ash::AppListSearchResultType::kZeroStateHelpApp,
result->result_type());
EXPECT_EQ(display_type, result->display_type());
}
} // namespace
// Parameterized by whether ProductivityLauncher feature is enabled.
class HelpAppZeroStateProviderTest
: public AppListTestBase,
public ::testing::WithParamInterface<bool> {
public:
HelpAppZeroStateProviderTest() {
if (GetParam()) {
scoped_feature_list_.InitWithFeatures(
/*enabled_features=*/{chromeos::features::kHelpAppDiscoverTab,
chromeos::features::kReleaseNotesSuggestionChip,
ash::features::kProductivityLauncher},
/*disabled_features=*/{});
} else {
scoped_feature_list_.InitWithFeatures(
/*enabled_features=*/{chromeos::features::kHelpAppDiscoverTab,
chromeos::features::
kReleaseNotesSuggestionChip},
/*disabled_features=*/{ash::features::kProductivityLauncher});
}
}
~HelpAppZeroStateProviderTest() override = default;
void SetUp() override {
AppListTestBase::SetUp();
if (GetParam()) {
app_list_notifier_ =
std::make_unique<AppListNotifierImpl>(&app_list_controller_);
} else {
app_list_notifier_ =
std::make_unique<AppListNotifierImplOld>(&app_list_controller_);
}
auto provider = std::make_unique<HelpAppZeroStateProvider>(
profile(), app_list_notifier_.get());
provider_ = provider.get();
search_controller_.AddProvider(0, std::move(provider));
}
ash::SearchResultDisplayType GetExpectedReleaseNotesDisplayType() {
return GetParam() ? ash::SearchResultDisplayType::kContinue
: ash::SearchResultDisplayType::kChip;
}
int GetExpectedReleaseNotesTitleStringId() {
return GetParam() ? IDS_HELP_APP_WHATS_NEW_CONTINUE_TASK_TITLE
: IDS_HELP_APP_WHATS_NEW_SUGGESTION_CHIP;
}
void StartZeroStateSearch() {
search_controller_.StartZeroState(base::DoNothing(), base::TimeDelta());
}
const app_list::Results& GetLatestResults() {
// When productivity launcher (and thus categorical search) is enabled,
// results are managed by the search controller instead of individual search
// providers.
if (GetParam())
return search_controller_.last_results();
return provider_->results();
}
::test::TestAppListController* app_list_controller() {
return &app_list_controller_;
}
ash::AppListNotifier* app_list_notifier() { return app_list_notifier_.get(); }
private:
::test::TestAppListController app_list_controller_;
std::unique_ptr<ash::AppListNotifier> app_list_notifier_;
TestSearchController search_controller_;
HelpAppZeroStateProvider* provider_ = nullptr;
base::test::ScopedFeatureList scoped_feature_list_;
};
INSTANTIATE_TEST_SUITE_P(ProductivityLauncher,
HelpAppZeroStateProviderTest,
testing::Bool());
// Test for empty query.
TEST_P(HelpAppZeroStateProviderTest,
HasNoResultsForEmptyQueryIfTimesLeftToShowIsZero) {
profile()->GetPrefs()->SetInteger(
prefs::kDiscoverTabSuggestionChipTimesLeftToShow, 0);
profile()->GetPrefs()->SetInteger(
prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 0);
StartZeroStateSearch();
EXPECT_TRUE(GetLatestResults().empty());
}
TEST_P(HelpAppZeroStateProviderTest,
ReturnsDiscoverTabChipForEmptyQueryIfTimesLeftIsPositive) {
profile()->GetPrefs()->SetInteger(
prefs::kDiscoverTabSuggestionChipTimesLeftToShow, 1);
profile()->GetPrefs()->SetInteger(
prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 0);
StartZeroStateSearch();
ASSERT_EQ(GetParam() ? 0u : 1u, GetLatestResults().size());
if (GetParam())
return;
ChromeSearchResult* result = GetLatestResults().at(0).get();
ExpectDiscoverTabChip(result);
}
TEST_P(HelpAppZeroStateProviderTest,
ReturnsReleaseNotesChipForEmptyQueryIfTimesLeftIsPositive) {
profile()->GetPrefs()->SetInteger(
prefs::kDiscoverTabSuggestionChipTimesLeftToShow, 0);
profile()->GetPrefs()->SetInteger(
prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 1);
StartZeroStateSearch();
ASSERT_EQ(1u, GetLatestResults().size());
ChromeSearchResult* result = GetLatestResults().at(0).get();
ExpectReleaseNotesChip(result, GetExpectedReleaseNotesTitleStringId(),
GetExpectedReleaseNotesDisplayType());
}
TEST_P(HelpAppZeroStateProviderTest, PrioritizesDiscoverTabChipForEmptyQuery) {
profile()->GetPrefs()->SetInteger(
prefs::kDiscoverTabSuggestionChipTimesLeftToShow, 1);
profile()->GetPrefs()->SetInteger(
prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 1);
StartZeroStateSearch();
ASSERT_EQ(1u, GetLatestResults().size());
ChromeSearchResult* result = GetLatestResults().at(0).get();
if (GetParam()) {
ExpectReleaseNotesChip(result, GetExpectedReleaseNotesTitleStringId(),
GetExpectedReleaseNotesDisplayType());
} else {
ExpectDiscoverTabChip(result);
}
}
TEST_P(HelpAppZeroStateProviderTest,
DecrementsTimesLeftToShowDiscoverTabChipUponShowing) {
profile()->GetPrefs()->SetInteger(
prefs::kDiscoverTabSuggestionChipTimesLeftToShow, 3);
StartZeroStateSearch();
if (GetParam()) {
EXPECT_EQ(0u, GetLatestResults().size());
return;
}
ASSERT_EQ(1u, GetLatestResults().size());
ChromeSearchResult* result = GetLatestResults().at(0).get();
ExpectDiscoverTabChip(result);
app_list_controller()->ShowAppList();
EXPECT_EQ(3, profile()->GetPrefs()->GetInteger(
prefs::kDiscoverTabSuggestionChipTimesLeftToShow));
app_list_notifier()->NotifyResultsUpdated(
ash::AppListNotifier::Location::kChip,
{ash::AppListNotifier::Result(kDiscoverTabResultId,
ash::HELP_APP_UPDATES)});
EXPECT_EQ(3, profile()->GetPrefs()->GetInteger(
prefs::kDiscoverTabSuggestionChipTimesLeftToShow));
ASSERT_TRUE(app_list_notifier()->FireImpressionTimerForTesting(
ash::AppListNotifier::Location::kChip));
EXPECT_EQ(2, profile()->GetPrefs()->GetInteger(
prefs::kDiscoverTabSuggestionChipTimesLeftToShow));
}
TEST_P(HelpAppZeroStateProviderTest,
DecrementsTimesLeftToShowReleaseNotesChipUponShowing) {
profile()->GetPrefs()->SetInteger(
prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 3);
StartZeroStateSearch();
ASSERT_EQ(1u, GetLatestResults().size());
ChromeSearchResult* result = GetLatestResults().at(0).get();
ExpectReleaseNotesChip(result, GetExpectedReleaseNotesTitleStringId(),
GetExpectedReleaseNotesDisplayType());
app_list_controller()->ShowAppList();
EXPECT_EQ(3, profile()->GetPrefs()->GetInteger(
prefs::kReleaseNotesSuggestionChipTimesLeftToShow));
app_list_notifier()->NotifyResultsUpdated(
GetExpectedReleaseNotesDisplayType(),
{ash::AppListNotifier::Result(kReleaseNotesResultId,
ash::HELP_APP_UPDATES)});
if (GetParam()) {
EXPECT_FALSE(app_list_notifier()->FireImpressionTimerForTesting(
ash::AppListNotifier::Location::kContinue));
app_list_notifier()->NotifyContinueSectionVisibilityChanged(
ash::AppListNotifier::Location::kContinue, true);
EXPECT_EQ(3, profile()->GetPrefs()->GetInteger(
prefs::kReleaseNotesSuggestionChipTimesLeftToShow));
}
ASSERT_TRUE(app_list_notifier()->FireImpressionTimerForTesting(
GetExpectedReleaseNotesDisplayType()));
EXPECT_EQ(2, profile()->GetPrefs()->GetInteger(
prefs::kReleaseNotesSuggestionChipTimesLeftToShow));
}
TEST_P(HelpAppZeroStateProviderTest,
ClickingDiscoverTabChipStopsItFromShowing) {
profile()->GetPrefs()->SetInteger(
prefs::kDiscoverTabSuggestionChipTimesLeftToShow, 3);
StartZeroStateSearch();
if (GetParam()) {
EXPECT_EQ(0u, GetLatestResults().size());
return;
}
ASSERT_EQ(1u, GetLatestResults().size());
ChromeSearchResult* result = GetLatestResults().at(0).get();
result->Open(/*event_flags=*/0);
EXPECT_EQ(0, profile()->GetPrefs()->GetInteger(
prefs::kDiscoverTabSuggestionChipTimesLeftToShow));
}
TEST_P(HelpAppZeroStateProviderTest,
ClickingReleaseNotesChipStopsItFromShowing) {
profile()->GetPrefs()->SetInteger(
prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 3);
StartZeroStateSearch();
ChromeSearchResult* result = GetLatestResults().at(0).get();
result->Open(/*event_flags=*/0);
EXPECT_EQ(0, profile()->GetPrefs()->GetInteger(
prefs::kReleaseNotesSuggestionChipTimesLeftToShow));
}
class HelpAppZeroStateProviderWithDiscoverTabDisabledTest
: public HelpAppZeroStateProviderTest {
public:
HelpAppZeroStateProviderWithDiscoverTabDisabledTest() {
scoped_feature_list_.InitWithFeatures(
/*enabled_features=*/{chromeos::features::kReleaseNotesSuggestionChip},
/*disabled_features=*/{chromeos::features::kHelpAppDiscoverTab});
}
~HelpAppZeroStateProviderWithDiscoverTabDisabledTest() override = default;
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
INSTANTIATE_TEST_SUITE_P(ProductivityLauncher,
HelpAppZeroStateProviderWithDiscoverTabDisabledTest,
testing::Bool());
TEST_P(HelpAppZeroStateProviderWithDiscoverTabDisabledTest,
DoesNotReturnDiscoverTabChipForEmptyQuery) {
profile()->GetPrefs()->SetInteger(
prefs::kDiscoverTabSuggestionChipTimesLeftToShow, 1);
profile()->GetPrefs()->SetInteger(
prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 0);
StartZeroStateSearch();
EXPECT_TRUE(GetLatestResults().empty());
}
} // namespace test
} // namespace app_list