##// END OF EJS Templates
Fixed that search results are escaped twice....
Jean-Philippe Lang -
r10002:8b12702ebef2
parent child
Show More
@@ -1,52 +1,52
1 <h2><%= l(:label_search) %></h2>
1 <h2><%= l(:label_search) %></h2>
2
2
3 <div class="box">
3 <div class="box">
4 <%= form_tag({}, :method => :get) do %>
4 <%= form_tag({}, :method => :get) do %>
5 <%= label_tag "search-input", l(:description_search), :class => "hidden-for-sighted" %>
5 <%= label_tag "search-input", l(:description_search), :class => "hidden-for-sighted" %>
6 <p><%= text_field_tag 'q', @question, :size => 60, :id => 'search-input' %>
6 <p><%= text_field_tag 'q', @question, :size => 60, :id => 'search-input' %>
7 <%= javascript_tag "$('#search-input').focus()" %>
7 <%= javascript_tag "$('#search-input').focus()" %>
8 <%= project_select_tag %>
8 <%= project_select_tag %>
9 <%= hidden_field_tag 'all_words', '', :id => nil %>
9 <%= hidden_field_tag 'all_words', '', :id => nil %>
10 <label><%= check_box_tag 'all_words', 1, @all_words %> <%= l(:label_all_words) %></label>
10 <label><%= check_box_tag 'all_words', 1, @all_words %> <%= l(:label_all_words) %></label>
11 <%= hidden_field_tag 'titles_only', '', :id => nil %>
11 <%= hidden_field_tag 'titles_only', '', :id => nil %>
12 <label><%= check_box_tag 'titles_only', 1, @titles_only %> <%= l(:label_search_titles_only) %></label>
12 <label><%= check_box_tag 'titles_only', 1, @titles_only %> <%= l(:label_search_titles_only) %></label>
13 </p>
13 </p>
14 <p>
14 <p>
15 <% @object_types.each do |t| %>
15 <% @object_types.each do |t| %>
16 <label><%= check_box_tag t, 1, @scope.include?(t) %> <%= type_label(t) %></label>
16 <label><%= check_box_tag t, 1, @scope.include?(t) %> <%= type_label(t) %></label>
17 <% end %>
17 <% end %>
18 </p>
18 </p>
19
19
20 <p><%= submit_tag l(:button_submit), :name => 'submit' %></p>
20 <p><%= submit_tag l(:button_submit), :name => 'submit' %></p>
21 <% end %>
21 <% end %>
22 </div>
22 </div>
23
23
24 <% if @results %>
24 <% if @results %>
25 <div id="search-results-counts">
25 <div id="search-results-counts">
26 <%= render_results_by_type(@results_by_type) unless @scope.size == 1 %>
26 <%= render_results_by_type(@results_by_type) unless @scope.size == 1 %>
27 </div>
27 </div>
28
28
29 <h3><%= l(:label_result_plural) %> (<%= @results_by_type.values.sum %>)</h3>
29 <h3><%= l(:label_result_plural) %> (<%= @results_by_type.values.sum %>)</h3>
30 <dl id="search-results">
30 <dl id="search-results">
31 <% @results.each do |e| %>
31 <% @results.each do |e| %>
32 <dt class="<%= e.event_type %>"><%= content_tag('span', h(e.project), :class => 'project') unless @project == e.project %> <%= link_to highlight_tokens(truncate(h(e.event_title), :length => 255), @tokens), e.event_url %></dt>
32 <dt class="<%= e.event_type %>"><%= content_tag('span', h(e.project), :class => 'project') unless @project == e.project %> <%= link_to highlight_tokens(truncate(e.event_title, :length => 255), @tokens), e.event_url %></dt>
33 <dd><span class="description"><%= highlight_tokens(h(e.event_description), @tokens) %></span>
33 <dd><span class="description"><%= highlight_tokens(e.event_description, @tokens) %></span>
34 <span class="author"><%= format_time(e.event_datetime) %></span></dd>
34 <span class="author"><%= format_time(e.event_datetime) %></span></dd>
35 <% end %>
35 <% end %>
36 </dl>
36 </dl>
37 <% end %>
37 <% end %>
38
38
39 <p><center>
39 <p><center>
40 <% if @pagination_previous_date %>
40 <% if @pagination_previous_date %>
41 <%= link_to_content_update("\xc2\xab " + l(:label_previous),
41 <%= link_to_content_update("\xc2\xab " + l(:label_previous),
42 params.merge(:previous => 1,
42 params.merge(:previous => 1,
43 :offset => @pagination_previous_date.strftime("%Y%m%d%H%M%S"))) %>&nbsp;
43 :offset => @pagination_previous_date.strftime("%Y%m%d%H%M%S"))) %>&nbsp;
44 <% end %>
44 <% end %>
45 <% if @pagination_next_date %>
45 <% if @pagination_next_date %>
46 <%= link_to_content_update(l(:label_next) + " \xc2\xbb",
46 <%= link_to_content_update(l(:label_next) + " \xc2\xbb",
47 params.merge(:previous => nil,
47 params.merge(:previous => nil,
48 :offset => @pagination_next_date.strftime("%Y%m%d%H%M%S"))) %>
48 :offset => @pagination_next_date.strftime("%Y%m%d%H%M%S"))) %>
49 <% end %>
49 <% end %>
50 </center></p>
50 </center></p>
51
51
52 <% html_title(l(:label_search)) -%>
52 <% html_title(l(:label_search)) -%>
@@ -1,202 +1,222
1 require File.expand_path('../../test_helper', __FILE__)
1 require File.expand_path('../../test_helper', __FILE__)
2 require 'search_controller'
2 require 'search_controller'
3
3
4 # Re-raise errors caught by the controller.
4 # Re-raise errors caught by the controller.
5 class SearchController; def rescue_action(e) raise e end; end
5 class SearchController; def rescue_action(e) raise e end; end
6
6
7 class SearchControllerTest < ActionController::TestCase
7 class SearchControllerTest < ActionController::TestCase
8 fixtures :projects, :enabled_modules, :roles, :users, :members, :member_roles,
8 fixtures :projects, :enabled_modules, :roles, :users, :members, :member_roles,
9 :issues, :trackers, :issue_statuses,
9 :issues, :trackers, :issue_statuses,
10 :custom_fields, :custom_values,
10 :custom_fields, :custom_values,
11 :repositories, :changesets
11 :repositories, :changesets
12
12
13 def setup
13 def setup
14 @controller = SearchController.new
14 @controller = SearchController.new
15 @request = ActionController::TestRequest.new
15 @request = ActionController::TestRequest.new
16 @response = ActionController::TestResponse.new
16 @response = ActionController::TestResponse.new
17 User.current = nil
17 User.current = nil
18 end
18 end
19
19
20 def test_search_for_projects
20 def test_search_for_projects
21 get :index
21 get :index
22 assert_response :success
22 assert_response :success
23 assert_template 'index'
23 assert_template 'index'
24
24
25 get :index, :q => "cook"
25 get :index, :q => "cook"
26 assert_response :success
26 assert_response :success
27 assert_template 'index'
27 assert_template 'index'
28 assert assigns(:results).include?(Project.find(1))
28 assert assigns(:results).include?(Project.find(1))
29 end
29 end
30
30
31 def test_search_all_projects
31 def test_search_all_projects
32 get :index, :q => 'recipe subproject commit', :all_words => ''
32 get :index, :q => 'recipe subproject commit', :all_words => ''
33 assert_response :success
33 assert_response :success
34 assert_template 'index'
34 assert_template 'index'
35
35
36 assert assigns(:results).include?(Issue.find(2))
36 assert assigns(:results).include?(Issue.find(2))
37 assert assigns(:results).include?(Issue.find(5))
37 assert assigns(:results).include?(Issue.find(5))
38 assert assigns(:results).include?(Changeset.find(101))
38 assert assigns(:results).include?(Changeset.find(101))
39 assert_tag :dt, :attributes => { :class => /issue/ },
39 assert_tag :dt, :attributes => { :class => /issue/ },
40 :child => { :tag => 'a', :content => /Add ingredients categories/ },
40 :child => { :tag => 'a', :content => /Add ingredients categories/ },
41 :sibling => { :tag => 'dd', :content => /should be classified by categories/ }
41 :sibling => { :tag => 'dd', :content => /should be classified by categories/ }
42
42
43 assert assigns(:results_by_type).is_a?(Hash)
43 assert assigns(:results_by_type).is_a?(Hash)
44 assert_equal 5, assigns(:results_by_type)['changesets']
44 assert_equal 5, assigns(:results_by_type)['changesets']
45 assert_tag :a, :content => 'Changesets (5)'
45 assert_tag :a, :content => 'Changesets (5)'
46 end
46 end
47
47
48 def test_search_issues
48 def test_search_issues
49 get :index, :q => 'issue', :issues => 1
49 get :index, :q => 'issue', :issues => 1
50 assert_response :success
50 assert_response :success
51 assert_template 'index'
51 assert_template 'index'
52
52
53 assert_equal true, assigns(:all_words)
53 assert_equal true, assigns(:all_words)
54 assert_equal false, assigns(:titles_only)
54 assert_equal false, assigns(:titles_only)
55 assert assigns(:results).include?(Issue.find(8))
55 assert assigns(:results).include?(Issue.find(8))
56 assert assigns(:results).include?(Issue.find(5))
56 assert assigns(:results).include?(Issue.find(5))
57 assert_tag :dt, :attributes => { :class => /issue closed/ },
57 assert_tag :dt, :attributes => { :class => /issue closed/ },
58 :child => { :tag => 'a', :content => /Closed/ }
58 :child => { :tag => 'a', :content => /Closed/ }
59 end
59 end
60
60
61 def test_search_all_projects_with_scope_param
61 def test_search_all_projects_with_scope_param
62 get :index, :q => 'issue', :scope => 'all'
62 get :index, :q => 'issue', :scope => 'all'
63 assert_response :success
63 assert_response :success
64 assert_template 'index'
64 assert_template 'index'
65 assert assigns(:results).present?
65 assert assigns(:results).present?
66 end
66 end
67
67
68 def test_search_my_projects
68 def test_search_my_projects
69 @request.session[:user_id] = 2
69 @request.session[:user_id] = 2
70 get :index, :id => 1, :q => 'recipe subproject', :scope => 'my_projects', :all_words => ''
70 get :index, :id => 1, :q => 'recipe subproject', :scope => 'my_projects', :all_words => ''
71 assert_response :success
71 assert_response :success
72 assert_template 'index'
72 assert_template 'index'
73 assert assigns(:results).include?(Issue.find(1))
73 assert assigns(:results).include?(Issue.find(1))
74 assert !assigns(:results).include?(Issue.find(5))
74 assert !assigns(:results).include?(Issue.find(5))
75 end
75 end
76
76
77 def test_search_my_projects_without_memberships
77 def test_search_my_projects_without_memberships
78 # anonymous user has no memberships
78 # anonymous user has no memberships
79 get :index, :id => 1, :q => 'recipe subproject', :scope => 'my_projects', :all_words => ''
79 get :index, :id => 1, :q => 'recipe subproject', :scope => 'my_projects', :all_words => ''
80 assert_response :success
80 assert_response :success
81 assert_template 'index'
81 assert_template 'index'
82 assert assigns(:results).empty?
82 assert assigns(:results).empty?
83 end
83 end
84
84
85 def test_search_project_and_subprojects
85 def test_search_project_and_subprojects
86 get :index, :id => 1, :q => 'recipe subproject', :scope => 'subprojects', :all_words => ''
86 get :index, :id => 1, :q => 'recipe subproject', :scope => 'subprojects', :all_words => ''
87 assert_response :success
87 assert_response :success
88 assert_template 'index'
88 assert_template 'index'
89 assert assigns(:results).include?(Issue.find(1))
89 assert assigns(:results).include?(Issue.find(1))
90 assert assigns(:results).include?(Issue.find(5))
90 assert assigns(:results).include?(Issue.find(5))
91 end
91 end
92
92
93 def test_search_without_searchable_custom_fields
93 def test_search_without_searchable_custom_fields
94 CustomField.update_all "searchable = #{ActiveRecord::Base.connection.quoted_false}"
94 CustomField.update_all "searchable = #{ActiveRecord::Base.connection.quoted_false}"
95
95
96 get :index, :id => 1
96 get :index, :id => 1
97 assert_response :success
97 assert_response :success
98 assert_template 'index'
98 assert_template 'index'
99 assert_not_nil assigns(:project)
99 assert_not_nil assigns(:project)
100
100
101 get :index, :id => 1, :q => "can"
101 get :index, :id => 1, :q => "can"
102 assert_response :success
102 assert_response :success
103 assert_template 'index'
103 assert_template 'index'
104 end
104 end
105
105
106 def test_search_with_searchable_custom_fields
106 def test_search_with_searchable_custom_fields
107 get :index, :id => 1, :q => "stringforcustomfield"
107 get :index, :id => 1, :q => "stringforcustomfield"
108 assert_response :success
108 assert_response :success
109 results = assigns(:results)
109 results = assigns(:results)
110 assert_not_nil results
110 assert_not_nil results
111 assert_equal 1, results.size
111 assert_equal 1, results.size
112 assert results.include?(Issue.find(7))
112 assert results.include?(Issue.find(7))
113 end
113 end
114
114
115 def test_search_all_words
115 def test_search_all_words
116 # 'all words' is on by default
116 # 'all words' is on by default
117 get :index, :id => 1, :q => 'recipe updating saving', :all_words => '1'
117 get :index, :id => 1, :q => 'recipe updating saving', :all_words => '1'
118 assert_equal true, assigns(:all_words)
118 assert_equal true, assigns(:all_words)
119 results = assigns(:results)
119 results = assigns(:results)
120 assert_not_nil results
120 assert_not_nil results
121 assert_equal 1, results.size
121 assert_equal 1, results.size
122 assert results.include?(Issue.find(3))
122 assert results.include?(Issue.find(3))
123 end
123 end
124
124
125 def test_search_one_of_the_words
125 def test_search_one_of_the_words
126 get :index, :id => 1, :q => 'recipe updating saving', :all_words => ''
126 get :index, :id => 1, :q => 'recipe updating saving', :all_words => ''
127 assert_equal false, assigns(:all_words)
127 assert_equal false, assigns(:all_words)
128 results = assigns(:results)
128 results = assigns(:results)
129 assert_not_nil results
129 assert_not_nil results
130 assert_equal 3, results.size
130 assert_equal 3, results.size
131 assert results.include?(Issue.find(3))
131 assert results.include?(Issue.find(3))
132 end
132 end
133
133
134 def test_search_titles_only_without_result
134 def test_search_titles_only_without_result
135 get :index, :id => 1, :q => 'recipe updating saving', :titles_only => '1'
135 get :index, :id => 1, :q => 'recipe updating saving', :titles_only => '1'
136 results = assigns(:results)
136 results = assigns(:results)
137 assert_not_nil results
137 assert_not_nil results
138 assert_equal 0, results.size
138 assert_equal 0, results.size
139 end
139 end
140
140
141 def test_search_titles_only
141 def test_search_titles_only
142 get :index, :id => 1, :q => 'recipe', :titles_only => '1'
142 get :index, :id => 1, :q => 'recipe', :titles_only => '1'
143 assert_equal true, assigns(:titles_only)
143 assert_equal true, assigns(:titles_only)
144 results = assigns(:results)
144 results = assigns(:results)
145 assert_not_nil results
145 assert_not_nil results
146 assert_equal 2, results.size
146 assert_equal 2, results.size
147 end
147 end
148
148
149 def test_search_content
149 def test_search_content
150 Issue.update_all("description = 'This is a searchkeywordinthecontent'", "id=1")
150 Issue.update_all("description = 'This is a searchkeywordinthecontent'", "id=1")
151
151
152 get :index, :id => 1, :q => 'searchkeywordinthecontent', :titles_only => ''
152 get :index, :id => 1, :q => 'searchkeywordinthecontent', :titles_only => ''
153 assert_equal false, assigns(:titles_only)
153 assert_equal false, assigns(:titles_only)
154 results = assigns(:results)
154 results = assigns(:results)
155 assert_not_nil results
155 assert_not_nil results
156 assert_equal 1, results.size
156 assert_equal 1, results.size
157 end
157 end
158
158
159 def test_search_with_offset
159 def test_search_with_offset
160 get :index, :q => 'coo', :offset => '20080806073000'
160 get :index, :q => 'coo', :offset => '20080806073000'
161 assert_response :success
161 assert_response :success
162 results = assigns(:results)
162 results = assigns(:results)
163 assert results.any?
163 assert results.any?
164 assert results.map(&:event_datetime).max < '20080806T073000'.to_time
164 assert results.map(&:event_datetime).max < '20080806T073000'.to_time
165 end
165 end
166
166
167 def test_search_previous_with_offset
167 def test_search_previous_with_offset
168 get :index, :q => 'coo', :offset => '20080806073000', :previous => '1'
168 get :index, :q => 'coo', :offset => '20080806073000', :previous => '1'
169 assert_response :success
169 assert_response :success
170 results = assigns(:results)
170 results = assigns(:results)
171 assert results.any?
171 assert results.any?
172 assert results.map(&:event_datetime).min >= '20080806T073000'.to_time
172 assert results.map(&:event_datetime).min >= '20080806T073000'.to_time
173 end
173 end
174
174
175 def test_search_with_invalid_project_id
175 def test_search_with_invalid_project_id
176 get :index, :id => 195, :q => 'recipe'
176 get :index, :id => 195, :q => 'recipe'
177 assert_response 404
177 assert_response 404
178 assert_nil assigns(:results)
178 assert_nil assigns(:results)
179 end
179 end
180
180
181 def test_quick_jump_to_issue
181 def test_quick_jump_to_issue
182 # issue of a public project
182 # issue of a public project
183 get :index, :q => "3"
183 get :index, :q => "3"
184 assert_redirected_to '/issues/3'
184 assert_redirected_to '/issues/3'
185
185
186 # issue of a private project
186 # issue of a private project
187 get :index, :q => "4"
187 get :index, :q => "4"
188 assert_response :success
188 assert_response :success
189 assert_template 'index'
189 assert_template 'index'
190 end
190 end
191
191
192 def test_large_integer
192 def test_large_integer
193 get :index, :q => '4615713488'
193 get :index, :q => '4615713488'
194 assert_response :success
194 assert_response :success
195 assert_template 'index'
195 assert_template 'index'
196 end
196 end
197
197
198 def test_tokens_with_quotes
198 def test_tokens_with_quotes
199 get :index, :id => 1, :q => '"good bye" hello "bye bye"'
199 get :index, :id => 1, :q => '"good bye" hello "bye bye"'
200 assert_equal ["good bye", "hello", "bye bye"], assigns(:tokens)
200 assert_equal ["good bye", "hello", "bye bye"], assigns(:tokens)
201 end
201 end
202
203 def test_results_should_be_escaped_once
204 assert Issue.find(1).update_attributes(:subject => '<subject> escaped_once', :description => '<description> escaped_once')
205 get :index, :q => 'escaped_once'
206 assert_response :success
207 assert_select '#search-results' do
208 assert_select 'dt.issue a', :text => /&lt;subject&gt;/
209 assert_select 'dd', :text => /&lt;description&gt;/
210 end
211 end
212
213 def test_keywords_should_be_highlighted
214 assert Issue.find(1).update_attributes(:subject => 'subject highlighted', :description => 'description highlighted')
215 get :index, :q => 'highlighted'
216 assert_response :success
217 assert_select '#search-results' do
218 assert_select 'dt.issue a span.highlight', :text => 'highlighted'
219 assert_select 'dd span.highlight', :text => 'highlighted'
220 end
221 end
202 end
222 end
General Comments 0
You need to be logged in to leave comments. Login now