From 1a78e8ec1bf4b6759893a28565f44fabeb6e68e1 Mon Sep 17 00:00:00 2001
From: Blake Erickson <o.blakeerickson@gmail.com>
Date: Fri, 27 Oct 2023 15:42:57 -0600
Subject: [PATCH] FEATURE: Add keywords support for site_settings search
 (#24146)

* FEATURE: Add keywords support for site_settings search

This change allows for a new `keywords` field that can be added to site
settings in order to help with searching. Keywords are not visible in
the UI, but site settings matching one of the contained keywords will
appear when searching for that keyword.

Keywords can be added for site settings inside of the
`config/locales/server.en.yml` file under the new `keywords` key.

```
site_settings
  example_1: "fancy description"
  example_2: "another description"

  keywords:
    example_1: "capybara"
```

* Add keywords entry for a recently changed site setting and add system specs

* Use page.visit now that we have our own visit
---
 .../addon/controllers/admin-site-settings.js  |  4 +++
 .../controllers/admin-site-settings-test.js   |  6 +++++
 config/locales/server.en.yml                  |  3 +++
 lib/site_setting_extension.rb                 |  5 ++++
 spec/system/admin_site_setting_search_spec.rb | 25 +++++++++++++++++++
 .../page_objects/pages/admin_settings.rb      | 16 +++++++++++-
 6 files changed, 58 insertions(+), 1 deletion(-)
 create mode 100644 spec/system/admin_site_setting_search_spec.rb

diff --git a/app/assets/javascripts/admin/addon/controllers/admin-site-settings.js b/app/assets/javascripts/admin/addon/controllers/admin-site-settings.js
index 579e01fb204..5ce8d5dd8d7 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-site-settings.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-site-settings.js
@@ -89,6 +89,10 @@ export default class AdminSiteSettingsController extends Controller {
             setting.includes(filter) ||
             setting.replace(/_/g, " ").includes(filter) ||
             item.get("description").toLowerCase().includes(filter) ||
+            (item.get("keywords") || "")
+              .replace(/_/g, " ")
+              .toLowerCase()
+              .includes(filter.replace(/_/g, " ")) ||
             (item.get("value") || "").toString().toLowerCase().includes(filter);
           if (!filterResult && fuzzyRegex && fuzzyRegex.test(setting)) {
             // Tightens up fuzzy search results a bit.
diff --git a/app/assets/javascripts/discourse/tests/unit/controllers/admin-site-settings-test.js b/app/assets/javascripts/discourse/tests/unit/controllers/admin-site-settings-test.js
index f43630d5754..ddef6e1ac0a 100644
--- a/app/assets/javascripts/discourse/tests/unit/controllers/admin-site-settings-test.js
+++ b/app/assets/javascripts/discourse/tests/unit/controllers/admin-site-settings-test.js
@@ -34,6 +34,7 @@ module("Unit | Controller | admin-site-settings", function (hooks) {
             description: "",
             value: "",
             setting: "digest_logo",
+            keywords: "capybara",
           }),
           SiteSetting.create({
             description: "",
@@ -71,5 +72,10 @@ module("Unit | Controller | admin-site-settings", function (hooks) {
       results[0].siteSettings[0].setting,
       "min_personal_message_post_length"
     );
+
+    // ensures keyword search is working
+    results = controller.performSearch("capybara", settings2);
+    assert.deepEqual(results[0].siteSettings.length, 1);
+    assert.deepEqual(results[0].siteSettings[0].setting, "digest_logo");
   });
 });
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index a5e826ce538..9a720f64937 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -2521,6 +2521,9 @@ en:
       invalid_uncategorized_category_setting: 'The "Uncategorized" category cannot be selected if ''allow uncategorized topics'' is not enabled.'
       invalid_search_ranking_weights: "Value is invalid for search_ranking_weights site setting. Example: '{0.1,0.2,0.3,1.0}'. Note that maximum value for each weight is 1.0."
 
+    keywords:
+      anonymous_posting_allowed_groups: "anonymous_posting_min_trust_level"
+
     placeholder:
       discourse_connect_provider_secrets:
         key: "www.example.com"
diff --git a/lib/site_setting_extension.rb b/lib/site_setting_extension.rb
index 1af3640be77..8e02650786b 100644
--- a/lib/site_setting_extension.rb
+++ b/lib/site_setting_extension.rb
@@ -199,6 +199,7 @@ module SiteSettingExtension
         opts = {
           setting: s,
           description: description(s),
+          keywords: keywords(s),
           default: default,
           value: value.to_s,
           category: categories[s],
@@ -218,6 +219,10 @@ module SiteSettingExtension
     I18n.t("site_settings.#{setting}", base_path: Discourse.base_path)
   end
 
+  def keywords(setting)
+    I18n.t("site_settings.keywords.#{setting}", default: "")
+  end
+
   def placeholder(setting)
     if !I18n.t("site_settings.placeholder.#{setting}", default: "").empty?
       I18n.t("site_settings.placeholder.#{setting}")
diff --git a/spec/system/admin_site_setting_search_spec.rb b/spec/system/admin_site_setting_search_spec.rb
new file mode 100644
index 00000000000..85334a56a29
--- /dev/null
+++ b/spec/system/admin_site_setting_search_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+describe "Admin Site Setting Search", type: :system do
+  let(:settings_page) { PageObjects::Pages::AdminSettings.new }
+  fab!(:admin) { Fabricate(:admin) }
+
+  before do
+    SiteSetting.title = "Discourse"
+    sign_in(admin)
+  end
+
+  describe "when searching for keywords" do
+    it "finds the associated site setting" do
+      settings_page.visit
+      settings_page.type_in_search("anonymous_posting_min_trust_level")
+      expect(settings_page).to have_search_result("anonymous_posting_allowed_groups")
+    end
+
+    it "can search for previous site setting without underscores" do
+      settings_page.visit
+      settings_page.type_in_search("anonymous posting min")
+      expect(settings_page).to have_search_result("anonymous_posting_allowed_groups")
+    end
+  end
+end
diff --git a/spec/system/page_objects/pages/admin_settings.rb b/spec/system/page_objects/pages/admin_settings.rb
index c813ec6dd36..b38f414b9b5 100644
--- a/spec/system/page_objects/pages/admin_settings.rb
+++ b/spec/system/page_objects/pages/admin_settings.rb
@@ -4,7 +4,12 @@ module PageObjects
   module Pages
     class AdminSettings < PageObjects::Pages::Base
       def visit_filtered_plugin_setting(filter)
-        visit("/admin/site_settings/category/plugins?filter=#{filter}")
+        page.visit("/admin/site_settings/category/plugins?filter=#{filter}")
+        self
+      end
+
+      def visit
+        page.visit("/admin/site_settings")
         self
       end
 
@@ -34,6 +39,15 @@ module PageObjects
           .map { |e| vals << e.text }
         vals
       end
+
+      def type_in_search(input)
+        find("input#setting-filter").send_keys(input)
+        self
+      end
+
+      def has_search_result?(setting)
+        page.has_selector?("div[data-setting='#{setting}']")
+      end
     end
   end
 end