Ticket #523: search_extension.diff
| File search_extension.diff, 15.0 kB (added by vitali, 11 months ago) |
|---|
-
vendor/extensions/search/test/unit/search_page_test.rb
old new 1 require File.dirname(__FILE__) + '/../test_helper' 2 3 class SearchPageTest < Test::Unit::TestCase 4 5 test_helper :render 6 fixtures :pages, :page_parts 7 8 def setup 9 @page = pages(:search) 10 11 @request = ActionController::TestRequest.new(:url => '/search/') 12 @response = ActionController::TestResponse.new 13 end 14 15 def test_search_simple_found 16 expected_result = [pages(:homepage)] 17 ['home', 'HOME', 'homE', 'home page'].each do |query| 18 @request.parameters[:q] = query 19 @page.process(@request, @response) 20 assert_response(:success) 21 assert(@page.query_result.eql?(expected_result)) 22 assert_equal(query, @page.query) 23 end 24 end 25 26 def test_search_in_title 27 query = @request.parameters[:q] = 'services title' 28 @page.process(@request, @response) 29 assert_response(:success) 30 assert(@page.query_result.eql?([pages(:services)])) 31 assert_equal(query, @page.query) 32 end 33 34 def test_search_blank 35 @page.process(@request, @response) 36 assert_response(:success) 37 assert(@page.query_result.empty?) 38 assert_equal("", @page.query) 39 end 40 41 def test_search_not_found 42 @request.parameters[:q] = 'not_existent_word' 43 @page.process(@request, @response) 44 assert_response(:success) 45 assert(@page.query_result.empty?) 46 end 47 48 def test_search_with_exclusion 49 search_page = pages(:search) 50 home_page = pages(:homepage) 51 # full result contains :homepage and :search 52 query = @request.parameters[:q] = 'page' 53 @page.process(@request, @response) 54 assert_response(:success) 55 assert(@page.query_result.eql?([home_page, search_page])) 56 # exclude :search 57 @request.parameters[:exclude_pages] = search_page.url 58 @page.process(@request, @response) 59 assert_response(:success) 60 assert(@page.query_result.eql?([home_page])) 61 # exclude multiple pages 62 @request.parameters[:exclude_pages] = search_page.url + "," + home_page.url 63 @page.process(@request, @response) 64 assert_response(:success) 65 assert(@page.query_result.eql?([])) 66 end 67 68 def test_ajax_search_renders_ajax_body 69 @request.parameters[:q] = 'home' 70 @request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest' 71 #assert(@request.xhr?) 72 @page.process(@request, @response) 73 assert_response(:success) 74 assert_equal(@page.render_part(:ajax_body), @response.body) 75 @page.part('ajax_body').destroy 76 @page.process(@request, @response) 77 assert_response(:success) 78 assert_equal(@page.render_part(:body), @response.body) 79 end 80 end -
vendor/extensions/search/test/unit/search_tags_test.rb
old new 1 require File.dirname(__FILE__) + '/../test_helper' 2 3 class SearchTagsTest < Test::Unit::TestCase 4 5 test_helper :render 6 fixtures :pages 7 8 def setup 9 @page = pages(:homepage) 10 end 11 12 def test_global_tags 13 assert_tag_defined @page, "search:form" 14 assert_tag_defined @page, "search:form:input" 15 end 16 17 def test_tag_search_form_minimal 18 assert_render_error "`search:form' tag must contain `action' attribute", "<r:search:form />" 19 assert_render_match %r{<form [^>]*action="/search/".*>}, "<r:search:form action='/search/'></r:search:form>" 20 assert_render_match %r{<form [^>]*action="/another_search/".*>}, "<r:search:form action='/another_search/'></r:search:form>" 21 end 22 23 def test_tag_search_form_with_custom_attributes 24 add_atts = {:action => "/search/", :id => "search_form", 25 :class => "default", :method => "get"} 26 27 add_atts.each do |att, value| 28 assert_render_match( 29 %r{<form [^>]*#{att}="#{value}".*>}, 30 "<r:search:form " + 31 add_atts.collect {|key, value| %{#{key}="#{value}"}}.join(" ") + 32 "/>" 33 ) 34 end 35 end 36 37 def test_tag_search_form_input 38 assert_render_error "`search:form' tag must contain `action' attribute", 39 "<r:search:form:input />" 40 assert_render_match %r{<input[\s]+type="text"[\s]+name="q"[\s]+id="q"[\s]+/>}, 41 %{<r:search:form action="/search/"><r:input /></r:search:form>} 42 end 43 44 def test_tag_search_form_input_with_custom_attributes 45 add_atts = {:id => "q", :size => 10, 46 :class => "query_input", :maxlength => 15} 47 48 add_atts.each do |att, value| 49 assert_render_match( 50 %r{<input[\s]+[^>]*#{att}="#{value}".*>}, 51 "<r:search:form action='/search/'><r:input " + 52 add_atts.collect {|key, value| %{#{key}="#{value}"}}.join(" ") + 53 "/></r:search:form>" 54 ) 55 end 56 end 57 58 def test_tag_search_form_input_with_restricted_attributes 59 add_atts = {:name => "blah", :type => "checkbox"} 60 61 add_atts.each do |att, value| 62 assert_render_error "`search:form:input' tag can't contain `#{att}' attribute", 63 %{<r:search:form action='/search/'><r:input #{att}="#{value}" /> 64 </r:search:form>} 65 end 66 end 67 68 def test_tag_search_form_input_with_custom_id 69 ids = ['my_id1', 'my_id2'] 70 ids.each do |id| 71 assert_render_match %r{<input[\s]+[^/>]*id="#{id}"[\s]+[^\>]*/>}, 72 %{<r:search:form action="/search/"><r:input id="#{id}" /> 73 </r:search:form>} 74 end 75 end 76 77 end -
vendor/extensions/search/test/functional/search_extension_test.rb
old new 10 10 end 11 11 12 12 def test_initialization 13 assert_equal RADIANT_ROOT + '/vendor/extensions/search', SearchExtension.root13 assert_equal File.join(File.expand_path(RAILS_ROOT), 'vendor', 'extensions', 'search'), SearchExtension.root 14 14 assert_equal 'Search', SearchExtension.extension_name 15 15 end 16 16 -
vendor/extensions/search/test/fixtures/pages.yml
old new 1 homepage: 2 id: 1 3 title: Ruby Home Page 4 breadcrumb: Home 5 slug: / 6 status_id: 100 7 parent_id: 8 published_at: 2006-01-30 08:41:07 9 search: 10 id: 2 11 title: Search 12 slug: search 13 status_id: 100 14 parent_id: 1 15 published_at: 2006-02-05 08:44:07 16 class_name: SearchPage 17 services: 18 id: 3 19 title: Services Title 20 slug: services 21 status_id: 100 22 parent_id: 1 23 published_at: 2006-02-05 08:44:07 -
vendor/extensions/search/test/fixtures/page_parts.yml
old new 1 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 homepage_body: 3 id: 1 4 name: body 5 content: This is the body portion of the Ruby home page. 6 page_id: 1 7 homepage_extended: 8 id: 2 9 name: extended 10 content: This is an extended portion of the Ruby home page. 11 page_id: 1 12 search_body: 13 id: 3 14 name: body 15 content: This is the body of the Search page. 16 page_id: 2 17 services_body: 18 id: 4 19 name: body 20 content: We provide great services. 21 page_id: 3 22 search_ajax_body: 23 id: 5 24 name: ajax_body 25 content: AJAX body of the Search page. 26 page_id: 2 -
vendor/extensions/search/app/models/search_page.rb
old new 7 7 tag.expand 8 8 end 9 9 10 desc %{ <r:search:form [label="Search:"] />11 Renders a search form, with the optional label.}12 tag 'search:form' do |tag|13 label = tag.attr['label'].nil? ? "Search:" : tag.attr['label']14 content = %{<form action="#{self.url.chop}" method="get" id="search_form"><p><label for="q">#{label}</label> <input type="text" id="q" name="q" value="" size="15" /></p></form>}15 content << "\n"16 end10 # desc %{ <r:search:form [label="Search:"] /> 11 # Renders a search form, with the optional label.} 12 # tag 'search:form' do |tag| 13 # label = tag.attr['label'].nil? ? "Search:" : tag.attr['label'] 14 # content = %{<form action="#{self.url.chop}" method="get" id="search_form"><p><label for="q">#{label}</label> <input type="text" id="q" name="q" value="" size="15" /></p></form>} 15 # content << "\n" 16 # end 17 17 18 18 desc %{ Renders the passed query.} 19 19 tag 'search:query' do |tag| … … 64 64 @query_result = [] 65 65 @query = "" 66 66 q = @request.parameters[:q] 67 exclude_pages = (@request.parameters[:exclude_pages] || '').split(",") 67 68 unless (@query = q.to_s.strip).blank? 68 69 tokens = query.split.collect { |c| "%#{c.downcase}%"} 69 70 pages = Page.find(:all, :include => [ :parts ], 70 71 :conditions => [(["((LOWER(content) LIKE ?) OR (LOWER(title) LIKE ?))"] * tokens.size).join(" AND "), 71 72 *tokens.collect { |token| [token] * 2 }.flatten]) 72 @query_result = pages.delete_if { |p| !p.published? } 73 @query_result = pages.delete_if { |p| !p.published? || 74 exclude_pages.include?(p.url) } 73 75 end 74 lazy_initialize_parser_and_context 75 if layout 76 parse_object(layout) 76 77 if @request.xhr? 78 if part :ajax_body 79 render_part :ajax_body 80 else 81 render_part :body 82 end 77 83 else 78 render_page_part(:body)84 super 79 85 end 80 86 end 81 87 -
vendor/extensions/search/app/models/search_tags.rb
old new 1 module SearchTags 2 include Radiant::Taggable 3 4 desc %{ The namespace for all search tags.} 5 tag 'search' do |tag| 6 tag.expand 7 end 8 9 desc %{ Outputs <form> element of the search form. 10 <r:search:form action="controller_url"[ ajax_results="element_id"[ ajax_delay="500"]][exclude_pages="/url/1/,/url/2/"]> 11 12 action - url to the page of type Search that will handle search request 13 ajax_results - if you want your form to be AJAX enabled, specify ID of element that will contain search results 14 ajax_delay - time of inactivity before search request submitted to the server 15 exclude_pages - comma separated list of page URLs to exclude from results. Don't forget trailing slashes 16 17 Any additional parameters will be added to the tag as attributes. 18 If you use AJAX enabled form you can have separate page part for displaying AJAX results. It should be called `ajax_body'. 19 20 *Usage:* 21 <pre><code><r:search:form action="controller_url"> 22 <r:search:form:input /> 23 <input type="submit" /> 24 ... 25 </r:search:form></code></pre> 26 } 27 tag 'search:form' do |tag| 28 unless action = tag.attr['action'] 29 raise StandardTags::TagError.new("`search:form' tag must contain `action' attribute") 30 end 31 result_id = tag.attr['ajax_results'] || nil 32 ajax_delay = tag.attr['ajax_delay'] || 500 33 exclude_pages = tag.attr['exclude_pages'] || '' 34 int_attrs = ['ajax_results', 'ajax_delay', 'exclude_pages'] 35 output = %{<form method="get"} + 36 tag.attr.delete_if {|key, value| int_attrs.include?(key) 37 }.collect {|key, value| %{#{key}="#{value}"}}.join(" ") + 38 %{> 39 <input type="hidden" name="exclude_pages" value="#{exclude_pages}" /> 40 #{tag.expand} 41 </form>} 42 # if result_id not given, skip AJAX form init 43 return output if result_id.nil? 44 # otherwise init AJAX 45 output << %{ <script type="text/javascript"> 46 var search_previous_value = ''; 47 var search_handler; 48 Event.observe("q", "keyup", function(ev){ 49 clearTimeout(search_handler); 50 search_form = Event.findElement(ev, 'form'); 51 search_handler = setTimeout(function(ev){ 52 if (this.getValue() == search_previous_value) { return; } 53 search_previous_value = this.getValue(); 54 new Ajax.Updater("#{result_id}", search_form.action, { 55 parameters: $(search_form).serialize(true), 56 evalScripts: true, 57 onLoading: function(){ 58 search_form.addClassName('loading'); 59 }, 60 onComplete: function(){ 61 search_form.removeClassName('loading'); 62 $("#{result_id}").show(); 63 } 64 }); 65 }.bind(this, ev), #{ajax_delay}); 66 }.bindAsEventListener($('q'))); 67 </script> 68 } 69 end 70 71 desc %{ Outputs input element for search form. All additional parameters will 72 be added as tag attributes. However don't use type and name. ID attribute 73 can be overwritten} 74 tag 'search:form:input' do |tag| 75 ["type", "name"].each do |attr| 76 if tag.attr[attr] 77 raise StandardTags::TagError.new("`search:form:input' tag can't contain `#{attr}' attribute") 78 end 79 end 80 81 tag_id = tag.attr['id'] || "q" 82 83 output = %{<input type="text" name="q" id="#{tag_id}" } + 84 tag.attr.delete_if {|attr, value| attr == 'id' 85 }.collect {|key, value| %{#{key}="#{value}"}}.join(" ") + 86 "/>" 87 end 88 89 end -
vendor/extensions/search/search_extension.rb
old new 9 9 10 10 def activate 11 11 # admin.tabs.add "Search", "/admin/search", :after => "Layouts", :visibility => [:all] 12 Page.send :include, SearchTags 12 13 SearchPage 13 14 end 14 15
