diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 7dc0421b6f9..e3dd2158862 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -8,9 +8,12 @@ class SearchController < ApplicationController def query params.require(:term) - + search_args = {guardian: guardian} search_args[:type_filter] = params[:type_filter] if params[:type_filter].present? + if params[:include_blurbs].present? + search_args[:include_blurbs] = params[:include_blurbs] == "true" + end search_context = params[:search_context] if search_context.present? diff --git a/lib/search.rb b/lib/search.rb index 7b2c270caf9..8c45f9eed4d 100644 --- a/lib/search.rb +++ b/lib/search.rb @@ -44,6 +44,7 @@ class Search @opts = opts || {} @guardian = @opts[:guardian] || Guardian.new @search_context = @opts[:search_context] + @include_blurbs = @opts[:include_blurbs] || false @limit = Search.per_facet * Search.facets.size @results = GroupedSearchResults.new(@opts[:type_filter]) @@ -101,7 +102,7 @@ class Search extra_posts = posts_query(expected_topics * Search.burst_factor) extra_posts = extra_posts.where("posts.topic_id NOT in (?)", @results.topic_ids) if @results.topic_ids.present? extra_posts.each do |p| - @results.add_result(SearchResult.from_post(p, @search_context, @term)) + @results.add_result(SearchResult.from_post(p, @search_context, @term, @include_blurbs)) end end end @@ -213,7 +214,7 @@ class Search posts.each do |p| - @results.add_result(SearchResult.from_post(p, @search_context, @term)) + @results.add_result(SearchResult.from_post(p, @search_context, @term, @include_blurbs)) end end diff --git a/lib/search/search_result.rb b/lib/search/search_result.rb index 7f24b7853f1..01e3dbf2527 100644 --- a/lib/search/search_result.rb +++ b/lib/search/search_result.rb @@ -5,7 +5,7 @@ class Search extend ActionView::Helpers::TextHelper end - attr_accessor :type, :id, :topic_id + attr_accessor :type, :id, :topic_id, :blurb # Category attributes attr_accessor :color, :text_color @@ -16,7 +16,7 @@ class Search def initialize(row) row.symbolize_keys! @type = row[:type].to_sym - @url, @id, @title, @topic_id = row[:url], row[:id], row[:title], row[:topic_id] + @url, @id, @title, @topic_id, @blurb = row[:url], row[:id], row[:title], row[:topic_id], row[:blurb] end def as_json(options = nil) @@ -24,6 +24,7 @@ class Search json[:avatar_template] = @avatar_template if @avatar_template.present? json[:color] = @color if @color.present? json[:text_color] = @text_color if @text_color.present? + json[:blurb] = @blurb if @blurb.present? json end @@ -40,11 +41,11 @@ class Search end end - def self.from_topic(t, custom_title=nil) - SearchResult.new(type: :topic, topic_id: t.id, id: t.id, title: custom_title || t.title, url: t.relative_url) + def self.from_topic(t, options = {}) + SearchResult.new(type: :topic, topic_id: t.id, id: t.id, title: options[:custom_title] || t.title, url: t.relative_url, blurb: options[:custom_blurb]) end - def self.from_post(p, context, term) + def self.from_post(p, context, term, include_blurbs=false) custom_title = if context && context.id == p.topic_id # TODO: rewrite this @@ -58,14 +59,18 @@ class Search excerpt: excerpt ) end - + if include_blurbs + #add a blurb from the post to the search results + custom_blurb = TextHelper.excerpt(p.raw, term.split(/\s+/)[0], radius: 100) + custom_blurb = TextHelper.truncate(p.raw, length: 200) if custom_blurb.blank? + end if p.post_number == 1 # we want the topic link when it's the OP - SearchResult.from_topic(p.topic, custom_title) + SearchResult.from_topic(p.topic, {custom_title: custom_title, custom_blurb: custom_blurb}) elsif context && context.id == p.topic_id - SearchResult.new(type: :topic, topic_id: p.topic_id, id: "_#{p.id}", title: custom_title, url: p.url) + SearchResult.new(type: :topic, topic_id: p.topic_id, id: "_#{p.id}", title: custom_title, url: p.url, blurb: custom_blurb) else - SearchResult.new(type: :topic, topic_id: p.topic_id, id: p.topic.id, title: p.topic.title, url: p.url) + SearchResult.new(type: :topic, topic_id: p.topic_id, id: p.topic.id, title: p.topic.title, url: p.url, blurb: custom_blurb) end end diff --git a/spec/components/search_spec.rb b/spec/components/search_spec.rb index 0f4bbb16a57..72d177bfa0f 100644 --- a/spec/components/search_spec.rb +++ b/spec/components/search_spec.rb @@ -5,6 +5,10 @@ require_dependency 'search' describe Search do + class TextHelper + extend ActionView::Helpers::TextHelper + end + before do ActiveRecord::Base.observers.enable :search_observer end @@ -175,13 +179,14 @@ describe Search do end context 'searching the OP' do - let!(:post) { Fabricate(:post, topic: topic, user: topic.user) } - let(:result) { first_of_type(Search.new('hello', type_filter: 'topic').execute, 'topic') } + let!(:post) { Fabricate(:post_with_long_raw_content, topic: topic, user: topic.user) } + let(:result) { first_of_type(Search.new('hundred', type_filter: 'topic', include_blurbs: true).execute, 'topic') } it 'returns a result correctly' do result.should be_present result[:title].should == topic.title result[:url].should == topic.relative_url + result[:blurb].should == TextHelper.excerpt(post.raw, 'hundred', radius: 100) end end diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb index 0fb8442bec4..e51297860ef 100644 --- a/spec/controllers/search_controller_spec.rb +++ b/spec/controllers/search_controller_spec.rb @@ -26,6 +26,17 @@ describe SearchController do 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 it "raises an error with an invalid context type" do diff --git a/spec/fabricators/post_fabricator.rb b/spec/fabricators/post_fabricator.rb index c8e116e62f4..5c1721e125e 100644 --- a/spec/fabricators/post_fabricator.rb +++ b/spec/fabricators/post_fabricator.rb @@ -4,6 +4,12 @@ Fabricator(:post) do raw "Hello world" end +Fabricator(:post_with_long_raw_content, from: :post) do + raw 'This is a sample post with semi-long raw content. The raw content is also more than + two hundred characters to satisfy any test conditions that require content longer + than the typical test post raw content.' +end + Fabricator(:post_with_youtube, from: :post) do cooked '
' end