diff --git a/app/assets/javascripts/discourse/lib/search.js b/app/assets/javascripts/discourse/lib/search.js index a64f90d0777..512213d02ad 100644 --- a/app/assets/javascripts/discourse/lib/search.js +++ b/app/assets/javascripts/discourse/lib/search.js @@ -23,6 +23,7 @@ Discourse.Search = { // Only include the data we have var data = { term: term }; if (opts.typeFilter) data.type_filter = opts.typeFilter; + if (opts.searchForId) data.search_for_id = true; if (opts.searchContext) { data.search_context = { diff --git a/app/assets/javascripts/discourse/views/choose-topic.js.es6 b/app/assets/javascripts/discourse/views/choose-topic.js.es6 index c5f3cc9e582..70cb7a8103f 100644 --- a/app/assets/javascripts/discourse/views/choose-topic.js.es6 +++ b/app/assets/javascripts/discourse/views/choose-topic.js.es6 @@ -30,7 +30,7 @@ export default Discourse.View.extend({ self.setProperties({ topics: null, loading: false }); return; } - Discourse.Search.forTerm(title, {typeFilter: 'topic'}).then(function (facets) { + Discourse.Search.forTerm(title, {typeFilter: 'topic', searchForId: true}).then(function (facets) { if (facets && facets[0] && facets[0].results) { self.set('topics', facets[0].results); } else { diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index bcf0e7fe9d5..57aa7a1fd46 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -14,6 +14,7 @@ class SearchController < ApplicationController if params[:include_blurbs].present? search_args[:include_blurbs] = params[:include_blurbs] == "true" end + search_args[:search_for_id] = true if params[:search_for_id].present? search_context = params[:search_context] if search_context.present? diff --git a/lib/search.rb b/lib/search.rb index 0be363c47fc..0dc1535a370 100644 --- a/lib/search.rb +++ b/lib/search.rb @@ -111,7 +111,8 @@ class Search return nil if @term.blank? || @term.length < (@opts[:min_search_term_length] || SiteSetting.min_search_term_length) # If the term is a number or url to a topic, just include that topic - if @results.type_filter == 'topic' + if @opts[:search_for_id] && @results.type_filter == 'topic' + return single_topic(@term.to_i).as_json if @term =~ /^\d+$/ begin route = Rails.application.routes.recognize_path(@term) return single_topic(route[:topic_id]).as_json if route[:topic_id].present? diff --git a/spec/components/search_spec.rb b/spec/components/search_spec.rb index 3fb68152e67..b2f9a2d66ef 100644 --- a/spec/components/search_spec.rb +++ b/spec/components/search_spec.rb @@ -191,8 +191,18 @@ describe Search do end end + context "search for a topic by id" do + let(:result) { first_of_type(Search.new(topic.id, type_filter: 'topic', search_for_id: true, min_search_term_length: 1).execute, 'topic') } + + it 'returns the topic' do + result.should be_present + result[:title].should == topic.title + result[:url].should == topic.relative_url + end + end + context "search for a topic by url" do - let(:result) { first_of_type(Search.new(topic.relative_url, type_filter: 'topic').execute, 'topic') } + let(:result) { first_of_type(Search.new(topic.relative_url, search_for_id: true, type_filter: 'topic').execute, 'topic') } it 'returns the topic' do result.should be_present diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb index e51297860ef..b93cf7de9dd 100644 --- a/spec/controllers/search_controller_spec.rb +++ b/spec/controllers/search_controller_spec.rb @@ -4,38 +4,43 @@ describe SearchController do let(:search_context) { {type: 'user', id: 'eviltrout'} } - it 'performs the query' do - guardian = Guardian.new - Guardian.stubs(:new).returns(guardian) + context "basics" do + let(:guardian) { Guardian.new } + let(:search) { mock() } - search = mock() - Search.expects(:new).with('test', guardian: guardian).returns(search) - search.expects(:execute) + before do + Guardian.stubs(:new).returns(guardian) + end - xhr :get, :query, term: 'test' + it 'performs the query' do + Search.expects(:new).with('test', guardian: guardian).returns(search) + search.expects(:execute) + + xhr :get, :query, term: 'test' + end + + it 'performs the query with a filter' do + Search.expects(:new).with('test', guardian: guardian, type_filter: 'topic').returns(search) + search.expects(:execute) + + xhr :get, :query, term: 'test', type_filter: 'topic' + end + + it "performs the query and returns results including blurbs" do + Search.expects(:new).with('test', guardian: guardian, include_blurbs: true).returns(search) + search.expects(:execute) + + xhr :get, :query, term: 'test', include_blurbs: 'true' + end + + it 'performs the query with a filter and passes through search_for_id' do + Search.expects(:new).with('test', guardian: guardian, search_for_id: true, type_filter: 'topic').returns(search) + search.expects(:execute) + + xhr :get, :query, term: 'test', type_filter: 'topic', search_for_id: true + end end - it 'performs the query with a filter' do - guardian = Guardian.new - Guardian.stubs(:new).returns(guardian) - - search = mock() - Search.expects(:new).with('test', guardian: guardian, type_filter: 'topic').returns(search) - search.expects(:execute) - - xhr :get, :query, term: 'test', type_filter: 'topic' - end - - it "performs the query and returns results including blurbs" do - guardian = Guardian.new - Guardian.stubs(:new).returns(guardian) - - search = mock() - Search.expects(:new).with('test', guardian: guardian, include_blurbs: true).returns(search) - search.expects(:execute) - - xhr :get, :query, term: 'test', include_blurbs: 'true' - end context "search context" do