From 20840c341fca220d32af249d479949d2f35579cd Mon Sep 17 00:00:00 2001
From: Alan Guo Xiang Tan <gxtan1990@gmail.com>
Date: Thu, 17 Aug 2023 09:04:48 +0800
Subject: [PATCH] FIX: `/filter` route input field not updating on route change
 (#23119)

What is the problem here?

When transiting between `/filter` routes with different `q` query
params, the input field is not updating to include the values in the `q`
query param. This was because we were setting the value of the input
field in the constructor of the controller but controllers are actually
singletons in Ember so setting the value of the input field is only done
once when the controller is initialised.

What is the fix here?

Instead of setting the value of the input field in the controller, we
set the value in the `setupController` hook in the route file.
---
 .../app/controllers/navigation/filter.js      |  5 ---
 .../discourse/app/routes/discovery-filter.js  |  4 +++
 spec/system/filtering_topics_spec.rb          | 36 +++++++++++++++++++
 .../components/topic_query_filter.rb          |  4 +++
 4 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/app/assets/javascripts/discourse/app/controllers/navigation/filter.js b/app/assets/javascripts/discourse/app/controllers/navigation/filter.js
index d58c65742d2..c3cddc6a5e3 100644
--- a/app/assets/javascripts/discourse/app/controllers/navigation/filter.js
+++ b/app/assets/javascripts/discourse/app/controllers/navigation/filter.js
@@ -11,11 +11,6 @@ export default class NavigationFilterController extends Controller {
   @tracked copyClass = "btn-default";
   @tracked newQueryString = "";
 
-  constructor() {
-    super(...arguments);
-    this.newQueryString = this.discoveryFilter.q;
-  }
-
   @bind
   updateQueryString(string) {
     this.newQueryString = string;
diff --git a/app/assets/javascripts/discourse/app/routes/discovery-filter.js b/app/assets/javascripts/discourse/app/routes/discovery-filter.js
index 6acba08f91d..1497677ac73 100644
--- a/app/assets/javascripts/discourse/app/routes/discovery-filter.js
+++ b/app/assets/javascripts/discourse/app/routes/discovery-filter.js
@@ -22,6 +22,10 @@ export default class DiscoveryFilterRoute extends DiscourseRoute {
 
   setupController(_controller, model) {
     this.controllerFor("discovery/topics").setProperties({ model });
+
+    this.controllerFor("navigation/filter").setProperties({
+      newQueryString: this.paramsFor("discovery.filter").q,
+    });
   }
 
   renderTemplate() {
diff --git a/spec/system/filtering_topics_spec.rb b/spec/system/filtering_topics_spec.rb
index a5e4adc0a37..7e90ca86534 100644
--- a/spec/system/filtering_topics_spec.rb
+++ b/spec/system/filtering_topics_spec.rb
@@ -4,9 +4,45 @@ describe "Filtering topics", type: :system do
   fab!(:user) { Fabricate(:user) }
   let(:topic_list) { PageObjects::Components::TopicList.new }
   let(:topic_query_filter) { PageObjects::Components::TopicQueryFilter.new }
+  let(:sidebar) { PageObjects::Components::NavigationMenu::Sidebar.new }
 
   before { SiteSetting.experimental_topics_filter = true }
 
+  it "updates the input field when the query string is changed" do
+    sidebar_section = Fabricate(:sidebar_section, user: user)
+
+    sidebar_section_link_1 =
+      Fabricate(
+        :sidebar_section_link,
+        sidebar_section: sidebar_section,
+        linkable: Fabricate(:sidebar_url, name: "filter tags", value: "/filter?q=tag%3Atag1"),
+      )
+
+    sidebar_section_link_2 =
+      Fabricate(
+        :sidebar_section_link,
+        sidebar_section: sidebar_section,
+        linkable:
+          Fabricate(
+            :sidebar_url,
+            name: "filter categories",
+            value: "/filter?q=category%3Acategory1",
+          ),
+      )
+
+    sign_in(user)
+
+    visit("/latest")
+
+    sidebar.click_section_link("filter tags")
+
+    expect(topic_query_filter).to have_input_text("tag:tag1")
+
+    sidebar.click_section_link("filter categories")
+
+    expect(topic_query_filter).to have_input_text("category:category1")
+  end
+
   describe "when filtering by status" do
     fab!(:topic) { Fabricate(:topic) }
     fab!(:closed_topic) { Fabricate(:topic, closed: true) }
diff --git a/spec/system/page_objects/components/topic_query_filter.rb b/spec/system/page_objects/components/topic_query_filter.rb
index d99b4d4d52a..46780658ce1 100644
--- a/spec/system/page_objects/components/topic_query_filter.rb
+++ b/spec/system/page_objects/components/topic_query_filter.rb
@@ -6,6 +6,10 @@ module PageObjects
       def fill_in(text)
         page.fill_in(class: "topic-query-filter__filter-term", with: "#{text}\n")
       end
+
+      def has_input_text?(text)
+        page.has_field?(class: "topic-query-filter__filter-term", with: text)
+      end
     end
   end
 end