blob: 7f2e748a5f9601eab226adc0c5fa39206af8d2ee [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/views/toolbar/chrome_labs_button.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/about_flags.h"
#include "chrome/browser/ui/toolbar/chrome_labs_prefs.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/test_with_browser_view.h"
#include "chrome/browser/ui/views/toolbar/chrome_labs_bubble_view.h"
#include "chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/browser/unexpire_flags.h"
#include "components/flags_ui/feature_entry_macros.h"
#include "ui/events/event_utils.h"
#include "ui/views/controls/dot_indicator.h"
#include "ui/views/test/button_test_api.h"
#include "ui/views/test/widget_test.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/constants/ash_switches.h"
#include "base/command_line.h"
#include "base/memory/ptr_util.h"
#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/ash/ownership/owner_settings_service_ash.h"
#include "chrome/browser/ash/ownership/owner_settings_service_ash_factory.h"
#include "chrome/common/pref_names.h"
#include "components/user_manager/scoped_user_manager.h"
#endif
namespace {
#if BUILDFLAG(IS_CHROMEOS_ASH)
constexpr char kFakeUserName[] = "test@example.com";
constexpr char kFakeGaiaId[] = "1234567890";
#endif
const char kFirstTestFeatureId[] = "feature-1";
const base::Feature kTestFeature1{"FeatureName1",
base::FEATURE_ENABLED_BY_DEFAULT};
const char kSecondTestFeatureId[] = "feature-2";
const base::Feature kTestFeature2{"FeatureName2",
base::FEATURE_DISABLED_BY_DEFAULT};
const char kExpiredFlagTestFeatureId[] = "expired-feature";
const base::Feature kTestFeatureExpired{"Expired",
base::FEATURE_DISABLED_BY_DEFAULT};
} // namespace
class ChromeLabsButtonTest : public TestWithBrowserView {
public:
ChromeLabsButtonTest()
:
#if BUILDFLAG(IS_CHROMEOS_ASH)
user_manager_(new ash::FakeChromeUserManager()),
user_manager_enabler_(base::WrapUnique(user_manager_)),
#endif
scoped_feature_entries_({{kFirstTestFeatureId, "", "",
flags_ui::FlagsState::GetCurrentPlatform(),
FEATURE_VALUE_TYPE(kTestFeature1)}}) {
}
void SetUp() override {
#if BUILDFLAG(IS_CHROMEOS_ASH)
const AccountId account_id(
AccountId::FromUserEmailGaiaId(kFakeUserName, kFakeGaiaId));
user_manager_->AddUser(account_id);
user_manager_->LoginUser(account_id);
#endif
scoped_feature_list_.InitAndEnableFeature(features::kChromeLabs);
std::vector<LabInfo> test_feature_info = {
{kFirstTestFeatureId, u"", u"", "", version_info::Channel::STABLE}};
scoped_chrome_labs_model_data_.SetModelDataForTesting(test_feature_info);
TestWithBrowserView::SetUp();
profile()->GetPrefs()->SetBoolean(chrome_labs_prefs::kBrowserLabsEnabled,
true);
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
protected:
ash::FakeChromeUserManager* user_manager_;
user_manager::ScopedUserManager user_manager_enabler_;
#endif
private:
about_flags::testing::ScopedFeatureEntries scoped_feature_entries_;
base::test::ScopedFeatureList scoped_feature_list_;
ScopedChromeLabsModelDataForTesting scoped_chrome_labs_model_data_;
};
TEST_F(ChromeLabsButtonTest, ShowAndHideChromeLabsBubbleOnPress) {
ChromeLabsButton* labs_button =
browser_view()->toolbar()->chrome_labs_button();
ChromeLabsCoordinator* coordinator =
labs_button->GetChromeLabsCoordinatorForTesting();
#if BUILDFLAG(IS_CHROMEOS_ASH)
ash::OwnerSettingsServiceAsh* service_ =
ash::OwnerSettingsServiceAshFactory::GetForBrowserContext(GetProfile());
labs_button->SetShouldCircumventDeviceCheckForTesting(true);
#endif
EXPECT_FALSE(coordinator->BubbleExists());
ui::MouseEvent e(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
ui::EventTimeForNow(), 0, 0);
views::test::ButtonTestApi test_api(labs_button);
test_api.NotifyClick(e);
#if BUILDFLAG(IS_CHROMEOS_ASH)
service_->RunPendingIsOwnerCallbacksForTesting(/*is_owner=*/false);
#endif
EXPECT_TRUE(coordinator->BubbleExists());
views::test::WidgetDestroyedWaiter destroyed_waiter(
coordinator->GetChromeLabsBubbleViewForTesting()->GetWidget());
test_api.NotifyClick(e);
destroyed_waiter.Wait();
EXPECT_FALSE(coordinator->BubbleExists());
}
TEST_F(ChromeLabsButtonTest, ShouldButtonShowTest) {
// There are experiments available so the button should not be nullptr.
EXPECT_NE(browser_view()->toolbar()->chrome_labs_button(), nullptr);
// Enterprise policy is initially set to true.
EXPECT_TRUE(browser_view()->toolbar()->chrome_labs_button()->GetVisible());
// Default enterprise policy value should show the Chrome Labs button.
profile()->GetPrefs()->ClearPref(chrome_labs_prefs::kBrowserLabsEnabled);
EXPECT_TRUE(browser_view()->toolbar()->chrome_labs_button()->GetVisible());
profile()->GetPrefs()->SetBoolean(chrome_labs_prefs::kBrowserLabsEnabled,
false);
EXPECT_FALSE(browser_view()->toolbar()->chrome_labs_button()->GetVisible());
}
TEST_F(ChromeLabsButtonTest, DotIndicatorTest) {
ChromeLabsButton* chrome_labs_button =
browser_view()->toolbar()->chrome_labs_button();
EXPECT_TRUE(chrome_labs_button->GetDotIndicatorVisibilityForTesting());
ui::MouseEvent e(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
ui::EventTimeForNow(), 0, 0);
views::test::ButtonTestApi test_api(chrome_labs_button);
test_api.NotifyClick(e);
EXPECT_FALSE(chrome_labs_button->GetDotIndicatorVisibilityForTesting());
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
class ChromeLabsButtonTestSafeMode : public ChromeLabsButtonTest {
public:
ChromeLabsButtonTestSafeMode() : ChromeLabsButtonTest() {}
void SetUp() override {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
ash::switches::kSafeMode);
ChromeLabsButtonTest::SetUp();
}
void TearDown() override {
base::CommandLine::ForCurrentProcess()->RemoveSwitch(
ash::switches::kSafeMode);
ChromeLabsButtonTest::TearDown();
}
};
TEST_F(ChromeLabsButtonTestSafeMode, ButtonShouldNotShowTest) {
EXPECT_EQ(browser_view()->toolbar()->chrome_labs_button(), nullptr);
}
class ChromeLabsButtonTestSecondaryUser : public ChromeLabsButtonTest {
public:
ChromeLabsButtonTestSecondaryUser() : ChromeLabsButtonTest() {}
void SetUp() override {
// Set the email of |secondary_user| to
// |TestingProfile::kDefaultProfileUserName| so
// |ProfileHelperImpl::GetUserByProfile| returns this user.
AccountId secondary_user =
AccountId::FromUserEmail(TestingProfile::kDefaultProfileUserName);
user_manager_->AddUser(secondary_user);
ChromeLabsButtonTest::SetUp();
}
};
TEST_F(ChromeLabsButtonTestSecondaryUser, ButtonShouldNotShowTest) {
EXPECT_EQ(browser_view()->toolbar()->chrome_labs_button(), nullptr);
}
#endif
class ChromeLabsButtonNoExperimentsAvailableTest : public TestWithBrowserView {
public:
ChromeLabsButtonNoExperimentsAvailableTest()
: scoped_feature_entries_({{kSecondTestFeatureId, "", "", 0,
FEATURE_VALUE_TYPE(kTestFeature2)}}) {}
void SetUp() override {
scoped_feature_list_.InitAndEnableFeature(features::kChromeLabs);
std::vector<LabInfo> test_feature_info = {
{kSecondTestFeatureId, u"", u"", "", version_info::Channel::STABLE}};
scoped_chrome_labs_model_data_.SetModelDataForTesting(test_feature_info);
TestWithBrowserView::SetUp();
profile()->GetPrefs()->SetBoolean(chrome_labs_prefs::kBrowserLabsEnabled,
true);
}
private:
about_flags::testing::ScopedFeatureEntries scoped_feature_entries_;
base::test::ScopedFeatureList scoped_feature_list_;
ScopedChromeLabsModelDataForTesting scoped_chrome_labs_model_data_;
};
TEST_F(ChromeLabsButtonNoExperimentsAvailableTest, ButtonShouldNotShowTest) {
EXPECT_EQ(browser_view()->toolbar()->chrome_labs_button(), nullptr);
}
class ChromeLabsButtonOnlyExpiredFeaturesAvailableTest
: public TestWithBrowserView {
public:
ChromeLabsButtonOnlyExpiredFeaturesAvailableTest()
: scoped_feature_entries_({{kExpiredFlagTestFeatureId, "", "",
flags_ui::FlagsState::GetCurrentPlatform(),
FEATURE_VALUE_TYPE(kTestFeatureExpired)}}) {
flags::testing::SetFlagExpiration(kExpiredFlagTestFeatureId, 0);
}
void SetUp() override {
scoped_feature_list_.InitAndEnableFeature(features::kChromeLabs);
std::vector<LabInfo> test_feature_info = {{kExpiredFlagTestFeatureId, u"",
u"", "",
version_info::Channel::STABLE}};
scoped_chrome_labs_model_data_.SetModelDataForTesting(test_feature_info);
TestWithBrowserView::SetUp();
profile()->GetPrefs()->SetBoolean(chrome_labs_prefs::kBrowserLabsEnabled,
true);
}
private:
about_flags::testing::ScopedFeatureEntries scoped_feature_entries_;
base::test::ScopedFeatureList scoped_feature_list_;
ScopedChromeLabsModelDataForTesting scoped_chrome_labs_model_data_;
};
TEST_F(ChromeLabsButtonOnlyExpiredFeaturesAvailableTest,
ButtonShouldNotShowTest) {
EXPECT_EQ(browser_view()->toolbar()->chrome_labs_button(), nullptr);
}