diff --git a/app/assets/javascripts/discourse/app/controllers/full-page-search.js b/app/assets/javascripts/discourse/app/controllers/full-page-search.js index 62188768484..1b9d41a6121 100644 --- a/app/assets/javascripts/discourse/app/controllers/full-page-search.js +++ b/app/assets/javascripts/discourse/app/controllers/full-page-search.js @@ -136,7 +136,7 @@ export default Controller.extend({ return (!skip && context) || skip === "false"; }, set(val) { - this.set("skip_context", val ? "false" : "true"); + this.set("skip_context", !val); }, }, diff --git a/app/assets/javascripts/discourse/tests/acceptance/search-mobile-test.js b/app/assets/javascripts/discourse/tests/acceptance/search-mobile-test.js index 2452d1ea8b6..46327959b6c 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/search-mobile-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/search-mobile-test.js @@ -47,4 +47,24 @@ acceptance("Search - Mobile", function (needs) { "it does not reset input when hitting search icon again" ); }); + + test("Search context in full page search", async function (assert) { + await visit("/search?context=tag&context_id=dev&skip_context=true"); + + assert.ok(exists(".search-header .search-context")); + + assert.strictEqual( + query(".search-header .search-context input[type='checkbox']").checked, + false, + "checkbox matches query parameter" + ); + + await click(".search-header .search-context label"); + + assert.strictEqual( + query(".search-header .search-context input[type='checkbox']").checked, + true, + "checkbox toggling works" + ); + }); }); diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index b2574d91660..521e52b6f13 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -215,7 +215,7 @@ class SearchController < ApplicationController search_context = params[:search_context] unless search_context if (context = params[:context]) && (id = params[:context_id]) - search_context = { type: context, id: id } + search_context = { type: context, id: id, name: id } end end @@ -234,7 +234,9 @@ class SearchController < ApplicationController elsif "topic" == search_context[:type] context_obj = Topic.find_by(id: search_context[:id].to_i) elsif "tag" == search_context[:type] - context_obj = Tag.where_name(search_context[:name]).first + if !DiscourseTagging.hidden_tag_names(guardian).include?(search_context[:id]) + context_obj = Tag.where_name(search_context[:id]).first + end end type_filter = nil diff --git a/spec/requests/search_controller_spec.rb b/spec/requests/search_controller_spec.rb index 7d35ab71f1d..fcedd413855 100644 --- a/spec/requests/search_controller_spec.rb +++ b/spec/requests/search_controller_spec.rb @@ -364,6 +364,61 @@ RSpec.describe SearchController do expect(SearchLog.where(term: "bantha")).to be_blank end + it "works when using a tag context" do + tag = Fabricate(:tag, name: "awesome") + awesome_topic.tags << tag + SearchIndexer.index(awesome_topic, force: true) + + get "/search.json", + params: { + q: "awesome", + context: "tag", + context_id: "awesome", + skip_context: false, + } + + expect(response.status).to eq(200) + expect(response.parsed_body["posts"].length).to eq(1) + expect(response.parsed_body["posts"][0]["id"]).to eq(awesome_post.id) + end + + context "with restricted tags" do + let(:restricted_tag) { Fabricate(:tag) } + let(:admin) { Fabricate(:admin) } + + before do + tag_group = + Fabricate(:tag_group, permissions: { "staff" => 1 }, tag_names: [restricted_tag.name]) + awesome_topic.tags << restricted_tag + SearchIndexer.index(awesome_topic, force: true) + end + + it "works for user with tag group permision" do + sign_in(admin) + get "/search.json", + params: { + q: "awesome", + context: "tag", + context_id: restricted_tag.name, + skip_context: false, + } + + expect(response.status).to eq(200) + end + + it "doesn’t work for user without tag group permission" do + get "/search.json", + params: { + q: "awesome", + context: "tag", + context_id: restricted_tag.name, + skip_context: false, + } + + expect(response.status).to eq(403) + end + end + context "when rate limited" do before { RateLimiter.enable }