blob: a4b4e1329a48dbb49410a038e4807a5911fcb927 [file] [log] [blame]
// Copyright 2021 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/ui/hats/trust_safety_sentiment_service.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time_override.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/bubble_anchor_util.h"
#include "chrome/browser/ui/hats/hats_service_factory.h"
#include "chrome/browser/ui/hats/mock_hats_service.h"
#include "chrome/browser/ui/hats/trust_safety_sentiment_service_factory.h"
#include "chrome/browser/ui/page_info/page_info_dialog.h"
#include "chrome/browser/ui/views/page_info/page_info_bubble_view.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/test/browser_test.h"
using ::testing::_;
namespace {
std::unique_ptr<KeyedService> BuildSentimentServiceForTesting(
content::BrowserContext* context) {
return std::make_unique<TrustSafetySentimentService>(
static_cast<Profile*>(context));
}
} // namespace
class TrustSafetySentimentServiceBrowserTest : public InProcessBrowserTest {
public:
TrustSafetySentimentServiceBrowserTest() {
feature_list_.InitAndEnableFeatureWithParameters(
features::kTrustSafetySentimentSurveyV2,
{{"trusted-surface-probability", "1.0"}});
}
// TODO(crbug.com/40285326): This fails with the field trial testing config.
void SetUpCommandLine(base::CommandLine* command_line) override {
InProcessBrowserTest::SetUpCommandLine(command_line);
command_line->AppendSwitch("disable-field-trial-config");
}
void SetUpOnMainThread() override {
mock_hats_service_ = static_cast<MockHatsService*>(
HatsServiceFactory::GetInstance()->SetTestingFactoryAndUse(
browser()->profile(), base::BindRepeating(&BuildMockHatsService)));
TrustSafetySentimentServiceFactory::GetInstance()->SetTestingFactory(
browser()->profile(),
base::BindRepeating(&BuildSentimentServiceForTesting));
EXPECT_CALL(*mock_hats_service_, CanShowAnySurvey(_))
.WillRepeatedly(testing::Return(true));
}
void TearDownOnMainThread() override { mock_hats_service_ = nullptr; }
void OpenPageInfo() {
ShowPageInfoDialog(browser()->tab_strip_model()->GetActiveWebContents(),
base::DoNothing(),
bubble_anchor_util::Anchor::kLocationBar);
}
void ClosePageInfo() {
PageInfoBubbleView::GetPageInfoBubbleForTesting()
->GetWidget()
->CloseWithReason(views::Widget::ClosedReason::kCloseButtonClicked);
base::RunLoop().RunUntilIdle();
}
void ChangePermission() {
PageInfo::PermissionInfo permission;
permission.type = ContentSettingsType::NOTIFICATIONS;
permission.setting = ContentSetting::CONTENT_SETTING_BLOCK;
permission.default_setting = ContentSetting::CONTENT_SETTING_ASK;
auto* bubble = static_cast<PageInfoBubbleView*>(
PageInfoBubbleView::GetPageInfoBubbleForTesting());
bubble->presenter_for_testing()->OnSitePermissionChanged(
permission.type, permission.setting, permission.requesting_origin,
permission.is_one_time);
}
void OpenEnoughNewTabs() {
for (int i = 0;
i < features::kTrustSafetySentimentSurveyNtpVisitsMaxRange.Get();
i++) {
ui_test_utils::NavigateToURLWithDisposition(
browser(), GURL(chrome::kChromeUINewTabURL),
WindowOpenDisposition::NEW_FOREGROUND_TAB,
ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
}
}
protected:
base::test::ScopedFeatureList feature_list_;
raw_ptr<MockHatsService> mock_hats_service_ = nullptr;
};
IN_PROC_BROWSER_TEST_F(TrustSafetySentimentServiceBrowserTest,
PageInfoTriggersSurvey_NoInteraction) {
// Check that after opening Page Info for the required time, then performing
// the required eligibility actions, a survey is requested from the HaTS
// service.
SurveyBitsData expected_product_specific_data = {
{"Interacted with Page Info", false}};
EXPECT_CALL(*mock_hats_service_,
LaunchSurvey(kHatsSurveyTriggerTrustSafetyV2TrustedSurface, _, _,
expected_product_specific_data, _, _, _));
{
base::subtle::ScopedTimeClockOverrides override(
[]() {
return base::subtle::TimeNowIgnoringOverride().LocalMidnight();
},
nullptr, nullptr);
OpenPageInfo();
}
// Wait for the required time before closing.
{
base::subtle::ScopedTimeClockOverrides override(
[]() {
return base::subtle::TimeNowIgnoringOverride().LocalMidnight() +
features::kTrustSafetySentimentSurveyTrustedSurfaceTime.Get();
},
nullptr, nullptr);
ClosePageInfo();
}
// Open the maximum number of required tabs, after waiting for the minimum
// prompt time.
{
base::subtle::ScopedTimeClockOverrides override(
[]() {
return base::subtle::TimeNowIgnoringOverride().LocalMidnight() +
features::kTrustSafetySentimentSurveyTrustedSurfaceTime.Get() +
features::kTrustSafetySentimentSurveyMinTimeToPrompt.Get();
},
nullptr, nullptr);
OpenEnoughNewTabs();
}
}
IN_PROC_BROWSER_TEST_F(TrustSafetySentimentServiceBrowserTest,
PageInfoTriggersSurvey_Interaction) {
// Check that interacting with page info (through a reported change to
// permissions in this instance) removes the time requirement, and also
// changes the product specific data accordingly.
SurveyBitsData expected_product_specific_data = {
{"Interacted with Page Info", true}};
EXPECT_CALL(*mock_hats_service_,
LaunchSurvey(kHatsSurveyTriggerTrustSafetyV2TrustedSurface, _, _,
expected_product_specific_data, _, _, _));
{
base::subtle::ScopedTimeClockOverrides override(
[]() {
return base::subtle::TimeNowIgnoringOverride().LocalMidnight();
},
nullptr, nullptr);
OpenPageInfo();
ChangePermission();
ClosePageInfo();
}
{
base::subtle::ScopedTimeClockOverrides override(
[]() {
return base::subtle::TimeNowIgnoringOverride().LocalMidnight() +
features::kTrustSafetySentimentSurveyMinTimeToPrompt.Get();
},
nullptr, nullptr);
OpenEnoughNewTabs();
}
}