Feature #4138 » rm4138-make_time_entries_and_their_custom_fields_searchable-trunk_r12406.diff
| app/controllers/timelog_controller.rb (working copy) | ||
|---|---|---|
| 17 | 17 | |
| 18 | 18 |
class TimelogController < ApplicationController |
| 19 | 19 |
menu_item :issues |
| 20 |
default_search_scope :time_entries |
|
| 20 | 21 | |
| 21 | 22 |
before_filter :find_project_for_new_time_entry, :only => [:create] |
| 22 | 23 |
before_filter :find_time_entry, :only => [:show, :edit, :update] |
| app/models/time_entry.rb (working copy) | ||
|---|---|---|
| 32 | 32 |
:author => :user, |
| 33 | 33 |
:group => :issue, |
| 34 | 34 |
:description => :comments |
| 35 | ||
| 35 |
acts_as_searchable :columns => 'comments' |
|
| 36 | 36 |
acts_as_activity_provider :timestamp => "#{table_name}.created_on",
|
| 37 | 37 |
:author_key => :user_id, |
| 38 | 38 |
:find_options => {:include => :project}
|
| app/views/custom_fields/_form.html.erb (working copy) | ||
|---|---|---|
| 78 | 78 |
<% when "TimeEntryCustomField" %> |
| 79 | 79 |
<p><%= f.check_box :is_required %></p> |
| 80 | 80 |
<p><%= f.check_box :is_filter %></p> |
| 81 |
<% if @custom_field.format.searchable_supported %> |
|
| 82 |
<p><%= f.check_box :searchable %></p> |
|
| 83 |
<% end %> |
|
| 81 | 84 | |
| 82 | 85 |
<% else %> |
| 83 | 86 |
<p><%= f.check_box :is_required %></p> |
| lib/redmine.rb (working copy) | ||
|---|---|---|
| 261 | 261 |
search.register :changesets |
| 262 | 262 |
search.register :wiki_pages |
| 263 | 263 |
search.register :messages |
| 264 |
search.register :time_entries |
|
| 264 | 265 |
search.register :projects |
| 265 | 266 |
end |
| 266 | 267 | |
| test/fixtures/custom_fields.yml (working copy) | ||
|---|---|---|
| 145 | 145 |
SGXDqWzDp2prc2Tigqw2NTTDuQ== |
| 146 | 146 |
- Other value |
| 147 | 147 |
field_format: list |
| 148 |
custom_fields_012: |
|
| 149 |
name: Searchable time entry field |
|
| 150 |
regexp: "" |
|
| 151 |
is_for_all: false |
|
| 152 |
is_filter: false |
|
| 153 |
type: TimeEntryCustomField |
|
| 154 |
possible_values: "" |
|
| 155 |
id: 12 |
|
| 156 |
is_required: false |
|
| 157 |
field_format: string |
|
| 158 |
searchable: true |
|
| 159 |
default_value: "" |
|
| 160 |
editable: true |
|
| 161 |
position: 2 |
|
| test/fixtures/custom_values.yml (working copy) | ||
|---|---|---|
| 101 | 101 |
customized_id: 1 |
| 102 | 102 |
id: 17 |
| 103 | 103 |
value: '2009-12-01' |
| 104 |
custom_values_018: |
|
| 105 |
customized_type: TimeEntry |
|
| 106 |
custom_field_id: 12 |
|
| 107 |
customized_id: 2 |
|
| 108 |
id: 18 |
|
| 109 |
value: "stringfortimeentry custom field search" |
|
| test/functional/search_controller_test.rb (working copy) | ||
|---|---|---|
| 21 | 21 |
fixtures :projects, :enabled_modules, :roles, :users, :members, :member_roles, |
| 22 | 22 |
:issues, :trackers, :issue_statuses, :enumerations, |
| 23 | 23 |
:custom_fields, :custom_values, |
| 24 |
:repositories, :changesets |
|
| 24 |
:repositories, :changesets, |
|
| 25 |
:time_entries |
|
| 25 | 26 | |
| 26 | 27 |
def setup |
| 27 | 28 |
User.current = nil |
| ... | ... | |
| 43 | 44 |
assert_response :success |
| 44 | 45 |
assert_template 'index' |
| 45 | 46 | |
| 46 |
assert assigns(:results).include?(Issue.find(2))
|
|
| 47 |
assert assigns(:results).include?(Issue.find(3))
|
|
| 47 | 48 |
assert assigns(:results).include?(Issue.find(5)) |
| 48 | 49 |
assert assigns(:results).include?(Changeset.find(101)) |
| 49 | 50 |
assert_tag :dt, :attributes => { :class => /issue/ },
|
| 50 |
:child => { :tag => 'a', :content => /Add ingredients categories/ },
|
|
| 51 |
:sibling => { :tag => 'dd', :content => /should be classified by categories/ }
|
|
| 51 |
:child => { :tag => 'a', :content => /Error 281 when updating a/ },
|
|
| 52 |
:sibling => { :tag => 'dd', :content => /Error 281 is encountered when/ }
|
|
| 52 | 53 | |
| 53 | 54 |
assert assigns(:results_by_type).is_a?(Hash) |
| 54 | 55 |
assert_equal 5, assigns(:results_by_type)['changesets'] |
| ... | ... | |
| 101 | 102 |
assert_not_include Issue.find(2), assigns(:results) |
| 102 | 103 |
end |
| 103 | 104 | |
| 105 |
def test_search_time_entries_on_project |
|
| 106 |
get :index, :id => 1, :q => 'hours' |
|
| 107 |
assert_response :success |
|
| 108 |
assert_template 'index' |
|
| 109 | ||
| 110 |
results = assigns(:results) |
|
| 111 |
assert_not_nil results |
|
| 112 |
assert_equal 1, results.size |
|
| 113 | ||
| 114 |
assert assigns(:results).include?(TimeEntry.find(1)) |
|
| 115 |
assert_tag :dt, :attributes => { :class => /time-entry/ },
|
|
| 116 |
:child => { :tag => 'a', :content => /\(Bug #1 \(New\): Can't print recipes\)/ },
|
|
| 117 |
:sibling => { :tag => 'dd', :content => /My/ }
|
|
| 118 |
end |
|
| 119 | ||
| 120 |
def test_search_time_entries_on_project_with_subprojects_scope |
|
| 121 |
get :index, :id => 1, :q => 'time spent', :scope => 'subprojects', :time_entries => 1 |
|
| 122 |
assert_response :success |
|
| 123 |
assert_template 'index' |
|
| 124 | ||
| 125 |
results = assigns(:results) |
|
| 126 |
assert_not_nil results |
|
| 127 |
assert_equal 1, results.size |
|
| 128 | ||
| 129 |
assert assigns(:results).include?(TimeEntry.find(4)) |
|
| 130 |
assert_tag :dt, :attributes => { :class => /time-entry/ },
|
|
| 131 |
:child => { :tag => 'a', :content => /\(Project: eCookbook Subproject 1\)/ },
|
|
| 132 |
:sibling => { :tag => 'dd', :content => /on a subproject/ }
|
|
| 133 |
end |
|
| 134 | ||
| 135 |
def test_search_time_entries_on_all_projects |
|
| 136 |
get :index, :q => 'recipe subproject commit', :all_words => '' |
|
| 137 |
assert_response :success |
|
| 138 |
assert_template 'index' |
|
| 139 | ||
| 140 |
assert assigns(:results).include?(TimeEntry.find(4)) |
|
| 141 |
assert_tag :dt, :attributes => { :class => /time-entry/ },
|
|
| 142 |
:child => { :tag => 'a', :content => /7.65 hours/ },
|
|
| 143 |
:sibling => { :tag => 'dd', :content => /Time spent on a/ }
|
|
| 144 |
assert_equal 1, assigns(:results_by_type)['time_entries'] |
|
| 145 |
end |
|
| 146 | ||
| 104 | 147 |
def test_search_all_projects_with_scope_param |
| 105 | 148 |
get :index, :q => 'issue', :scope => 'all' |
| 106 | 149 |
assert_response :success |
| ... | ... | |
| 155 | 198 |
assert results.include?(Issue.find(7)) |
| 156 | 199 |
end |
| 157 | 200 | |
| 201 |
def test_search_time_entries_with_searchable_custom_fields |
|
| 202 |
get :index, :id => 1, :q => "stringfortimeentry", :time_entries => 1 |
|
| 203 |
assert_response :success |
|
| 204 |
results = assigns(:results) |
|
| 205 |
assert_not_nil results |
|
| 206 |
assert_equal 1, results.size |
|
| 207 |
assert results.include?(TimeEntry.find(2)) |
|
| 208 |
end |
|
| 209 | ||
| 158 | 210 |
def test_search_all_words |
| 159 | 211 |
# 'all words' is on by default |
| 160 | 212 |
get :index, :id => 1, :q => 'recipe updating saving', :all_words => '1' |
| test/functional/timelog_controller_test.rb (working copy) | ||
|---|---|---|
| 660 | 660 |
assert_response :success |
| 661 | 661 |
assert_equal 'text/csv; header=present', response.content_type |
| 662 | 662 |
end |
| 663 | ||
| 664 |
def test_default_search_scope |
|
| 665 |
get :index |
|
| 666 | ||
| 667 |
assert_select 'div#quick-search form' do |
|
| 668 |
assert_select 'input[name=time_entries][value=1][type=hidden]' |
|
| 669 |
end |
|
| 670 |
end |
|
| 663 | 671 |
end |