blob: e91a41ee31e9ab9cc6c89a7f9f95b3c7163722c6 [file] [log] [blame]
// Copyright 2023 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/promos/promos_utils.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/branding_buildflags.h"
#include "chrome/browser/promos/promos_features.h"
#include "chrome/browser/promos/promos_pref_names.h"
#include "chrome/test/base/testing_profile.h"
#include "components/prefs/testing_pref_service.h"
#include "components/segmentation_platform/embedder/default_model/device_switcher_model.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace promos_utils {
class IOSPasswordPromoOnDesktopTest : public ::testing::Test {
public:
void SetUp() override {
// Register the prefs when not on a branded build (they're automatically
// registered when on a branded build).
#if !BUILDFLAG(GOOGLE_CHROME_BRANDING)
promos_utils::RegisterProfilePrefs(prefs()->registry());
#endif // !BUILDFLAG(GOOGLE_CHROME_BRANDING)
}
// Getter for the test syncable prefs service.
sync_preferences::TestingPrefServiceSyncable* prefs() {
return profile()->GetTestingPrefService();
}
// Getter for the browser task environment.
content::BrowserTaskEnvironment* environment() { return &task_environment_; }
// Getter for the histograms tester.
base::HistogramTester* histograms() { return &histogram_; }
// Getter for the features list.
base::test::ScopedFeatureList* features() { return &scoped_feature_list_; }
// Getter for the testing profile.
TestingProfile* profile() { return &profile_; }
// Enables the iOS Password promo feature with a "contextual-direct" param.
void EnableContextualDirectFeature() {
features()->InitWithFeaturesAndParameters(
{{promos_features::kIOSPromoPasswordBubble,
{{"activation", "contextual-direct"}}}},
{/* disabled_features */});
}
private:
content::BrowserTaskEnvironment task_environment_{
base::test::TaskEnvironment::MainThreadType::UI};
base::HistogramTester histogram_;
base::test::ScopedFeatureList scoped_feature_list_;
TestingProfile profile_;
};
// Tests that RegisterProfilePrefs registers the prefs to their default values
// correctly.
TEST_F(IOSPasswordPromoOnDesktopTest, RegisterProfilePrefsTest) {
ASSERT_FALSE(prefs()->GetBoolean(promos_prefs::kiOSPasswordPromoOptOut));
ASSERT_EQ(
prefs()->GetInteger(promos_prefs::kiOSPasswordPromoImpressionsCounter),
0);
ASSERT_EQ(
prefs()->GetTime(promos_prefs::kiOSPasswordPromoLastImpressionTimestamp),
base::Time());
}
// Tests that RecordIOSPasswordPromoUserInteractionHistogram records the proper
// histogram for first impression and action dismissed.
TEST_F(
IOSPasswordPromoOnDesktopTest,
RecordIOSPasswordPromoUserInteractionHistogramTestFirstImpressionDismissed) {
promos_utils::RecordIOSPasswordPromoUserInteractionHistogram(
1, DesktopIOSPasswordPromoAction::kDismissed);
histograms()->ExpectUniqueSample(
"IOS.DesktopPasswordPromo.FirstImpression.Action",
DesktopIOSPasswordPromoAction::kDismissed, 1);
}
// Tests that RecordIOSPasswordPromoUserInteractionHistogram records the proper
// histogram for first impression and action explicitly closed.
TEST_F(
IOSPasswordPromoOnDesktopTest,
RecordIOSPasswordPromoUserInteractionHistogramTestFirstImpressionClosed) {
promos_utils::RecordIOSPasswordPromoUserInteractionHistogram(
1, DesktopIOSPasswordPromoAction::kExplicitlyClosed);
histograms()->ExpectUniqueSample(
"IOS.DesktopPasswordPromo.FirstImpression.Action",
DesktopIOSPasswordPromoAction::kExplicitlyClosed, 1);
}
// Tests that RecordIOSPasswordPromoUserInteractionHistogram records the proper
// histogram for first impression and action get started button clicked.
TEST_F(
IOSPasswordPromoOnDesktopTest,
RecordIOSPasswordPromoUserInteractionHistogramTestFirstImpressionGetStartedClicked) {
promos_utils::RecordIOSPasswordPromoUserInteractionHistogram(
1, DesktopIOSPasswordPromoAction::kGetStartedClicked);
histograms()->ExpectUniqueSample(
"IOS.DesktopPasswordPromo.FirstImpression.Action",
DesktopIOSPasswordPromoAction::kGetStartedClicked, 1);
}
// Tests that RecordIOSPasswordPromoUserInteractionHistogram records the proper
// histogram for second impression and action dismissed.
TEST_F(
IOSPasswordPromoOnDesktopTest,
RecordIOSPasswordPromoUserInteractionHistogramTestSecondImpressionDismissed) {
promos_utils::RecordIOSPasswordPromoUserInteractionHistogram(
2, DesktopIOSPasswordPromoAction::kDismissed);
histograms()->ExpectUniqueSample(
"IOS.DesktopPasswordPromo.SecondImpression.Action",
DesktopIOSPasswordPromoAction::kDismissed, 1);
}
// Tests that RecordIOSPasswordPromoUserInteractionHistogram records the proper
// histogram for second impression and action explicitly closed.
TEST_F(
IOSPasswordPromoOnDesktopTest,
RecordIOSPasswordPromoUserInteractionHistogramTestSecondImpressionClosed) {
promos_utils::RecordIOSPasswordPromoUserInteractionHistogram(
2, DesktopIOSPasswordPromoAction::kExplicitlyClosed);
histograms()->ExpectUniqueSample(
"IOS.DesktopPasswordPromo.SecondImpression.Action",
DesktopIOSPasswordPromoAction::kExplicitlyClosed, 1);
}
// Tests that RecordIOSPasswordPromoUserInteractionHistogram records the proper
// histogram for second impression and action get started button clicked.
TEST_F(
IOSPasswordPromoOnDesktopTest,
RecordIOSPasswordPromoUserInteractionHistogramTestSecondImpressionGetStartedClicked) {
promos_utils::RecordIOSPasswordPromoUserInteractionHistogram(
2, DesktopIOSPasswordPromoAction::kGetStartedClicked);
histograms()->ExpectUniqueSample(
"IOS.DesktopPasswordPromo.SecondImpression.Action",
DesktopIOSPasswordPromoAction::kGetStartedClicked, 1);
}
// Tests that IsActivationCriteriaOverriddenIOSPasswordPromo returns true when
// the feature flag is set to override criteria.
TEST_F(IOSPasswordPromoOnDesktopTest,
IsActivationCriteriaOverriddenIOSPasswordPromoTrueTest) {
features()->InitWithFeaturesAndParameters(
{{promos_features::kIOSPromoPasswordBubble,
{{"activation", "always-show-indirect"}}}},
{/* disabled_features */});
EXPECT_TRUE(promos_utils::IsActivationCriteriaOverriddenIOSPasswordPromo());
}
// Tests that IsActivationCriteriaOverriddenIOSPasswordPromo returns false when
// the feature flag is set to not override criteria.
TEST_F(IOSPasswordPromoOnDesktopTest,
IsActivationCriteriaOverriddenIOSPasswordPromoFalseTest) {
EnableContextualDirectFeature();
EXPECT_FALSE(promos_utils::IsActivationCriteriaOverriddenIOSPasswordPromo());
}
// Tests that ShouldShowIOSPasswordPromo returns true when no promo has yet been
// shown and the feature flag is set.
TEST_F(IOSPasswordPromoOnDesktopTest, ShouldShowIOSPasswordPromoTestTrue) {
EnableContextualDirectFeature();
EXPECT_TRUE(promos_utils::ShouldShowIOSPasswordPromo(profile()));
}
// Tests that ShouldShowIOSPasswordPromo returns false when the feature flag is
// not properly set.
TEST_F(IOSPasswordPromoOnDesktopTest,
ShouldShowIOSPasswordPromoTestFalseWrongFeatureFlag) {
features()->InitWithFeaturesAndParameters(
{{promos_features::kIOSPromoPasswordBubble,
{{"activation", "always-show-indirect"}}}},
{/* disabled_features */});
EXPECT_FALSE(promos_utils::ShouldShowIOSPasswordPromo(profile()));
}
// Tests that ShouldShowIOSPasswordPromo returns false when the user has already
// seen 2 promos.
TEST_F(IOSPasswordPromoOnDesktopTest,
ShouldShowIOSPasswordPromoTestFalseTooManyImpressions) {
EnableContextualDirectFeature();
prefs()->SetInteger(promos_prefs::kiOSPasswordPromoImpressionsCounter, 2);
EXPECT_FALSE(promos_utils::ShouldShowIOSPasswordPromo(profile()));
}
// Tests that ShouldShowIOSPasswordPromo returns false when the last seen
// impression is too recent.
TEST_F(IOSPasswordPromoOnDesktopTest,
ShouldShowIOSPasswordPromoTestFalseLastImpressionTooRecent) {
EnableContextualDirectFeature();
prefs()->SetTime(promos_prefs::kiOSPasswordPromoLastImpressionTimestamp,
base::Time::Now());
EXPECT_FALSE(promos_utils::ShouldShowIOSPasswordPromo(profile()));
}
// Tests that ShouldShowIOSPasswordPromo returns false when the user has
// opted-out from the promo.
TEST_F(IOSPasswordPromoOnDesktopTest,
ShouldShowIOSPasswordPromoTestFalseUserOptedOut) {
EnableContextualDirectFeature();
prefs()->SetBoolean(promos_prefs::kiOSPasswordPromoOptOut, true);
EXPECT_FALSE(promos_utils::ShouldShowIOSPasswordPromo(profile()));
}
// Tests that UserNotClassifiedAsMobileDeviceSwitcher returns true when the
// result is successful and the mobile labels are not present in the
// classification labels.
TEST_F(IOSPasswordPromoOnDesktopTest,
UserNotClassifiedAsMobileDeviceSwitcherTestTrue) {
segmentation_platform::ClassificationResult result(
segmentation_platform::PredictionStatus::kSucceeded);
result.ordered_labels.emplace_back("test_label");
EXPECT_TRUE(promos_utils::UserNotClassifiedAsMobileDeviceSwitcher(result));
}
// Tests that UserNotClassifiedAsMobileDeviceSwitcher returns false when the
// result has an error.
TEST_F(IOSPasswordPromoOnDesktopTest,
UserNotClassifiedAsMobileDeviceSwitcherTestFalseError) {
segmentation_platform::ClassificationResult result(
segmentation_platform::PredictionStatus::kFailed);
EXPECT_FALSE(promos_utils::UserNotClassifiedAsMobileDeviceSwitcher(result));
}
// Tests that UserNotClassifiedAsMobileDeviceSwitcher returns false when a
// mobile label is present in the classification results.
TEST_F(IOSPasswordPromoOnDesktopTest,
UserNotClassifiedAsMobileDeviceSwitcherTestFalseMobileLabelPresent) {
segmentation_platform::ClassificationResult result(
segmentation_platform::PredictionStatus::kSucceeded);
result.ordered_labels.emplace_back(
segmentation_platform::DeviceSwitcherModel::kIosPhoneChromeLabel);
EXPECT_FALSE(promos_utils::UserNotClassifiedAsMobileDeviceSwitcher(result));
}
// Tests that iOSPasswordPromoShown sets the correct prefs and records the
// correct histogram for the first impression.
TEST_F(IOSPasswordPromoOnDesktopTest,
iOSPasswordPromoShownTestFirstImpression) {
// Record before and after times to ensure the timestamp is within that range.
base::Time before = base::Time::Now();
promos_utils::iOSPasswordPromoShown(profile());
base::Time after = base::Time::Now();
ASSERT_EQ(
prefs()->GetInteger(promos_prefs::kiOSPasswordPromoImpressionsCounter),
1);
ASSERT_GE(
prefs()->GetTime(promos_prefs::kiOSPasswordPromoLastImpressionTimestamp),
before);
ASSERT_LE(
prefs()->GetTime(promos_prefs::kiOSPasswordPromoLastImpressionTimestamp),
after);
histograms()->ExpectUniqueSample(
"IOS.DesktopPasswordPromo.Shown",
promos_utils::DesktopIOSPasswordPromoImpression::kFirstImpression, 1);
}
// Tests that iOSPasswordPromoShown sets the correct prefs and records the
// correct histogram for the second impression.
TEST_F(IOSPasswordPromoOnDesktopTest,
iOSPasswordPromoShownTestSecondImpression) {
// First impression
promos_utils::iOSPasswordPromoShown(profile());
// Second impression
base::Time before = base::Time::Now();
promos_utils::iOSPasswordPromoShown(profile());
base::Time after = base::Time::Now();
ASSERT_EQ(
prefs()->GetInteger(promos_prefs::kiOSPasswordPromoImpressionsCounter),
2);
ASSERT_GE(
prefs()->GetTime(promos_prefs::kiOSPasswordPromoLastImpressionTimestamp),
before);
ASSERT_LE(
prefs()->GetTime(promos_prefs::kiOSPasswordPromoLastImpressionTimestamp),
after);
histograms()->ExpectBucketCount(
"IOS.DesktopPasswordPromo.Shown",
promos_utils::DesktopIOSPasswordPromoImpression::kSecondImpression, 1);
}
// Tests that IsDirectVariantIOSPasswordPromo returns true when the user is in a
// direct variant of the feature flag.
TEST_F(IOSPasswordPromoOnDesktopTest, IsDirectVariantIOSPasswordPromoTestTrue) {
EnableContextualDirectFeature();
EXPECT_TRUE(promos_utils::IsDirectVariantIOSPasswordPromo());
}
// Tests that IsDirectVariantIOSPasswordPromo returns false when the feature is
// not active.
TEST_F(IOSPasswordPromoOnDesktopTest,
IsDirectVariantIOSPasswordPromoTestFalseFeatureInactive) {
EXPECT_FALSE(promos_utils::IsDirectVariantIOSPasswordPromo());
}
// Tests that IsDirectVariantIOSPasswordPromo returns false when the user's
// feature is set to an indirect variant.
TEST_F(IOSPasswordPromoOnDesktopTest,
IsDirectVariantIOSPasswordPromoTestFalseIndirectActive) {
features()->InitWithFeaturesAndParameters(
{{promos_features::kIOSPromoPasswordBubble,
{{"activation", "always-show-indirect"}}}},
{/* disabled_features */});
EXPECT_FALSE(promos_utils::IsDirectVariantIOSPasswordPromo());
}
// Tests that IsIndirectVariantIOSPasswordPromo returns true when the user is in
// an indirect variant of the feature flag.
TEST_F(IOSPasswordPromoOnDesktopTest,
IsIndirectVariantIOSPasswordPromoTestTrue) {
features()->InitWithFeaturesAndParameters(
{{promos_features::kIOSPromoPasswordBubble,
{{"activation", "always-show-indirect"}}}},
{/* disabled_features */});
EXPECT_TRUE(promos_utils::IsIndirectVariantIOSPasswordPromo());
}
// Tests that IsIndirectVariantIOSPasswordPromo returns false when the feature
// is not active.
TEST_F(IOSPasswordPromoOnDesktopTest,
IsIndirectVariantIOSPasswordPromoTestFalseFeatureInactive) {
EXPECT_FALSE(promos_utils::IsIndirectVariantIOSPasswordPromo());
}
// Tests that IsIndirectVariantIOSPasswordPromo returns false when the user's
// feature is set to a direct variant.
TEST_F(IOSPasswordPromoOnDesktopTest,
IsIndirectVariantIOSPasswordPromoTestFalseDirectActive) {
EnableContextualDirectFeature();
EXPECT_FALSE(promos_utils::IsIndirectVariantIOSPasswordPromo());
}
} // namespace promos_utils