chromium/components/feature_engagement/internal/tracker_impl_unittest.cc

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/feature_engagement/internal/tracker_impl.h"

#include <map>
#include <memory>
#include <utility>

#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback_forward.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/metrics/user_action_tester.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/feature_engagement/internal/availability_model_impl.h"
#include "components/feature_engagement/internal/display_lock_controller.h"
#include "components/feature_engagement/internal/editable_configuration.h"
#include "components/feature_engagement/internal/event_model_impl.h"
#include "components/feature_engagement/internal/feature_config_condition_validator.h"
#include "components/feature_engagement/internal/in_memory_event_store.h"
#include "components/feature_engagement/internal/never_availability_model.h"
#include "components/feature_engagement/internal/never_event_storage_validator.h"
#include "components/feature_engagement/internal/once_condition_validator.h"
#include "components/feature_engagement/internal/stats.h"
#include "components/feature_engagement/internal/test/test_time_provider.h"
#include "components/feature_engagement/internal/time_provider.h"
#include "components/feature_engagement/public/configuration.h"
#include "components/feature_engagement/public/feature_constants.h"
#include "components/feature_engagement/public/feature_list.h"
#include "components/feature_engagement/public/session_controller.h"
#include "components/feature_engagement/test/scoped_iph_feature_list.h"
#include "components/feature_engagement/test/test_tracker.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace feature_engagement {

namespace {
BASE_FEATURE();
BASE_FEATURE();
BASE_FEATURE();
BASE_FEATURE();
BASE_FEATURE();
BASE_FEATURE();
BASE_FEATURE();

void RegisterFeatureConfig(EditableConfiguration* configuration,
                           const base::Feature& feature,
                           bool valid,
                           bool tracking_only,
                           bool snooze_params,
                           const char* additional_event_name = nullptr) {}

void RegisterGroupConfig(EditableConfiguration* configuration,
                         const base::Feature& group,
                         bool valid) {}

// An OnInitializedCallback that stores whether it has been invoked and what
// the result was.
class StoringInitializedCallback {};

// An InMemoryEventStore that is able to fake successful and unsuccessful
// loading of state.
class TestTrackerInMemoryEventStore : public InMemoryEventStore {};

class StoreEverythingEventStorageValidator : public EventStorageValidator {};

class TestTrackerAvailabilityModel : public AvailabilityModel {};

class TestTrackerDisplayLockController : public DisplayLockController {};

class TestTrackerEventExporter : public TrackerEventExporter {};

class TestSessionController : public SessionController {};

#if BUILDFLAG(IS_CHROMEOS_ASH)
class TestConfigurationProvider : public ConfigurationProvider {
 public:
  TestConfigurationProvider() = default;
  ~TestConfigurationProvider() override = default;

  // ConfigurationProvider:
  bool MaybeProvideFeatureConfiguration(
      const base::Feature& feature,
      feature_engagement::FeatureConfig& config,
      const feature_engagement::FeatureVector& known_features,
      const feature_engagement::GroupVector& known_groups) const override {
    config = config_;
    return true;
  }

  const char* GetConfigurationSourceDescription() const override {
    return "Test Configuration Provider";
  }

  std::set<std::string> MaybeProvideAllowedEventPrefixes(
      const base::Feature& feature) const override {
    return {};
  }

  void SetConfig(const FeatureConfig& config) { config_ = config; }

 private:
  FeatureConfig config_;
};
#endif

class TrackerImplTest : public ::testing::Test {};

// A top-level test class where the store fails to initialize.
class FailingStoreInitTrackerImplTest : public TrackerImplTest {};

// A top-level test class where the AvailabilityModel fails to initialize.
class FailingAvailabilityModelInitTrackerImplTest : public TrackerImplTest {};

}  // namespace

TEST_F(TrackerImplTest, TestCreateTestTracker) {}

TEST_F(TrackerImplTest, TestInitialization) {}

TEST_F(TrackerImplTest, TestInitializationMultipleCallbacks) {}

TEST_F(TrackerImplTest, TestAddingCallbackAfterInitFinished) {}

TEST_F(TrackerImplTest, TestAddingCallbackBeforeAndAfterInitFinished) {}

TEST_F(FailingStoreInitTrackerImplTest, TestFailingInitialization) {}

TEST_F(FailingStoreInitTrackerImplTest,
       TestFailingInitializationMultipleCallbacks) {}

TEST_F(FailingAvailabilityModelInitTrackerImplTest, AvailabilityModelNotReady) {}

TEST_F(TrackerImplTest, TestMigrateEvents) {}

TEST_F(TrackerImplTest, TestMigrateMultipleEvents) {}

TEST_F(TrackerImplTest, TestMigrateSameEventMultipleTimes) {}

TEST_F(TrackerImplTest, TestNoMigration) {}

TEST_F(TrackerImplTest, TestSetPriorityNotificationBeforeRegistration) {}

TEST_F(TrackerImplTest, TestSetPriorityNotificationAfterRegistration) {}

TEST_F(TrackerImplTest, TestUnregisterPriorityNotification) {}

TEST_F(TrackerImplTest, TestTriggering) {}

TEST_F(TrackerImplTest, TestTriggeringWithSessionController) {}

TEST_F(TrackerImplTest, TestTrackingOnlyTriggering) {}

TEST_F(TrackerImplTest, TestHasEverTriggered) {}

TEST_F(TrackerImplTest, TestWouldTriggerInspection) {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(TrackerImplTest, TestWouldTriggerWithUpdatedConfig) {
  // Ensure all initialization is finished.
  StoringInitializedCallback callback;
  tracker_->AddOnInitializedCallback(base::BindOnce(
      &StoringInitializedCallback::OnInitialized, base::Unretained(&callback)));
  base::RunLoop().RunUntilIdle();
  base::UserActionTester user_action_tester;

  // Initially, foo would have been shown.
  EXPECT_TRUE(tracker_->WouldTriggerHelpUI(kTrackerTestFeatureFoo));

  FeatureConfig config;
  config.valid = false;
  config.used.name = kTrackerTestFeatureFoo.name + std::string("_used");
  config.trigger.name = kTrackerTestFeatureFoo.name + std::string("_trigger");

  auto provider = std::make_unique<TestConfigurationProvider>();
  provider->SetConfig(config);
  tracker_->UpdateConfig(kTrackerTestFeatureFoo, provider.get());
  EXPECT_FALSE(tracker_->WouldTriggerHelpUI(kTrackerTestFeatureFoo));

  config.valid = true;
  provider->SetConfig(config);
  tracker_->UpdateConfig(kTrackerTestFeatureFoo, provider.get());
  EXPECT_TRUE(tracker_->WouldTriggerHelpUI(kTrackerTestFeatureFoo));
}
#endif

TEST_F(TrackerImplTest, TestTriggerStateInspection) {}

TEST_F(TrackerImplTest, TestNotifyEvent) {}

#if !BUILDFLAG(IS_ANDROID)

TEST_F(TrackerImplTest, TestNotifyUsedEvent) {}

TEST_F(TrackerImplTest, TestClearEventData) {}

#endif  // !BUILDFLAG(IS_ANDROID)

TEST_F(TrackerImplTest, ShouldPassThroughAcquireDisplayLock) {}

// Checks that the time is correctly logged when an IPH is presented.
TEST_F(TrackerImplTest, ShownTimeLogged) {}

// Checks that the time is not logged when the feature is `tracking_only`.
TEST_F(TrackerImplTest, TrackingOnly_ShownTimeNotLogged) {}

// Base class for any tests that specifically require a
// |OnceConditionValidator|.
class OnceConditionTrackerImplTest : public TrackerImplTest {};

// Checks that the times are logged even when multiple IPH are presented.
TEST_F(OnceConditionTrackerImplTest, MultipleShownTimeLogged) {}

namespace test {

class ScopedIphFeatureListTest : public TrackerImplTest {};

TEST_F(ScopedIphFeatureListTest, InitWithNoFeaturesAllowed) {}

TEST_F(ScopedIphFeatureListTest, InitWithNoFeaturesAllowed_AllowedAfterReset) {}

TEST_F(ScopedIphFeatureListTest,
       InitWithNoFeaturesAllowed_AllowedAfterDestruct) {}

TEST_F(ScopedIphFeatureListTest, InitWithExistingFeatures) {}

TEST_F(ScopedIphFeatureListTest, InitWithExistingFeatures_AllowedAfterReset) {}

TEST_F(ScopedIphFeatureListTest,
       InitWithExistingFeatures_AllowedAfterDestruct) {}

TEST_F(ScopedIphFeatureListTest, InitForDemo) {}

TEST_F(ScopedIphFeatureListTest, InitForDemo_Reset) {}

TEST_F(ScopedIphFeatureListTest, InitForDemo_Destruct) {}

TEST_F(ScopedIphFeatureListTest, InitAndEnableFeatures) {}

TEST_F(ScopedIphFeatureListTest, InitAndEnableFeatures_Reset) {}

TEST_F(ScopedIphFeatureListTest, InitAndEnableFeatures_Destruct) {}

TEST_F(ScopedIphFeatureListTest, InitAndEnableFeaturesWithParameters) {}

TEST_F(ScopedIphFeatureListTest, InitAndEnableFeaturesWithParameters_Reset) {}

TEST_F(ScopedIphFeatureListTest, InitAndEnableFeaturesWithParameters_Destruct) {}

TEST_F(ScopedIphFeatureListTest, NestedScopes) {}

TEST_F(ScopedIphFeatureListTest, NestedScopes_DestructInWrongOrder) {}

TEST_F(ScopedIphFeatureListTest, NestedScopes_SameFeature) {}

// Test class for tests that require an actual
// |FeatureConfigConditionValidator|.
class FeatureConfigConditionValidatorTrackerTest : public TrackerImplTest {};

TEST_F(FeatureConfigConditionValidatorTrackerTest, GroupRulesApplied) {}

TEST_F(FeatureConfigConditionValidatorTrackerTest, TestTriggeringWithSnooze) {}

}  // namespace test

}  // namespace feature_engagement