chromium/chrome/browser/ash/input_method/autocorrect_prefs_unittest.cc

// Copyright 2022 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/ash/input_method/autocorrect_prefs.h"

#include "ash/constants/ash_features.h"
#include "ash/constants/ash_pref_names.h"
#include "base/feature_list.h"
#include "base/strings/strcat.h"
#include "base/values.h"
#include "chrome/browser/ash/input_method/autocorrect_enums.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace ash::input_method {
namespace {

constexpr char kUsEnglish[] = "xkb:us::eng";
constexpr char kBrazilPortuguese[] = "xkb:br::por";
constexpr char kLatinAmericaSpanish[] = "xkb:latam::spa";
constexpr char kFranceFrench[] = "xkb:fr::fra";

void SetManagedPkAutocorrectAllowed(Profile& profile, bool allowed) {
  profile.GetPrefs()->SetBoolean(
      prefs::kManagedPhysicalKeyboardAutocorrectAllowed, allowed);
}

void SetAutocorrectLevelTo(Profile& profile,
                           const std::string& pref_name,
                           const std::string& engine_id,
                           int autocorrect_level) {
  base::Value::Dict input_method_setting;
  input_method_setting.SetByDottedPath(
      base::StrCat({engine_id, ".", pref_name}), autocorrect_level);
  profile.GetPrefs()->Set(::prefs::kLanguageInputMethodSpecificSettings,
                          base::Value(std::move(input_method_setting)));
}

void SetPkAutocorrectLevelTo(Profile& profile,
                             const std::string& engine_id,
                             int autocorrect_level) {
  SetAutocorrectLevelTo(/*profile=*/profile,
                        /*pref_name=*/"physicalKeyboardAutoCorrectionLevel",
                        /*engine_id=*/engine_id,
                        /*autocorrect_level=*/autocorrect_level);
}

void SetVkAutocorrectLevelTo(Profile& profile,
                             const std::string& engine_id,
                             int autocorrect_level) {
  SetAutocorrectLevelTo(/*profile=*/profile,
                        /*pref_name=*/"virtualKeyboardAutoCorrectionLevel",
                        /*engine_id=*/engine_id,
                        /*autocorrect_level=*/autocorrect_level);
}

class AutocorrectPrefsTest : public ::testing::Test {
 protected:
  content::BrowserTaskEnvironment task_environment_;
  base::test::ScopedFeatureList feature_list_;
  TestingProfile profile_;
};

TEST_F(AutocorrectPrefsTest,
       FetchesTheCorrectPkValueWhenAutocorrectLevelIsNotSet) {
  EXPECT_EQ(
      GetPhysicalKeyboardAutocorrectPref(*(profile_.GetPrefs()), kUsEnglish),
      AutocorrectPreference::kDefault);
}

TEST_F(AutocorrectPrefsTest,
       FetchesTheCorrectVkValueWhenAutocorrectLevelIsNotSet) {
  EXPECT_EQ(
      GetVirtualKeyboardAutocorrectPref(*(profile_.GetPrefs()), kUsEnglish),
      AutocorrectPreference::kDefault);
}

struct AutocorrectPrefCase {
  std::string test_name;
  int autocorrect_level;
  AutocorrectPreference autocorrect_pref;
};

class FetchesAutocorrectPreference
    : public AutocorrectPrefsTest,
      public testing::WithParamInterface<AutocorrectPrefCase> {};

TEST_P(FetchesAutocorrectPreference, AndReturnsCorrectPkPref) {
  const AutocorrectPrefCase& test_case = GetParam();
  SetPkAutocorrectLevelTo(profile_,
                          /*engine_id=*/kUsEnglish,
                          /*autocorrect_level=*/test_case.autocorrect_level);

  EXPECT_EQ(
      GetPhysicalKeyboardAutocorrectPref(*(profile_.GetPrefs()), kUsEnglish),
      test_case.autocorrect_pref);
}

TEST_P(FetchesAutocorrectPreference, AndScopesReturnedPkPreferenceToEngineId) {
  const AutocorrectPrefCase& test_case = GetParam();
  SetPkAutocorrectLevelTo(profile_,
                          /*engine_id=*/kUsEnglish,
                          /*autocorrect_level=*/test_case.autocorrect_level);

  // The above preference is set for the US English engine only. Queries for
  // the autocorrect level on any other engine should return the default.
  EXPECT_EQ(GetPhysicalKeyboardAutocorrectPref(*(profile_.GetPrefs()),
                                               kBrazilPortuguese),
            AutocorrectPreference::kDefault);
}

TEST_P(FetchesAutocorrectPreference, AndReturnsCorrectVkPref) {
  const AutocorrectPrefCase& test_case = GetParam();
  SetVkAutocorrectLevelTo(profile_,
                          /*engine_id=*/kUsEnglish,
                          /*autocorrect_level=*/test_case.autocorrect_level);

  EXPECT_EQ(
      GetVirtualKeyboardAutocorrectPref(*(profile_.GetPrefs()), kUsEnglish),
      test_case.autocorrect_pref);
}

TEST_P(FetchesAutocorrectPreference, AndScopesReturnedVkPreferenceToEngineId) {
  const AutocorrectPrefCase& test_case = GetParam();
  SetVkAutocorrectLevelTo(profile_,
                          /*engine_id=*/kUsEnglish,
                          /*autocorrect_level=*/test_case.autocorrect_level);

  // The above preference is set for the US English engine only. Queries for
  // the autocorrect level on any other engine should return the default.
  EXPECT_EQ(GetVirtualKeyboardAutocorrectPref(*(profile_.GetPrefs()),
                                              kBrazilPortuguese),
            AutocorrectPreference::kDefault);
}

INSTANTIATE_TEST_SUITE_P(
    AutocorrectPrefsTest,
    FetchesAutocorrectPreference,
    testing::ValuesIn<AutocorrectPrefCase>({
        AutocorrectPrefCase{
            "ForAutocorrectLevelZero",
            /*autocorrect_level=*/0,
            /*autocorrect_pref=*/AutocorrectPreference::kDisabled},
        AutocorrectPrefCase{
            "ForAutocorrectLevelNegativeOne",
            /*autocorrect_level=*/-1,
            /*autocorrect_pref=*/AutocorrectPreference::kDisabled},
        AutocorrectPrefCase{
            "ForAutocorrectLevelOne",
            /*autocorrect_level=*/1,
            /*autocorrect_pref=*/AutocorrectPreference::kEnabled},
        AutocorrectPrefCase{
            "ForAutocorrectLevelTwo",
            /*autocorrect_level=*/1,
            /*autocorrect_pref=*/AutocorrectPreference::kEnabled},
    }),
    [](const testing::TestParamInfo<AutocorrectPrefCase> info) {
      return info.param.test_name;
    });

TEST_F(AutocorrectPrefsTest, MarksUsersPrefAsEnabledByDefault) {
  feature_list_.InitWithFeatures({features::kAutocorrectByDefault}, {});

  SetPhysicalKeyboardAutocorrectAsEnabledByDefault(profile_.GetPrefs(),
                                                   kUsEnglish);

  EXPECT_EQ(
      GetPhysicalKeyboardAutocorrectPref(*(profile_.GetPrefs()), kUsEnglish),
      AutocorrectPreference::kEnabledByDefault);
}

TEST_F(AutocorrectPrefsTest, EnabledByDefaultIsScopedToSingleLanguage) {
  feature_list_.InitWithFeatures({features::kAutocorrectByDefault}, {});

  SetPhysicalKeyboardAutocorrectAsEnabledByDefault(profile_.GetPrefs(),
                                                   kBrazilPortuguese);

  EXPECT_EQ(
      GetPhysicalKeyboardAutocorrectPref(*(profile_.GetPrefs()), kUsEnglish),
      AutocorrectPreference::kDefault);
  EXPECT_EQ(GetPhysicalKeyboardAutocorrectPref(*(profile_.GetPrefs()),
                                               kBrazilPortuguese),
            AutocorrectPreference::kEnabledByDefault);
}

class AutocorrectAdminPolicy : public AutocorrectPrefsTest,
                               public testing::WithParamInterface<std::string> {
};

TEST_P(AutocorrectAdminPolicy,
       WhenAdminPolicyDisallowsAutocorrectItIsAlwaysDisabled) {
  const std::string& engine_id = GetParam();

  SetPkAutocorrectLevelTo(profile_, engine_id, 1);
  SetManagedPkAutocorrectAllowed(profile_, false);

  EXPECT_EQ(
      GetPhysicalKeyboardAutocorrectPref(*(profile_.GetPrefs()), engine_id),
      AutocorrectPreference::kDisabled);
}

TEST_P(AutocorrectAdminPolicy, WhenAdminPolicyAllowsAutocorrectItCanBeEnabled) {
  const std::string& engine_id = GetParam();

  SetPkAutocorrectLevelTo(profile_, engine_id, 1);
  SetManagedPkAutocorrectAllowed(profile_, true);

  EXPECT_EQ(
      GetPhysicalKeyboardAutocorrectPref(*(profile_.GetPrefs()), engine_id),
      AutocorrectPreference::kEnabled);
}

TEST_P(AutocorrectAdminPolicy, WhenAdminPolicyIsNotSetAutocorrectCanBeEnabled) {
  const std::string& engine_id = GetParam();

  SetPkAutocorrectLevelTo(profile_, engine_id, 1);

  EXPECT_EQ(
      GetPhysicalKeyboardAutocorrectPref(*(profile_.GetPrefs()), engine_id),
      AutocorrectPreference::kEnabled);
}

INSTANTIATE_TEST_SUITE_P(AutocorrectPrefsTest,
                         AutocorrectAdminPolicy,
                         testing::ValuesIn<std::string>({
                             kBrazilPortuguese,
                             kFranceFrench,
                             kLatinAmericaSpanish,
                             kUsEnglish,
                         }));

}  // namespace
}  // namespace ash::input_method