[merchant trust] Add survey config for evaluation surveys
Add features and survey configs for evaluation surveys. They will be attempted to be shown on NTP open if the conditions apply: since feature interaction between [min, max] minutes has passed (will be added in a separate CL).
Bug: 378854311
Change-Id: Ib552295434c42b65f44016d110044e4b310545c4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6185361
Reviewed-by: Martin Šrámek <[email protected]>
Reviewed-by: Nicola Tommasi <[email protected]>
Code-Coverage: [email protected] <[email protected]>
Reviewed-by: Elly FJ <[email protected]>
Commit-Queue: Olesia Marukhno <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1409967}
diff --git a/components/page_info/core/features.cc b/components/page_info/core/features.cc
index e84c198f..856842d 100644
--- a/components/page_info/core/features.cc
+++ b/components/page_info/core/features.cc
@@ -83,4 +83,12 @@
base::ToLowerASCII(locale) == kMerchantTrustEnabledForLocale;
}
+BASE_FEATURE(kMerchantTrustEvaluationControlSurvey,
+ "MerchantTrustEvaluationControlSurvey",
+ base::FEATURE_DISABLED_BY_DEFAULT);
+
+BASE_FEATURE(kMerchantTrustEvaluationExperimentSurvey,
+ "MerchantTrustEvaluationExperimentSurvey",
+ base::FEATURE_DISABLED_BY_DEFAULT);
+
} // namespace page_info
diff --git a/components/page_info/core/features.h b/components/page_info/core/features.h
index f55976c..be807ee 100644
--- a/components/page_info/core/features.h
+++ b/components/page_info/core/features.h
@@ -49,6 +49,19 @@
extern bool IsMerchantTrustFeatureEnabled(const std::string& country_code,
const std::string& locale);
+// Enables the 'Merchant trust' sentiment survey for control group. Used for
+// feature evaluation. This should be set in the fieldtrial config along with
+// the trigger ID for the corresponding survey (as en_site_id) and probability
+// (as probability).
+BASE_DECLARE_FEATURE(kMerchantTrustEvaluationControlSurvey);
+
+// Enables the 'Merchant trust' sentiment survey for experiment group. Used for
+// feature evaluation. The survey will be attempted to be shown on a new tab
+// when all the conditions apply. This should be set in the fieldtrial config
+// along with the trigger ID for the corresponding survey (as en_site_id) and
+// probability (as probability).
+BASE_DECLARE_FEATURE(kMerchantTrustEvaluationExperimentSurvey);
+
} // namespace page_info
#endif // COMPONENTS_PAGE_INFO_CORE_FEATURES_H_
diff --git a/components/page_info/core/merchant_trust_service.cc b/components/page_info/core/merchant_trust_service.cc
index 41317fb75..60c1d57b 100644
--- a/components/page_info/core/merchant_trust_service.cc
+++ b/components/page_info/core/merchant_trust_service.cc
@@ -40,10 +40,12 @@
} // namespace
MerchantTrustService::MerchantTrustService(
+ std::unique_ptr<Delegate> delegate,
optimization_guide::OptimizationGuideDecider* optimization_guide_decider,
bool is_off_the_record,
PrefService* prefs)
- : optimization_guide_decider_(optimization_guide_decider),
+ : delegate_(std::move(delegate)),
+ optimization_guide_decider_(optimization_guide_decider),
is_off_the_record_(is_off_the_record),
prefs_(prefs),
weak_ptr_factory_(this) {
@@ -72,6 +74,12 @@
weak_ptr_factory_.GetWeakPtr(), url, std::move(callback)));
}
+void MerchantTrustService::MaybeShowEvaluationSurvey() {
+ if (CanShowEvaluationSurvey()) {
+ delegate_->ShowEvaluationSurvey();
+ }
+}
+
void MerchantTrustService::OnCanApplyOptimizationComplete(
const GURL& url,
MerchantDataCallback callback,
@@ -139,4 +147,20 @@
return merchant_data;
}
+bool MerchantTrustService::CanShowEvaluationSurvey() {
+ if (base::FeatureList::IsEnabled(
+ page_info::kMerchantTrustEvaluationControlSurvey)) {
+ // TODO(crbug.com/378854311): Check when the feature was used.
+ return true;
+ }
+
+ if (base::FeatureList::IsEnabled(
+ page_info::kMerchantTrustEvaluationExperimentSurvey)) {
+ // TODO(crbug.com/378854311): Check when the feature was used.
+ return true;
+ }
+
+ return false;
+}
+
} // namespace page_info
diff --git a/components/page_info/core/merchant_trust_service.h b/components/page_info/core/merchant_trust_service.h
index f4cb4b052..07c35e73 100644
--- a/components/page_info/core/merchant_trust_service.h
+++ b/components/page_info/core/merchant_trust_service.h
@@ -29,11 +29,20 @@
// Provides merchant information for a web site.
class MerchantTrustService : public KeyedService {
public:
+ class Delegate {
+ public:
+ // Launches the evaluation survey based on the experiment state.
+ virtual void ShowEvaluationSurvey() = 0;
+
+ virtual ~Delegate() = default;
+ };
+
using DecisionAndMetadata =
std::pair<optimization_guide::OptimizationGuideDecision,
std::optional<commerce::MerchantTrustSignalsV2>>;
- explicit MerchantTrustService(
+ MerchantTrustService(
+ std::unique_ptr<Delegate> delegate,
optimization_guide::OptimizationGuideDecider* optimization_guide_decider,
bool is_off_the_record,
PrefService* prefs);
@@ -46,7 +55,12 @@
virtual void GetMerchantTrustInfo(const GURL& url,
MerchantDataCallback callback) const;
+ // Attempt to show an evaluation survey if the conditions apply. It will show
+ // either a control or an experiment survey depending on the feature state.
+ virtual void MaybeShowEvaluationSurvey();
+
private:
+ std::unique_ptr<Delegate> delegate_;
const raw_ptr<optimization_guide::OptimizationGuideDecider>
optimization_guide_decider_;
const bool is_off_the_record_;
@@ -66,6 +80,10 @@
std::optional<page_info::MerchantData> GetMerchantDataFromProto(
const std::optional<commerce::MerchantTrustSignalsV2>& metadata) const;
+
+ // Whether the evaluation survey should be shown based on how long ago user
+ // interacted with the feature.
+ bool CanShowEvaluationSurvey();
};
} // namespace page_info
diff --git a/components/page_info/core/merchant_trust_service_unittest.cc b/components/page_info/core/merchant_trust_service_unittest.cc
index 5286bfa7..f94c39f8 100644
--- a/components/page_info/core/merchant_trust_service_unittest.cc
+++ b/components/page_info/core/merchant_trust_service_unittest.cc
@@ -60,11 +60,18 @@
} // namespace
+class MockMerchantTrustServiceDelegate : public MerchantTrustService::Delegate {
+ public:
+ MOCK_METHOD(void, ShowEvaluationSurvey, (), (override));
+};
+
class MockMerchantTrustService : public MerchantTrustService {
public:
explicit MockMerchantTrustService(
- optimization_guide::OptimizationGuideDecider* optimization_guide_decider)
- : MerchantTrustService(optimization_guide_decider,
+ optimization_guide::OptimizationGuideDecider* optimization_guide_decider,
+ std::unique_ptr<MockMerchantTrustServiceDelegate> delegate)
+ : MerchantTrustService(std::move(delegate),
+ optimization_guide_decider,
/*is_off_the_record=*/false,
nullptr) {}
@@ -74,7 +81,10 @@
class MerchantTrustServiceTest : public ::testing::Test {
public:
void SetUp() override {
- service_ = std::make_unique<MockMerchantTrustService>(&opt_guide());
+ auto delegate = std::make_unique<MockMerchantTrustServiceDelegate>();
+ delegate_ = delegate.get();
+ service_ = std::make_unique<MockMerchantTrustService>(&opt_guide(),
+ std::move(delegate));
SetOptimizationGuideAllowed(true);
SetResponse(GURL("https://foo.com"), OptimizationGuideDecision::kUnknown,
BuildMerchantTrustResponse());
@@ -107,6 +117,7 @@
optimization_guide::MockOptimizationGuideDecider& opt_guide() {
return opt_guide_;
}
+ MockMerchantTrustServiceDelegate* delegate() { return delegate_; }
private:
base::test::TaskEnvironment task_environment_{
@@ -114,6 +125,7 @@
testing::NiceMock<optimization_guide::MockOptimizationGuideDecider>
opt_guide_;
std::unique_ptr<MockMerchantTrustService> service_;
+ raw_ptr<MockMerchantTrustServiceDelegate> delegate_;
};
// Tests that proto are returned correctly when optimization guide decision is
@@ -225,4 +237,45 @@
t.ExpectUniqueSample("Security.PageInfo.MerchantTrustStatus",
MerchantTrustStatus::kMissingReviewsSummary, 1);
}
+
+// Test for control evaluation survey.
+TEST_F(MerchantTrustServiceTest, ControlSurvey) {
+ base::test::ScopedFeatureList feature_list;
+ EXPECT_CALL(*delegate(), ShowEvaluationSurvey()).Times(1);
+
+ feature_list.InitWithFeatureState(kMerchantTrustEvaluationControlSurvey,
+ true);
+ service()->MaybeShowEvaluationSurvey();
+}
+
+// Test for control evaluation survey disabled.
+TEST_F(MerchantTrustServiceTest, ControlSurveyDisabled) {
+ base::test::ScopedFeatureList feature_list;
+ EXPECT_CALL(*delegate(), ShowEvaluationSurvey()).Times(0);
+
+ feature_list.InitWithFeatureState(kMerchantTrustEvaluationControlSurvey,
+ false);
+ service()->MaybeShowEvaluationSurvey();
+}
+
+// Test for experiment evaluation survey.
+TEST_F(MerchantTrustServiceTest, ExperimentSurvey) {
+ base::test::ScopedFeatureList feature_list;
+ EXPECT_CALL(*delegate(), ShowEvaluationSurvey()).Times(1);
+
+ feature_list.InitWithFeatureState(kMerchantTrustEvaluationExperimentSurvey,
+ true);
+ service()->MaybeShowEvaluationSurvey();
+}
+
+// Test for experiment evaluation survey disabled.
+TEST_F(MerchantTrustServiceTest, ExperimentSurveyDisabled) {
+ base::test::ScopedFeatureList feature_list;
+ EXPECT_CALL(*delegate(), ShowEvaluationSurvey()).Times(0);
+
+ feature_list.InitWithFeatureState(kMerchantTrustEvaluationExperimentSurvey,
+ false);
+ service()->MaybeShowEvaluationSurvey();
+}
+
} // namespace page_info