##// END OF EJS Templates
Merged r11064 from trunk (#12652)....
Jean-Philippe Lang -
r10913:b0ccaffe1bfd
parent child
Show More
@@ -1,242 +1,242
1 require 'redmine/access_control'
1 require 'redmine/access_control'
2 require 'redmine/menu_manager'
2 require 'redmine/menu_manager'
3 require 'redmine/activity'
3 require 'redmine/activity'
4 require 'redmine/search'
4 require 'redmine/search'
5 require 'redmine/custom_field_format'
5 require 'redmine/custom_field_format'
6 require 'redmine/mime_type'
6 require 'redmine/mime_type'
7 require 'redmine/core_ext'
7 require 'redmine/core_ext'
8 require 'redmine/themes'
8 require 'redmine/themes'
9 require 'redmine/hook'
9 require 'redmine/hook'
10 require 'redmine/plugin'
10 require 'redmine/plugin'
11 require 'redmine/notifiable'
11 require 'redmine/notifiable'
12 require 'redmine/wiki_formatting'
12 require 'redmine/wiki_formatting'
13 require 'redmine/scm/base'
13 require 'redmine/scm/base'
14
14
15 begin
15 begin
16 require 'RMagick' unless Object.const_defined?(:Magick)
16 require 'RMagick' unless Object.const_defined?(:Magick)
17 rescue LoadError
17 rescue LoadError
18 # RMagick is not available
18 # RMagick is not available
19 end
19 end
20
20
21 if RUBY_VERSION < '1.9'
21 if RUBY_VERSION < '1.9'
22 require 'fastercsv'
22 require 'fastercsv'
23 else
23 else
24 require 'csv'
24 require 'csv'
25 FCSV = CSV
25 FCSV = CSV
26 end
26 end
27
27
28 Redmine::Scm::Base.add "Subversion"
28 Redmine::Scm::Base.add "Subversion"
29 Redmine::Scm::Base.add "Darcs"
29 Redmine::Scm::Base.add "Darcs"
30 Redmine::Scm::Base.add "Mercurial"
30 Redmine::Scm::Base.add "Mercurial"
31 Redmine::Scm::Base.add "Cvs"
31 Redmine::Scm::Base.add "Cvs"
32 Redmine::Scm::Base.add "Bazaar"
32 Redmine::Scm::Base.add "Bazaar"
33 Redmine::Scm::Base.add "Git"
33 Redmine::Scm::Base.add "Git"
34 Redmine::Scm::Base.add "Filesystem"
34 Redmine::Scm::Base.add "Filesystem"
35
35
36 Redmine::CustomFieldFormat.map do |fields|
36 Redmine::CustomFieldFormat.map do |fields|
37 fields.register 'string'
37 fields.register 'string'
38 fields.register 'text'
38 fields.register 'text'
39 fields.register 'int', :label => :label_integer
39 fields.register 'int', :label => :label_integer
40 fields.register 'float'
40 fields.register 'float'
41 fields.register 'list'
41 fields.register 'list'
42 fields.register 'date'
42 fields.register 'date'
43 fields.register 'bool', :label => :label_boolean
43 fields.register 'bool', :label => :label_boolean
44 fields.register 'user', :only => %w(Issue TimeEntry Version Project), :edit_as => 'list'
44 fields.register 'user', :only => %w(Issue TimeEntry Version Project), :edit_as => 'list'
45 fields.register 'version', :only => %w(Issue TimeEntry Version Project), :edit_as => 'list'
45 fields.register 'version', :only => %w(Issue TimeEntry Version Project), :edit_as => 'list'
46 end
46 end
47
47
48 # Permissions
48 # Permissions
49 Redmine::AccessControl.map do |map|
49 Redmine::AccessControl.map do |map|
50 map.permission :view_project, {:projects => [:show], :activities => [:index]}, :public => true, :read => true
50 map.permission :view_project, {:projects => [:show], :activities => [:index]}, :public => true, :read => true
51 map.permission :search_project, {:search => :index}, :public => true, :read => true
51 map.permission :search_project, {:search => :index}, :public => true, :read => true
52 map.permission :add_project, {:projects => [:new, :create]}, :require => :loggedin
52 map.permission :add_project, {:projects => [:new, :create]}, :require => :loggedin
53 map.permission :edit_project, {:projects => [:settings, :edit, :update]}, :require => :member
53 map.permission :edit_project, {:projects => [:settings, :edit, :update]}, :require => :member
54 map.permission :close_project, {:projects => [:close, :reopen]}, :require => :member, :read => true
54 map.permission :close_project, {:projects => [:close, :reopen]}, :require => :member, :read => true
55 map.permission :select_project_modules, {:projects => :modules}, :require => :member
55 map.permission :select_project_modules, {:projects => :modules}, :require => :member
56 map.permission :manage_members, {:projects => :settings, :members => [:index, :show, :create, :update, :destroy, :autocomplete]}, :require => :member
56 map.permission :manage_members, {:projects => :settings, :members => [:index, :show, :create, :update, :destroy, :autocomplete]}, :require => :member
57 map.permission :manage_versions, {:projects => :settings, :versions => [:new, :create, :edit, :update, :close_completed, :destroy]}, :require => :member
57 map.permission :manage_versions, {:projects => :settings, :versions => [:new, :create, :edit, :update, :close_completed, :destroy]}, :require => :member
58 map.permission :add_subprojects, {:projects => [:new, :create]}, :require => :member
58 map.permission :add_subprojects, {:projects => [:new, :create]}, :require => :member
59
59
60 map.project_module :issue_tracking do |map|
60 map.project_module :issue_tracking do |map|
61 # Issue categories
61 # Issue categories
62 map.permission :manage_categories, {:projects => :settings, :issue_categories => [:index, :show, :new, :create, :edit, :update, :destroy]}, :require => :member
62 map.permission :manage_categories, {:projects => :settings, :issue_categories => [:index, :show, :new, :create, :edit, :update, :destroy]}, :require => :member
63 # Issues
63 # Issues
64 map.permission :view_issues, {:issues => [:index, :show],
64 map.permission :view_issues, {:issues => [:index, :show],
65 :auto_complete => [:issues],
65 :auto_complete => [:issues],
66 :context_menus => [:issues],
66 :context_menus => [:issues],
67 :versions => [:index, :show, :status_by],
67 :versions => [:index, :show, :status_by],
68 :journals => [:index, :diff],
68 :journals => [:index, :diff],
69 :queries => :index,
69 :queries => :index,
70 :reports => [:issue_report, :issue_report_details]},
70 :reports => [:issue_report, :issue_report_details]},
71 :read => true
71 :read => true
72 map.permission :add_issues, {:issues => [:new, :create, :update_form], :attachments => :upload}
72 map.permission :add_issues, {:issues => [:new, :create, :update_form], :attachments => :upload}
73 map.permission :edit_issues, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new], :attachments => :upload}
73 map.permission :edit_issues, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new], :attachments => :upload}
74 map.permission :manage_issue_relations, {:issue_relations => [:index, :show, :create, :destroy]}
74 map.permission :manage_issue_relations, {:issue_relations => [:index, :show, :create, :destroy]}
75 map.permission :manage_subtasks, {}
75 map.permission :manage_subtasks, {}
76 map.permission :set_issues_private, {}
76 map.permission :set_issues_private, {}
77 map.permission :set_own_issues_private, {}, :require => :loggedin
77 map.permission :set_own_issues_private, {}, :require => :loggedin
78 map.permission :add_issue_notes, {:issues => [:edit, :update], :journals => [:new], :attachments => :upload}
78 map.permission :add_issue_notes, {:issues => [:edit, :update], :journals => [:new], :attachments => :upload}
79 map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
79 map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
80 map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin
80 map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin
81 map.permission :view_private_notes, {}, :read => true, :require => :member
81 map.permission :view_private_notes, {}, :read => true, :require => :member
82 map.permission :set_notes_private, {}, :require => :member
82 map.permission :set_notes_private, {}, :require => :member
83 map.permission :move_issues, {:issues => [:bulk_edit, :bulk_update]}, :require => :loggedin
83 map.permission :move_issues, {:issues => [:bulk_edit, :bulk_update]}, :require => :loggedin
84 map.permission :delete_issues, {:issues => :destroy}, :require => :member
84 map.permission :delete_issues, {:issues => :destroy}, :require => :member
85 # Queries
85 # Queries
86 map.permission :manage_public_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :member
86 map.permission :manage_public_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :member
87 map.permission :save_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :loggedin
87 map.permission :save_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :loggedin
88 # Watchers
88 # Watchers
89 map.permission :view_issue_watchers, {}, :read => true
89 map.permission :view_issue_watchers, {}, :read => true
90 map.permission :add_issue_watchers, {:watchers => :new}
90 map.permission :add_issue_watchers, {:watchers => :new}
91 map.permission :delete_issue_watchers, {:watchers => :destroy}
91 map.permission :delete_issue_watchers, {:watchers => :destroy}
92 end
92 end
93
93
94 map.project_module :time_tracking do |map|
94 map.project_module :time_tracking do |map|
95 map.permission :log_time, {:timelog => [:new, :create]}, :require => :loggedin
95 map.permission :log_time, {:timelog => [:new, :create]}, :require => :loggedin
96 map.permission :view_time_entries, {:timelog => [:index, :report, :show]}, :read => true
96 map.permission :view_time_entries, {:timelog => [:index, :report, :show]}, :read => true
97 map.permission :edit_time_entries, {:timelog => [:edit, :update, :destroy, :bulk_edit, :bulk_update]}, :require => :member
97 map.permission :edit_time_entries, {:timelog => [:edit, :update, :destroy, :bulk_edit, :bulk_update]}, :require => :member
98 map.permission :edit_own_time_entries, {:timelog => [:edit, :update, :destroy,:bulk_edit, :bulk_update]}, :require => :loggedin
98 map.permission :edit_own_time_entries, {:timelog => [:edit, :update, :destroy,:bulk_edit, :bulk_update]}, :require => :loggedin
99 map.permission :manage_project_activities, {:project_enumerations => [:update, :destroy]}, :require => :member
99 map.permission :manage_project_activities, {:project_enumerations => [:update, :destroy]}, :require => :member
100 end
100 end
101
101
102 map.project_module :news do |map|
102 map.project_module :news do |map|
103 map.permission :manage_news, {:news => [:new, :create, :edit, :update, :destroy], :comments => [:destroy]}, :require => :member
103 map.permission :manage_news, {:news => [:new, :create, :edit, :update, :destroy], :comments => [:destroy]}, :require => :member
104 map.permission :view_news, {:news => [:index, :show]}, :public => true, :read => true
104 map.permission :view_news, {:news => [:index, :show]}, :public => true, :read => true
105 map.permission :comment_news, {:comments => :create}
105 map.permission :comment_news, {:comments => :create}
106 end
106 end
107
107
108 map.project_module :documents do |map|
108 map.project_module :documents do |map|
109 map.permission :manage_documents, {:documents => [:new, :create, :edit, :update, :destroy, :add_attachment]}, :require => :loggedin
109 map.permission :manage_documents, {:documents => [:new, :create, :edit, :update, :destroy, :add_attachment]}, :require => :loggedin
110 map.permission :view_documents, {:documents => [:index, :show, :download]}, :read => true
110 map.permission :view_documents, {:documents => [:index, :show, :download]}, :read => true
111 end
111 end
112
112
113 map.project_module :files do |map|
113 map.project_module :files do |map|
114 map.permission :manage_files, {:files => [:new, :create]}, :require => :loggedin
114 map.permission :manage_files, {:files => [:new, :create]}, :require => :loggedin
115 map.permission :view_files, {:files => :index, :versions => :download}, :read => true
115 map.permission :view_files, {:files => :index, :versions => :download}, :read => true
116 end
116 end
117
117
118 map.project_module :wiki do |map|
118 map.project_module :wiki do |map|
119 map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
119 map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
120 map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member
120 map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member
121 map.permission :delete_wiki_pages, {:wiki => [:destroy, :destroy_version]}, :require => :member
121 map.permission :delete_wiki_pages, {:wiki => [:destroy, :destroy_version]}, :require => :member
122 map.permission :view_wiki_pages, {:wiki => [:index, :show, :special, :date_index]}, :read => true
122 map.permission :view_wiki_pages, {:wiki => [:index, :show, :special, :date_index]}, :read => true
123 map.permission :export_wiki_pages, {:wiki => [:export]}, :read => true
123 map.permission :export_wiki_pages, {:wiki => [:export]}, :read => true
124 map.permission :view_wiki_edits, {:wiki => [:history, :diff, :annotate]}, :read => true
124 map.permission :view_wiki_edits, {:wiki => [:history, :diff, :annotate]}, :read => true
125 map.permission :edit_wiki_pages, :wiki => [:edit, :update, :preview, :add_attachment]
125 map.permission :edit_wiki_pages, :wiki => [:edit, :update, :preview, :add_attachment]
126 map.permission :delete_wiki_pages_attachments, {}
126 map.permission :delete_wiki_pages_attachments, {}
127 map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member
127 map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member
128 end
128 end
129
129
130 map.project_module :repository do |map|
130 map.project_module :repository do |map|
131 map.permission :manage_repository, {:repositories => [:new, :create, :edit, :update, :committers, :destroy]}, :require => :member
131 map.permission :manage_repository, {:repositories => [:new, :create, :edit, :update, :committers, :destroy]}, :require => :member
132 map.permission :browse_repository, {:repositories => [:show, :browse, :entry, :raw, :annotate, :changes, :diff, :stats, :graph]}, :read => true
132 map.permission :browse_repository, {:repositories => [:show, :browse, :entry, :raw, :annotate, :changes, :diff, :stats, :graph]}, :read => true
133 map.permission :view_changesets, {:repositories => [:show, :revisions, :revision]}, :read => true
133 map.permission :view_changesets, {:repositories => [:show, :revisions, :revision]}, :read => true
134 map.permission :commit_access, {}
134 map.permission :commit_access, {}
135 map.permission :manage_related_issues, {:repositories => [:add_related_issue, :remove_related_issue]}
135 map.permission :manage_related_issues, {:repositories => [:add_related_issue, :remove_related_issue]}
136 end
136 end
137
137
138 map.project_module :boards do |map|
138 map.project_module :boards do |map|
139 map.permission :manage_boards, {:boards => [:new, :create, :edit, :update, :destroy]}, :require => :member
139 map.permission :manage_boards, {:boards => [:new, :create, :edit, :update, :destroy]}, :require => :member
140 map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true, :read => true
140 map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true, :read => true
141 map.permission :add_messages, {:messages => [:new, :reply, :quote]}
141 map.permission :add_messages, {:messages => [:new, :reply, :quote]}
142 map.permission :edit_messages, {:messages => :edit}, :require => :member
142 map.permission :edit_messages, {:messages => :edit}, :require => :member
143 map.permission :edit_own_messages, {:messages => :edit}, :require => :loggedin
143 map.permission :edit_own_messages, {:messages => :edit}, :require => :loggedin
144 map.permission :delete_messages, {:messages => :destroy}, :require => :member
144 map.permission :delete_messages, {:messages => :destroy}, :require => :member
145 map.permission :delete_own_messages, {:messages => :destroy}, :require => :loggedin
145 map.permission :delete_own_messages, {:messages => :destroy}, :require => :loggedin
146 end
146 end
147
147
148 map.project_module :calendar do |map|
148 map.project_module :calendar do |map|
149 map.permission :view_calendar, {:calendars => [:show, :update]}, :read => true
149 map.permission :view_calendar, {:calendars => [:show, :update]}, :read => true
150 end
150 end
151
151
152 map.project_module :gantt do |map|
152 map.project_module :gantt do |map|
153 map.permission :view_gantt, {:gantts => [:show, :update]}, :read => true
153 map.permission :view_gantt, {:gantts => [:show, :update]}, :read => true
154 end
154 end
155 end
155 end
156
156
157 Redmine::MenuManager.map :top_menu do |menu|
157 Redmine::MenuManager.map :top_menu do |menu|
158 menu.push :home, :home_path
158 menu.push :home, :home_path
159 menu.push :my_page, { :controller => 'my', :action => 'page' }, :if => Proc.new { User.current.logged? }
159 menu.push :my_page, { :controller => 'my', :action => 'page' }, :if => Proc.new { User.current.logged? }
160 menu.push :projects, { :controller => 'projects', :action => 'index' }, :caption => :label_project_plural
160 menu.push :projects, { :controller => 'projects', :action => 'index' }, :caption => :label_project_plural
161 menu.push :administration, { :controller => 'admin', :action => 'index' }, :if => Proc.new { User.current.admin? }, :last => true
161 menu.push :administration, { :controller => 'admin', :action => 'index' }, :if => Proc.new { User.current.admin? }, :last => true
162 menu.push :help, Redmine::Info.help_url, :last => true
162 menu.push :help, Redmine::Info.help_url, :last => true
163 end
163 end
164
164
165 Redmine::MenuManager.map :account_menu do |menu|
165 Redmine::MenuManager.map :account_menu do |menu|
166 menu.push :login, :signin_path, :if => Proc.new { !User.current.logged? }
166 menu.push :login, :signin_path, :if => Proc.new { !User.current.logged? }
167 menu.push :register, :register_path, :if => Proc.new { !User.current.logged? && Setting.self_registration? }
167 menu.push :register, :register_path, :if => Proc.new { !User.current.logged? && Setting.self_registration? }
168 menu.push :my_account, { :controller => 'my', :action => 'account' }, :if => Proc.new { User.current.logged? }
168 menu.push :my_account, { :controller => 'my', :action => 'account' }, :if => Proc.new { User.current.logged? }
169 menu.push :logout, :signout_path, :if => Proc.new { User.current.logged? }
169 menu.push :logout, :signout_path, :if => Proc.new { User.current.logged? }
170 end
170 end
171
171
172 Redmine::MenuManager.map :application_menu do |menu|
172 Redmine::MenuManager.map :application_menu do |menu|
173 # Empty
173 # Empty
174 end
174 end
175
175
176 Redmine::MenuManager.map :admin_menu do |menu|
176 Redmine::MenuManager.map :admin_menu do |menu|
177 menu.push :projects, {:controller => 'admin', :action => 'projects'}, :caption => :label_project_plural
177 menu.push :projects, {:controller => 'admin', :action => 'projects'}, :caption => :label_project_plural
178 menu.push :users, {:controller => 'users'}, :caption => :label_user_plural
178 menu.push :users, {:controller => 'users'}, :caption => :label_user_plural
179 menu.push :groups, {:controller => 'groups'}, :caption => :label_group_plural
179 menu.push :groups, {:controller => 'groups'}, :caption => :label_group_plural
180 menu.push :roles, {:controller => 'roles'}, :caption => :label_role_and_permissions
180 menu.push :roles, {:controller => 'roles'}, :caption => :label_role_and_permissions
181 menu.push :trackers, {:controller => 'trackers'}, :caption => :label_tracker_plural
181 menu.push :trackers, {:controller => 'trackers'}, :caption => :label_tracker_plural
182 menu.push :issue_statuses, {:controller => 'issue_statuses'}, :caption => :label_issue_status_plural,
182 menu.push :issue_statuses, {:controller => 'issue_statuses'}, :caption => :label_issue_status_plural,
183 :html => {:class => 'issue_statuses'}
183 :html => {:class => 'issue_statuses'}
184 menu.push :workflows, {:controller => 'workflows', :action => 'edit'}, :caption => :label_workflow
184 menu.push :workflows, {:controller => 'workflows', :action => 'edit'}, :caption => :label_workflow
185 menu.push :custom_fields, {:controller => 'custom_fields'}, :caption => :label_custom_field_plural,
185 menu.push :custom_fields, {:controller => 'custom_fields'}, :caption => :label_custom_field_plural,
186 :html => {:class => 'custom_fields'}
186 :html => {:class => 'custom_fields'}
187 menu.push :enumerations, {:controller => 'enumerations'}
187 menu.push :enumerations, {:controller => 'enumerations'}
188 menu.push :settings, {:controller => 'settings'}
188 menu.push :settings, {:controller => 'settings'}
189 menu.push :ldap_authentication, {:controller => 'auth_sources', :action => 'index'},
189 menu.push :ldap_authentication, {:controller => 'auth_sources', :action => 'index'},
190 :html => {:class => 'server_authentication'}
190 :html => {:class => 'server_authentication'}
191 menu.push :plugins, {:controller => 'admin', :action => 'plugins'}, :last => true
191 menu.push :plugins, {:controller => 'admin', :action => 'plugins'}, :last => true
192 menu.push :info, {:controller => 'admin', :action => 'info'}, :caption => :label_information_plural, :last => true
192 menu.push :info, {:controller => 'admin', :action => 'info'}, :caption => :label_information_plural, :last => true
193 end
193 end
194
194
195 Redmine::MenuManager.map :project_menu do |menu|
195 Redmine::MenuManager.map :project_menu do |menu|
196 menu.push :overview, { :controller => 'projects', :action => 'show' }
196 menu.push :overview, { :controller => 'projects', :action => 'show' }
197 menu.push :activity, { :controller => 'activities', :action => 'index' }
197 menu.push :activity, { :controller => 'activities', :action => 'index' }
198 menu.push :roadmap, { :controller => 'versions', :action => 'index' }, :param => :project_id,
198 menu.push :roadmap, { :controller => 'versions', :action => 'index' }, :param => :project_id,
199 :if => Proc.new { |p| p.shared_versions.any? }
199 :if => Proc.new { |p| p.shared_versions.any? }
200 menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
200 menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
201 menu.push :new_issue, { :controller => 'issues', :action => 'new' }, :param => :project_id, :caption => :label_issue_new,
201 menu.push :new_issue, { :controller => 'issues', :action => 'new', :copy_from => nil }, :param => :project_id, :caption => :label_issue_new,
202 :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
202 :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
203 menu.push :gantt, { :controller => 'gantts', :action => 'show' }, :param => :project_id, :caption => :label_gantt
203 menu.push :gantt, { :controller => 'gantts', :action => 'show' }, :param => :project_id, :caption => :label_gantt
204 menu.push :calendar, { :controller => 'calendars', :action => 'show' }, :param => :project_id, :caption => :label_calendar
204 menu.push :calendar, { :controller => 'calendars', :action => 'show' }, :param => :project_id, :caption => :label_calendar
205 menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural
205 menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural
206 menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural
206 menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural
207 menu.push :wiki, { :controller => 'wiki', :action => 'show', :id => nil }, :param => :project_id,
207 menu.push :wiki, { :controller => 'wiki', :action => 'show', :id => nil }, :param => :project_id,
208 :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
208 :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
209 menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id,
209 menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id,
210 :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural
210 :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural
211 menu.push :files, { :controller => 'files', :action => 'index' }, :caption => :label_file_plural, :param => :project_id
211 menu.push :files, { :controller => 'files', :action => 'index' }, :caption => :label_file_plural, :param => :project_id
212 menu.push :repository, { :controller => 'repositories', :action => 'show', :repository_id => nil, :path => nil, :rev => nil },
212 menu.push :repository, { :controller => 'repositories', :action => 'show', :repository_id => nil, :path => nil, :rev => nil },
213 :if => Proc.new { |p| p.repository && !p.repository.new_record? }
213 :if => Proc.new { |p| p.repository && !p.repository.new_record? }
214 menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true
214 menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true
215 end
215 end
216
216
217 Redmine::Activity.map do |activity|
217 Redmine::Activity.map do |activity|
218 activity.register :issues, :class_name => %w(Issue Journal)
218 activity.register :issues, :class_name => %w(Issue Journal)
219 activity.register :changesets
219 activity.register :changesets
220 activity.register :news
220 activity.register :news
221 activity.register :documents, :class_name => %w(Document Attachment)
221 activity.register :documents, :class_name => %w(Document Attachment)
222 activity.register :files, :class_name => 'Attachment'
222 activity.register :files, :class_name => 'Attachment'
223 activity.register :wiki_edits, :class_name => 'WikiContent::Version', :default => false
223 activity.register :wiki_edits, :class_name => 'WikiContent::Version', :default => false
224 activity.register :messages, :default => false
224 activity.register :messages, :default => false
225 activity.register :time_entries, :default => false
225 activity.register :time_entries, :default => false
226 end
226 end
227
227
228 Redmine::Search.map do |search|
228 Redmine::Search.map do |search|
229 search.register :issues
229 search.register :issues
230 search.register :news
230 search.register :news
231 search.register :documents
231 search.register :documents
232 search.register :changesets
232 search.register :changesets
233 search.register :wiki_pages
233 search.register :wiki_pages
234 search.register :messages
234 search.register :messages
235 search.register :projects
235 search.register :projects
236 end
236 end
237
237
238 Redmine::WikiFormatting.map do |format|
238 Redmine::WikiFormatting.map do |format|
239 format.register :textile, Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting::Textile::Helper
239 format.register :textile, Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting::Textile::Helper
240 end
240 end
241
241
242 ActionView::Template.register_template_handler :rsb, Redmine::Views::ApiTemplateHandler
242 ActionView::Template.register_template_handler :rsb, Redmine::Views::ApiTemplateHandler
@@ -1,3837 +1,3840
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19 require 'issues_controller'
19 require 'issues_controller'
20
20
21 class IssuesControllerTest < ActionController::TestCase
21 class IssuesControllerTest < ActionController::TestCase
22 fixtures :projects,
22 fixtures :projects,
23 :users,
23 :users,
24 :roles,
24 :roles,
25 :members,
25 :members,
26 :member_roles,
26 :member_roles,
27 :issues,
27 :issues,
28 :issue_statuses,
28 :issue_statuses,
29 :versions,
29 :versions,
30 :trackers,
30 :trackers,
31 :projects_trackers,
31 :projects_trackers,
32 :issue_categories,
32 :issue_categories,
33 :enabled_modules,
33 :enabled_modules,
34 :enumerations,
34 :enumerations,
35 :attachments,
35 :attachments,
36 :workflows,
36 :workflows,
37 :custom_fields,
37 :custom_fields,
38 :custom_values,
38 :custom_values,
39 :custom_fields_projects,
39 :custom_fields_projects,
40 :custom_fields_trackers,
40 :custom_fields_trackers,
41 :time_entries,
41 :time_entries,
42 :journals,
42 :journals,
43 :journal_details,
43 :journal_details,
44 :queries,
44 :queries,
45 :repositories,
45 :repositories,
46 :changesets
46 :changesets
47
47
48 include Redmine::I18n
48 include Redmine::I18n
49
49
50 def setup
50 def setup
51 @controller = IssuesController.new
51 @controller = IssuesController.new
52 @request = ActionController::TestRequest.new
52 @request = ActionController::TestRequest.new
53 @response = ActionController::TestResponse.new
53 @response = ActionController::TestResponse.new
54 User.current = nil
54 User.current = nil
55 end
55 end
56
56
57 def test_index
57 def test_index
58 with_settings :default_language => "en" do
58 with_settings :default_language => "en" do
59 get :index
59 get :index
60 assert_response :success
60 assert_response :success
61 assert_template 'index'
61 assert_template 'index'
62 assert_not_nil assigns(:issues)
62 assert_not_nil assigns(:issues)
63 assert_nil assigns(:project)
63 assert_nil assigns(:project)
64
64
65 # links to visible issues
65 # links to visible issues
66 assert_select 'a[href=/issues/1]', :text => /Can&#x27;t print recipes/
66 assert_select 'a[href=/issues/1]', :text => /Can&#x27;t print recipes/
67 assert_select 'a[href=/issues/5]', :text => /Subproject issue/
67 assert_select 'a[href=/issues/5]', :text => /Subproject issue/
68 # private projects hidden
68 # private projects hidden
69 assert_select 'a[href=/issues/6]', 0
69 assert_select 'a[href=/issues/6]', 0
70 assert_select 'a[href=/issues/4]', 0
70 assert_select 'a[href=/issues/4]', 0
71 # project column
71 # project column
72 assert_select 'th', :text => /Project/
72 assert_select 'th', :text => /Project/
73 end
73 end
74 end
74 end
75
75
76 def test_index_should_not_list_issues_when_module_disabled
76 def test_index_should_not_list_issues_when_module_disabled
77 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
77 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
78 get :index
78 get :index
79 assert_response :success
79 assert_response :success
80 assert_template 'index'
80 assert_template 'index'
81 assert_not_nil assigns(:issues)
81 assert_not_nil assigns(:issues)
82 assert_nil assigns(:project)
82 assert_nil assigns(:project)
83
83
84 assert_select 'a[href=/issues/1]', 0
84 assert_select 'a[href=/issues/1]', 0
85 assert_select 'a[href=/issues/5]', :text => /Subproject issue/
85 assert_select 'a[href=/issues/5]', :text => /Subproject issue/
86 end
86 end
87
87
88 def test_index_should_list_visible_issues_only
88 def test_index_should_list_visible_issues_only
89 get :index, :per_page => 100
89 get :index, :per_page => 100
90 assert_response :success
90 assert_response :success
91 assert_not_nil assigns(:issues)
91 assert_not_nil assigns(:issues)
92 assert_nil assigns(:issues).detect {|issue| !issue.visible?}
92 assert_nil assigns(:issues).detect {|issue| !issue.visible?}
93 end
93 end
94
94
95 def test_index_with_project
95 def test_index_with_project
96 Setting.display_subprojects_issues = 0
96 Setting.display_subprojects_issues = 0
97 get :index, :project_id => 1
97 get :index, :project_id => 1
98 assert_response :success
98 assert_response :success
99 assert_template 'index'
99 assert_template 'index'
100 assert_not_nil assigns(:issues)
100 assert_not_nil assigns(:issues)
101
101
102 assert_select 'a[href=/issues/1]', :text => /Can&#x27;t print recipes/
102 assert_select 'a[href=/issues/1]', :text => /Can&#x27;t print recipes/
103 assert_select 'a[href=/issues/5]', 0
103 assert_select 'a[href=/issues/5]', 0
104 end
104 end
105
105
106 def test_index_with_project_and_subprojects
106 def test_index_with_project_and_subprojects
107 Setting.display_subprojects_issues = 1
107 Setting.display_subprojects_issues = 1
108 get :index, :project_id => 1
108 get :index, :project_id => 1
109 assert_response :success
109 assert_response :success
110 assert_template 'index'
110 assert_template 'index'
111 assert_not_nil assigns(:issues)
111 assert_not_nil assigns(:issues)
112
112
113 assert_select 'a[href=/issues/1]', :text => /Can&#x27;t print recipes/
113 assert_select 'a[href=/issues/1]', :text => /Can&#x27;t print recipes/
114 assert_select 'a[href=/issues/5]', :text => /Subproject issue/
114 assert_select 'a[href=/issues/5]', :text => /Subproject issue/
115 assert_select 'a[href=/issues/6]', 0
115 assert_select 'a[href=/issues/6]', 0
116 end
116 end
117
117
118 def test_index_with_project_and_subprojects_should_show_private_subprojects_with_permission
118 def test_index_with_project_and_subprojects_should_show_private_subprojects_with_permission
119 @request.session[:user_id] = 2
119 @request.session[:user_id] = 2
120 Setting.display_subprojects_issues = 1
120 Setting.display_subprojects_issues = 1
121 get :index, :project_id => 1
121 get :index, :project_id => 1
122 assert_response :success
122 assert_response :success
123 assert_template 'index'
123 assert_template 'index'
124 assert_not_nil assigns(:issues)
124 assert_not_nil assigns(:issues)
125
125
126 assert_select 'a[href=/issues/1]', :text => /Can&#x27;t print recipes/
126 assert_select 'a[href=/issues/1]', :text => /Can&#x27;t print recipes/
127 assert_select 'a[href=/issues/5]', :text => /Subproject issue/
127 assert_select 'a[href=/issues/5]', :text => /Subproject issue/
128 assert_select 'a[href=/issues/6]', :text => /Issue of a private subproject/
128 assert_select 'a[href=/issues/6]', :text => /Issue of a private subproject/
129 end
129 end
130
130
131 def test_index_with_project_and_default_filter
131 def test_index_with_project_and_default_filter
132 get :index, :project_id => 1, :set_filter => 1
132 get :index, :project_id => 1, :set_filter => 1
133 assert_response :success
133 assert_response :success
134 assert_template 'index'
134 assert_template 'index'
135 assert_not_nil assigns(:issues)
135 assert_not_nil assigns(:issues)
136
136
137 query = assigns(:query)
137 query = assigns(:query)
138 assert_not_nil query
138 assert_not_nil query
139 # default filter
139 # default filter
140 assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters)
140 assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters)
141 end
141 end
142
142
143 def test_index_with_project_and_filter
143 def test_index_with_project_and_filter
144 get :index, :project_id => 1, :set_filter => 1,
144 get :index, :project_id => 1, :set_filter => 1,
145 :f => ['tracker_id'],
145 :f => ['tracker_id'],
146 :op => {'tracker_id' => '='},
146 :op => {'tracker_id' => '='},
147 :v => {'tracker_id' => ['1']}
147 :v => {'tracker_id' => ['1']}
148 assert_response :success
148 assert_response :success
149 assert_template 'index'
149 assert_template 'index'
150 assert_not_nil assigns(:issues)
150 assert_not_nil assigns(:issues)
151
151
152 query = assigns(:query)
152 query = assigns(:query)
153 assert_not_nil query
153 assert_not_nil query
154 assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters)
154 assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters)
155 end
155 end
156
156
157 def test_index_with_short_filters
157 def test_index_with_short_filters
158 to_test = {
158 to_test = {
159 'status_id' => {
159 'status_id' => {
160 'o' => { :op => 'o', :values => [''] },
160 'o' => { :op => 'o', :values => [''] },
161 'c' => { :op => 'c', :values => [''] },
161 'c' => { :op => 'c', :values => [''] },
162 '7' => { :op => '=', :values => ['7'] },
162 '7' => { :op => '=', :values => ['7'] },
163 '7|3|4' => { :op => '=', :values => ['7', '3', '4'] },
163 '7|3|4' => { :op => '=', :values => ['7', '3', '4'] },
164 '=7' => { :op => '=', :values => ['7'] },
164 '=7' => { :op => '=', :values => ['7'] },
165 '!3' => { :op => '!', :values => ['3'] },
165 '!3' => { :op => '!', :values => ['3'] },
166 '!7|3|4' => { :op => '!', :values => ['7', '3', '4'] }},
166 '!7|3|4' => { :op => '!', :values => ['7', '3', '4'] }},
167 'subject' => {
167 'subject' => {
168 'This is a subject' => { :op => '=', :values => ['This is a subject'] },
168 'This is a subject' => { :op => '=', :values => ['This is a subject'] },
169 'o' => { :op => '=', :values => ['o'] },
169 'o' => { :op => '=', :values => ['o'] },
170 '~This is part of a subject' => { :op => '~', :values => ['This is part of a subject'] },
170 '~This is part of a subject' => { :op => '~', :values => ['This is part of a subject'] },
171 '!~This is part of a subject' => { :op => '!~', :values => ['This is part of a subject'] }},
171 '!~This is part of a subject' => { :op => '!~', :values => ['This is part of a subject'] }},
172 'tracker_id' => {
172 'tracker_id' => {
173 '3' => { :op => '=', :values => ['3'] },
173 '3' => { :op => '=', :values => ['3'] },
174 '=3' => { :op => '=', :values => ['3'] }},
174 '=3' => { :op => '=', :values => ['3'] }},
175 'start_date' => {
175 'start_date' => {
176 '2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
176 '2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
177 '=2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
177 '=2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
178 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
178 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
179 '<=2011-10-12' => { :op => '<=', :values => ['2011-10-12'] },
179 '<=2011-10-12' => { :op => '<=', :values => ['2011-10-12'] },
180 '><2011-10-01|2011-10-30' => { :op => '><', :values => ['2011-10-01', '2011-10-30'] },
180 '><2011-10-01|2011-10-30' => { :op => '><', :values => ['2011-10-01', '2011-10-30'] },
181 '<t+2' => { :op => '<t+', :values => ['2'] },
181 '<t+2' => { :op => '<t+', :values => ['2'] },
182 '>t+2' => { :op => '>t+', :values => ['2'] },
182 '>t+2' => { :op => '>t+', :values => ['2'] },
183 't+2' => { :op => 't+', :values => ['2'] },
183 't+2' => { :op => 't+', :values => ['2'] },
184 't' => { :op => 't', :values => [''] },
184 't' => { :op => 't', :values => [''] },
185 'w' => { :op => 'w', :values => [''] },
185 'w' => { :op => 'w', :values => [''] },
186 '>t-2' => { :op => '>t-', :values => ['2'] },
186 '>t-2' => { :op => '>t-', :values => ['2'] },
187 '<t-2' => { :op => '<t-', :values => ['2'] },
187 '<t-2' => { :op => '<t-', :values => ['2'] },
188 't-2' => { :op => 't-', :values => ['2'] }},
188 't-2' => { :op => 't-', :values => ['2'] }},
189 'created_on' => {
189 'created_on' => {
190 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
190 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
191 '<t-2' => { :op => '<t-', :values => ['2'] },
191 '<t-2' => { :op => '<t-', :values => ['2'] },
192 '>t-2' => { :op => '>t-', :values => ['2'] },
192 '>t-2' => { :op => '>t-', :values => ['2'] },
193 't-2' => { :op => 't-', :values => ['2'] }},
193 't-2' => { :op => 't-', :values => ['2'] }},
194 'cf_1' => {
194 'cf_1' => {
195 'c' => { :op => '=', :values => ['c'] },
195 'c' => { :op => '=', :values => ['c'] },
196 '!c' => { :op => '!', :values => ['c'] },
196 '!c' => { :op => '!', :values => ['c'] },
197 '!*' => { :op => '!*', :values => [''] },
197 '!*' => { :op => '!*', :values => [''] },
198 '*' => { :op => '*', :values => [''] }},
198 '*' => { :op => '*', :values => [''] }},
199 'estimated_hours' => {
199 'estimated_hours' => {
200 '=13.4' => { :op => '=', :values => ['13.4'] },
200 '=13.4' => { :op => '=', :values => ['13.4'] },
201 '>=45' => { :op => '>=', :values => ['45'] },
201 '>=45' => { :op => '>=', :values => ['45'] },
202 '<=125' => { :op => '<=', :values => ['125'] },
202 '<=125' => { :op => '<=', :values => ['125'] },
203 '><10.5|20.5' => { :op => '><', :values => ['10.5', '20.5'] },
203 '><10.5|20.5' => { :op => '><', :values => ['10.5', '20.5'] },
204 '!*' => { :op => '!*', :values => [''] },
204 '!*' => { :op => '!*', :values => [''] },
205 '*' => { :op => '*', :values => [''] }}
205 '*' => { :op => '*', :values => [''] }}
206 }
206 }
207
207
208 default_filter = { 'status_id' => {:operator => 'o', :values => [''] }}
208 default_filter = { 'status_id' => {:operator => 'o', :values => [''] }}
209
209
210 to_test.each do |field, expression_and_expected|
210 to_test.each do |field, expression_and_expected|
211 expression_and_expected.each do |filter_expression, expected|
211 expression_and_expected.each do |filter_expression, expected|
212
212
213 get :index, :set_filter => 1, field => filter_expression
213 get :index, :set_filter => 1, field => filter_expression
214
214
215 assert_response :success
215 assert_response :success
216 assert_template 'index'
216 assert_template 'index'
217 assert_not_nil assigns(:issues)
217 assert_not_nil assigns(:issues)
218
218
219 query = assigns(:query)
219 query = assigns(:query)
220 assert_not_nil query
220 assert_not_nil query
221 assert query.has_filter?(field)
221 assert query.has_filter?(field)
222 assert_equal(default_filter.merge({field => {:operator => expected[:op], :values => expected[:values]}}), query.filters)
222 assert_equal(default_filter.merge({field => {:operator => expected[:op], :values => expected[:values]}}), query.filters)
223 end
223 end
224 end
224 end
225 end
225 end
226
226
227 def test_index_with_project_and_empty_filters
227 def test_index_with_project_and_empty_filters
228 get :index, :project_id => 1, :set_filter => 1, :fields => ['']
228 get :index, :project_id => 1, :set_filter => 1, :fields => ['']
229 assert_response :success
229 assert_response :success
230 assert_template 'index'
230 assert_template 'index'
231 assert_not_nil assigns(:issues)
231 assert_not_nil assigns(:issues)
232
232
233 query = assigns(:query)
233 query = assigns(:query)
234 assert_not_nil query
234 assert_not_nil query
235 # no filter
235 # no filter
236 assert_equal({}, query.filters)
236 assert_equal({}, query.filters)
237 end
237 end
238
238
239 def test_index_with_project_custom_field_filter
239 def test_index_with_project_custom_field_filter
240 field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
240 field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
241 CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo')
241 CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo')
242 CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo')
242 CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo')
243 filter_name = "project.cf_#{field.id}"
243 filter_name = "project.cf_#{field.id}"
244 @request.session[:user_id] = 1
244 @request.session[:user_id] = 1
245
245
246 get :index, :set_filter => 1,
246 get :index, :set_filter => 1,
247 :f => [filter_name],
247 :f => [filter_name],
248 :op => {filter_name => '='},
248 :op => {filter_name => '='},
249 :v => {filter_name => ['Foo']}
249 :v => {filter_name => ['Foo']}
250 assert_response :success
250 assert_response :success
251 assert_template 'index'
251 assert_template 'index'
252 assert_equal [3, 5], assigns(:issues).map(&:project_id).uniq.sort
252 assert_equal [3, 5], assigns(:issues).map(&:project_id).uniq.sort
253 end
253 end
254
254
255 def test_index_with_query
255 def test_index_with_query
256 get :index, :project_id => 1, :query_id => 5
256 get :index, :project_id => 1, :query_id => 5
257 assert_response :success
257 assert_response :success
258 assert_template 'index'
258 assert_template 'index'
259 assert_not_nil assigns(:issues)
259 assert_not_nil assigns(:issues)
260 assert_nil assigns(:issue_count_by_group)
260 assert_nil assigns(:issue_count_by_group)
261 end
261 end
262
262
263 def test_index_with_query_grouped_by_tracker
263 def test_index_with_query_grouped_by_tracker
264 get :index, :project_id => 1, :query_id => 6
264 get :index, :project_id => 1, :query_id => 6
265 assert_response :success
265 assert_response :success
266 assert_template 'index'
266 assert_template 'index'
267 assert_not_nil assigns(:issues)
267 assert_not_nil assigns(:issues)
268 assert_not_nil assigns(:issue_count_by_group)
268 assert_not_nil assigns(:issue_count_by_group)
269 end
269 end
270
270
271 def test_index_with_query_grouped_by_list_custom_field
271 def test_index_with_query_grouped_by_list_custom_field
272 get :index, :project_id => 1, :query_id => 9
272 get :index, :project_id => 1, :query_id => 9
273 assert_response :success
273 assert_response :success
274 assert_template 'index'
274 assert_template 'index'
275 assert_not_nil assigns(:issues)
275 assert_not_nil assigns(:issues)
276 assert_not_nil assigns(:issue_count_by_group)
276 assert_not_nil assigns(:issue_count_by_group)
277 end
277 end
278
278
279 def test_index_with_query_grouped_by_user_custom_field
279 def test_index_with_query_grouped_by_user_custom_field
280 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
280 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
281 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
281 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
282 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
282 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
283 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
283 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
284 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
284 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
285
285
286 get :index, :project_id => 1, :set_filter => 1, :group_by => "cf_#{cf.id}"
286 get :index, :project_id => 1, :set_filter => 1, :group_by => "cf_#{cf.id}"
287 assert_response :success
287 assert_response :success
288
288
289 assert_select 'tr.group', 3
289 assert_select 'tr.group', 3
290 assert_select 'tr.group' do
290 assert_select 'tr.group' do
291 assert_select 'a', :text => 'John Smith'
291 assert_select 'a', :text => 'John Smith'
292 assert_select 'span.count', :text => '1'
292 assert_select 'span.count', :text => '1'
293 end
293 end
294 assert_select 'tr.group' do
294 assert_select 'tr.group' do
295 assert_select 'a', :text => 'Dave Lopper'
295 assert_select 'a', :text => 'Dave Lopper'
296 assert_select 'span.count', :text => '2'
296 assert_select 'span.count', :text => '2'
297 end
297 end
298 end
298 end
299
299
300 def test_index_with_query_grouped_by_tracker
300 def test_index_with_query_grouped_by_tracker
301 3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
301 3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
302
302
303 get :index, :set_filter => 1, :group_by => 'tracker', :sort => 'id:desc'
303 get :index, :set_filter => 1, :group_by => 'tracker', :sort => 'id:desc'
304 assert_response :success
304 assert_response :success
305
305
306 trackers = assigns(:issues).map(&:tracker).uniq
306 trackers = assigns(:issues).map(&:tracker).uniq
307 assert_equal [1, 2, 3], trackers.map(&:id)
307 assert_equal [1, 2, 3], trackers.map(&:id)
308 end
308 end
309
309
310 def test_index_with_query_grouped_by_tracker_in_reverse_order
310 def test_index_with_query_grouped_by_tracker_in_reverse_order
311 3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
311 3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
312
312
313 get :index, :set_filter => 1, :group_by => 'tracker', :sort => 'id:desc,tracker:desc'
313 get :index, :set_filter => 1, :group_by => 'tracker', :sort => 'id:desc,tracker:desc'
314 assert_response :success
314 assert_response :success
315
315
316 trackers = assigns(:issues).map(&:tracker).uniq
316 trackers = assigns(:issues).map(&:tracker).uniq
317 assert_equal [3, 2, 1], trackers.map(&:id)
317 assert_equal [3, 2, 1], trackers.map(&:id)
318 end
318 end
319
319
320 def test_index_with_query_id_and_project_id_should_set_session_query
320 def test_index_with_query_id_and_project_id_should_set_session_query
321 get :index, :project_id => 1, :query_id => 4
321 get :index, :project_id => 1, :query_id => 4
322 assert_response :success
322 assert_response :success
323 assert_kind_of Hash, session[:query]
323 assert_kind_of Hash, session[:query]
324 assert_equal 4, session[:query][:id]
324 assert_equal 4, session[:query][:id]
325 assert_equal 1, session[:query][:project_id]
325 assert_equal 1, session[:query][:project_id]
326 end
326 end
327
327
328 def test_index_with_invalid_query_id_should_respond_404
328 def test_index_with_invalid_query_id_should_respond_404
329 get :index, :project_id => 1, :query_id => 999
329 get :index, :project_id => 1, :query_id => 999
330 assert_response 404
330 assert_response 404
331 end
331 end
332
332
333 def test_index_with_cross_project_query_in_session_should_show_project_issues
333 def test_index_with_cross_project_query_in_session_should_show_project_issues
334 q = Query.create!(:name => "test", :user_id => 2, :is_public => false, :project => nil)
334 q = Query.create!(:name => "test", :user_id => 2, :is_public => false, :project => nil)
335 @request.session[:query] = {:id => q.id, :project_id => 1}
335 @request.session[:query] = {:id => q.id, :project_id => 1}
336
336
337 with_settings :display_subprojects_issues => '0' do
337 with_settings :display_subprojects_issues => '0' do
338 get :index, :project_id => 1
338 get :index, :project_id => 1
339 end
339 end
340 assert_response :success
340 assert_response :success
341 assert_not_nil assigns(:query)
341 assert_not_nil assigns(:query)
342 assert_equal q.id, assigns(:query).id
342 assert_equal q.id, assigns(:query).id
343 assert_equal 1, assigns(:query).project_id
343 assert_equal 1, assigns(:query).project_id
344 assert_equal [1], assigns(:issues).map(&:project_id).uniq
344 assert_equal [1], assigns(:issues).map(&:project_id).uniq
345 end
345 end
346
346
347 def test_private_query_should_not_be_available_to_other_users
347 def test_private_query_should_not_be_available_to_other_users
348 q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
348 q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
349 @request.session[:user_id] = 3
349 @request.session[:user_id] = 3
350
350
351 get :index, :query_id => q.id
351 get :index, :query_id => q.id
352 assert_response 403
352 assert_response 403
353 end
353 end
354
354
355 def test_private_query_should_be_available_to_its_user
355 def test_private_query_should_be_available_to_its_user
356 q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
356 q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
357 @request.session[:user_id] = 2
357 @request.session[:user_id] = 2
358
358
359 get :index, :query_id => q.id
359 get :index, :query_id => q.id
360 assert_response :success
360 assert_response :success
361 end
361 end
362
362
363 def test_public_query_should_be_available_to_other_users
363 def test_public_query_should_be_available_to_other_users
364 q = Query.create!(:name => "private", :user => User.find(2), :is_public => true, :project => nil)
364 q = Query.create!(:name => "private", :user => User.find(2), :is_public => true, :project => nil)
365 @request.session[:user_id] = 3
365 @request.session[:user_id] = 3
366
366
367 get :index, :query_id => q.id
367 get :index, :query_id => q.id
368 assert_response :success
368 assert_response :success
369 end
369 end
370
370
371 def test_index_should_omit_page_param_in_export_links
371 def test_index_should_omit_page_param_in_export_links
372 get :index, :page => 2
372 get :index, :page => 2
373 assert_response :success
373 assert_response :success
374 assert_select 'a.atom[href=/issues.atom]'
374 assert_select 'a.atom[href=/issues.atom]'
375 assert_select 'a.csv[href=/issues.csv]'
375 assert_select 'a.csv[href=/issues.csv]'
376 assert_select 'a.pdf[href=/issues.pdf]'
376 assert_select 'a.pdf[href=/issues.pdf]'
377 assert_select 'form#csv-export-form[action=/issues.csv]'
377 assert_select 'form#csv-export-form[action=/issues.csv]'
378 end
378 end
379
379
380 def test_index_csv
380 def test_index_csv
381 get :index, :format => 'csv'
381 get :index, :format => 'csv'
382 assert_response :success
382 assert_response :success
383 assert_not_nil assigns(:issues)
383 assert_not_nil assigns(:issues)
384 assert_equal 'text/csv; header=present', @response.content_type
384 assert_equal 'text/csv; header=present', @response.content_type
385 assert @response.body.starts_with?("#,")
385 assert @response.body.starts_with?("#,")
386 lines = @response.body.chomp.split("\n")
386 lines = @response.body.chomp.split("\n")
387 assert_equal assigns(:query).columns.size + 1, lines[0].split(',').size
387 assert_equal assigns(:query).columns.size + 1, lines[0].split(',').size
388 end
388 end
389
389
390 def test_index_csv_with_project
390 def test_index_csv_with_project
391 get :index, :project_id => 1, :format => 'csv'
391 get :index, :project_id => 1, :format => 'csv'
392 assert_response :success
392 assert_response :success
393 assert_not_nil assigns(:issues)
393 assert_not_nil assigns(:issues)
394 assert_equal 'text/csv; header=present', @response.content_type
394 assert_equal 'text/csv; header=present', @response.content_type
395 end
395 end
396
396
397 def test_index_csv_with_description
397 def test_index_csv_with_description
398 get :index, :format => 'csv', :description => '1'
398 get :index, :format => 'csv', :description => '1'
399 assert_response :success
399 assert_response :success
400 assert_not_nil assigns(:issues)
400 assert_not_nil assigns(:issues)
401 assert_equal 'text/csv; header=present', @response.content_type
401 assert_equal 'text/csv; header=present', @response.content_type
402 assert @response.body.starts_with?("#,")
402 assert @response.body.starts_with?("#,")
403 lines = @response.body.chomp.split("\n")
403 lines = @response.body.chomp.split("\n")
404 assert_equal assigns(:query).columns.size + 2, lines[0].split(',').size
404 assert_equal assigns(:query).columns.size + 2, lines[0].split(',').size
405 end
405 end
406
406
407 def test_index_csv_with_spent_time_column
407 def test_index_csv_with_spent_time_column
408 issue = Issue.create!(:project_id => 1, :tracker_id => 1, :subject => 'test_index_csv_with_spent_time_column', :author_id => 2)
408 issue = Issue.create!(:project_id => 1, :tracker_id => 1, :subject => 'test_index_csv_with_spent_time_column', :author_id => 2)
409 TimeEntry.create!(:project => issue.project, :issue => issue, :hours => 7.33, :user => User.find(2), :spent_on => Date.today)
409 TimeEntry.create!(:project => issue.project, :issue => issue, :hours => 7.33, :user => User.find(2), :spent_on => Date.today)
410
410
411 get :index, :format => 'csv', :set_filter => '1', :c => %w(subject spent_hours)
411 get :index, :format => 'csv', :set_filter => '1', :c => %w(subject spent_hours)
412 assert_response :success
412 assert_response :success
413 assert_equal 'text/csv; header=present', @response.content_type
413 assert_equal 'text/csv; header=present', @response.content_type
414 lines = @response.body.chomp.split("\n")
414 lines = @response.body.chomp.split("\n")
415 assert_include "#{issue.id},#{issue.subject},7.33", lines
415 assert_include "#{issue.id},#{issue.subject},7.33", lines
416 end
416 end
417
417
418 def test_index_csv_with_all_columns
418 def test_index_csv_with_all_columns
419 get :index, :format => 'csv', :columns => 'all'
419 get :index, :format => 'csv', :columns => 'all'
420 assert_response :success
420 assert_response :success
421 assert_not_nil assigns(:issues)
421 assert_not_nil assigns(:issues)
422 assert_equal 'text/csv; header=present', @response.content_type
422 assert_equal 'text/csv; header=present', @response.content_type
423 assert @response.body.starts_with?("#,")
423 assert @response.body.starts_with?("#,")
424 lines = @response.body.chomp.split("\n")
424 lines = @response.body.chomp.split("\n")
425 assert_equal assigns(:query).available_inline_columns.size + 1, lines[0].split(',').size
425 assert_equal assigns(:query).available_inline_columns.size + 1, lines[0].split(',').size
426 end
426 end
427
427
428 def test_index_csv_with_multi_column_field
428 def test_index_csv_with_multi_column_field
429 CustomField.find(1).update_attribute :multiple, true
429 CustomField.find(1).update_attribute :multiple, true
430 issue = Issue.find(1)
430 issue = Issue.find(1)
431 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
431 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
432 issue.save!
432 issue.save!
433
433
434 get :index, :format => 'csv', :columns => 'all'
434 get :index, :format => 'csv', :columns => 'all'
435 assert_response :success
435 assert_response :success
436 lines = @response.body.chomp.split("\n")
436 lines = @response.body.chomp.split("\n")
437 assert lines.detect {|line| line.include?('"MySQL, Oracle"')}
437 assert lines.detect {|line| line.include?('"MySQL, Oracle"')}
438 end
438 end
439
439
440 def test_index_csv_big_5
440 def test_index_csv_big_5
441 with_settings :default_language => "zh-TW" do
441 with_settings :default_language => "zh-TW" do
442 str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88"
442 str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88"
443 str_big5 = "\xa4@\xa4\xeb"
443 str_big5 = "\xa4@\xa4\xeb"
444 if str_utf8.respond_to?(:force_encoding)
444 if str_utf8.respond_to?(:force_encoding)
445 str_utf8.force_encoding('UTF-8')
445 str_utf8.force_encoding('UTF-8')
446 str_big5.force_encoding('Big5')
446 str_big5.force_encoding('Big5')
447 end
447 end
448 issue = Issue.generate!(:subject => str_utf8)
448 issue = Issue.generate!(:subject => str_utf8)
449
449
450 get :index, :project_id => 1,
450 get :index, :project_id => 1,
451 :f => ['subject'],
451 :f => ['subject'],
452 :op => '=', :values => [str_utf8],
452 :op => '=', :values => [str_utf8],
453 :format => 'csv'
453 :format => 'csv'
454 assert_equal 'text/csv; header=present', @response.content_type
454 assert_equal 'text/csv; header=present', @response.content_type
455 lines = @response.body.chomp.split("\n")
455 lines = @response.body.chomp.split("\n")
456 s1 = "\xaa\xac\xbaA"
456 s1 = "\xaa\xac\xbaA"
457 if str_utf8.respond_to?(:force_encoding)
457 if str_utf8.respond_to?(:force_encoding)
458 s1.force_encoding('Big5')
458 s1.force_encoding('Big5')
459 end
459 end
460 assert lines[0].include?(s1)
460 assert lines[0].include?(s1)
461 assert lines[1].include?(str_big5)
461 assert lines[1].include?(str_big5)
462 end
462 end
463 end
463 end
464
464
465 def test_index_csv_cannot_convert_should_be_replaced_big_5
465 def test_index_csv_cannot_convert_should_be_replaced_big_5
466 with_settings :default_language => "zh-TW" do
466 with_settings :default_language => "zh-TW" do
467 str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85"
467 str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85"
468 if str_utf8.respond_to?(:force_encoding)
468 if str_utf8.respond_to?(:force_encoding)
469 str_utf8.force_encoding('UTF-8')
469 str_utf8.force_encoding('UTF-8')
470 end
470 end
471 issue = Issue.generate!(:subject => str_utf8)
471 issue = Issue.generate!(:subject => str_utf8)
472
472
473 get :index, :project_id => 1,
473 get :index, :project_id => 1,
474 :f => ['subject'],
474 :f => ['subject'],
475 :op => '=', :values => [str_utf8],
475 :op => '=', :values => [str_utf8],
476 :c => ['status', 'subject'],
476 :c => ['status', 'subject'],
477 :format => 'csv',
477 :format => 'csv',
478 :set_filter => 1
478 :set_filter => 1
479 assert_equal 'text/csv; header=present', @response.content_type
479 assert_equal 'text/csv; header=present', @response.content_type
480 lines = @response.body.chomp.split("\n")
480 lines = @response.body.chomp.split("\n")
481 s1 = "\xaa\xac\xbaA" # status
481 s1 = "\xaa\xac\xbaA" # status
482 if str_utf8.respond_to?(:force_encoding)
482 if str_utf8.respond_to?(:force_encoding)
483 s1.force_encoding('Big5')
483 s1.force_encoding('Big5')
484 end
484 end
485 assert lines[0].include?(s1)
485 assert lines[0].include?(s1)
486 s2 = lines[1].split(",")[2]
486 s2 = lines[1].split(",")[2]
487 if s1.respond_to?(:force_encoding)
487 if s1.respond_to?(:force_encoding)
488 s3 = "\xa5H?" # subject
488 s3 = "\xa5H?" # subject
489 s3.force_encoding('Big5')
489 s3.force_encoding('Big5')
490 assert_equal s3, s2
490 assert_equal s3, s2
491 elsif RUBY_PLATFORM == 'java'
491 elsif RUBY_PLATFORM == 'java'
492 assert_equal "??", s2
492 assert_equal "??", s2
493 else
493 else
494 assert_equal "\xa5H???", s2
494 assert_equal "\xa5H???", s2
495 end
495 end
496 end
496 end
497 end
497 end
498
498
499 def test_index_csv_tw
499 def test_index_csv_tw
500 with_settings :default_language => "zh-TW" do
500 with_settings :default_language => "zh-TW" do
501 str1 = "test_index_csv_tw"
501 str1 = "test_index_csv_tw"
502 issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
502 issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
503
503
504 get :index, :project_id => 1,
504 get :index, :project_id => 1,
505 :f => ['subject'],
505 :f => ['subject'],
506 :op => '=', :values => [str1],
506 :op => '=', :values => [str1],
507 :c => ['estimated_hours', 'subject'],
507 :c => ['estimated_hours', 'subject'],
508 :format => 'csv',
508 :format => 'csv',
509 :set_filter => 1
509 :set_filter => 1
510 assert_equal 'text/csv; header=present', @response.content_type
510 assert_equal 'text/csv; header=present', @response.content_type
511 lines = @response.body.chomp.split("\n")
511 lines = @response.body.chomp.split("\n")
512 assert_equal "#{issue.id},1234.50,#{str1}", lines[1]
512 assert_equal "#{issue.id},1234.50,#{str1}", lines[1]
513 end
513 end
514 end
514 end
515
515
516 def test_index_csv_fr
516 def test_index_csv_fr
517 with_settings :default_language => "fr" do
517 with_settings :default_language => "fr" do
518 str1 = "test_index_csv_fr"
518 str1 = "test_index_csv_fr"
519 issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
519 issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
520
520
521 get :index, :project_id => 1,
521 get :index, :project_id => 1,
522 :f => ['subject'],
522 :f => ['subject'],
523 :op => '=', :values => [str1],
523 :op => '=', :values => [str1],
524 :c => ['estimated_hours', 'subject'],
524 :c => ['estimated_hours', 'subject'],
525 :format => 'csv',
525 :format => 'csv',
526 :set_filter => 1
526 :set_filter => 1
527 assert_equal 'text/csv; header=present', @response.content_type
527 assert_equal 'text/csv; header=present', @response.content_type
528 lines = @response.body.chomp.split("\n")
528 lines = @response.body.chomp.split("\n")
529 assert_equal "#{issue.id};1234,50;#{str1}", lines[1]
529 assert_equal "#{issue.id};1234,50;#{str1}", lines[1]
530 end
530 end
531 end
531 end
532
532
533 def test_index_pdf
533 def test_index_pdf
534 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
534 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
535 with_settings :default_language => lang do
535 with_settings :default_language => lang do
536
536
537 get :index
537 get :index
538 assert_response :success
538 assert_response :success
539 assert_template 'index'
539 assert_template 'index'
540
540
541 if lang == "ja"
541 if lang == "ja"
542 if RUBY_PLATFORM != 'java'
542 if RUBY_PLATFORM != 'java'
543 assert_equal "CP932", l(:general_pdf_encoding)
543 assert_equal "CP932", l(:general_pdf_encoding)
544 end
544 end
545 if RUBY_PLATFORM == 'java' && l(:general_pdf_encoding) == "CP932"
545 if RUBY_PLATFORM == 'java' && l(:general_pdf_encoding) == "CP932"
546 next
546 next
547 end
547 end
548 end
548 end
549
549
550 get :index, :format => 'pdf'
550 get :index, :format => 'pdf'
551 assert_response :success
551 assert_response :success
552 assert_not_nil assigns(:issues)
552 assert_not_nil assigns(:issues)
553 assert_equal 'application/pdf', @response.content_type
553 assert_equal 'application/pdf', @response.content_type
554
554
555 get :index, :project_id => 1, :format => 'pdf'
555 get :index, :project_id => 1, :format => 'pdf'
556 assert_response :success
556 assert_response :success
557 assert_not_nil assigns(:issues)
557 assert_not_nil assigns(:issues)
558 assert_equal 'application/pdf', @response.content_type
558 assert_equal 'application/pdf', @response.content_type
559
559
560 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
560 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
561 assert_response :success
561 assert_response :success
562 assert_not_nil assigns(:issues)
562 assert_not_nil assigns(:issues)
563 assert_equal 'application/pdf', @response.content_type
563 assert_equal 'application/pdf', @response.content_type
564 end
564 end
565 end
565 end
566 end
566 end
567
567
568 def test_index_pdf_with_query_grouped_by_list_custom_field
568 def test_index_pdf_with_query_grouped_by_list_custom_field
569 get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
569 get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
570 assert_response :success
570 assert_response :success
571 assert_not_nil assigns(:issues)
571 assert_not_nil assigns(:issues)
572 assert_not_nil assigns(:issue_count_by_group)
572 assert_not_nil assigns(:issue_count_by_group)
573 assert_equal 'application/pdf', @response.content_type
573 assert_equal 'application/pdf', @response.content_type
574 end
574 end
575
575
576 def test_index_atom
576 def test_index_atom
577 get :index, :project_id => 'ecookbook', :format => 'atom'
577 get :index, :project_id => 'ecookbook', :format => 'atom'
578 assert_response :success
578 assert_response :success
579 assert_template 'common/feed'
579 assert_template 'common/feed'
580 assert_equal 'application/atom+xml', response.content_type
580 assert_equal 'application/atom+xml', response.content_type
581
581
582 assert_select 'feed' do
582 assert_select 'feed' do
583 assert_select 'link[rel=self][href=?]', 'http://test.host/projects/ecookbook/issues.atom'
583 assert_select 'link[rel=self][href=?]', 'http://test.host/projects/ecookbook/issues.atom'
584 assert_select 'link[rel=alternate][href=?]', 'http://test.host/projects/ecookbook/issues'
584 assert_select 'link[rel=alternate][href=?]', 'http://test.host/projects/ecookbook/issues'
585 assert_select 'entry link[href=?]', 'http://test.host/issues/1'
585 assert_select 'entry link[href=?]', 'http://test.host/issues/1'
586 end
586 end
587 end
587 end
588
588
589 def test_index_sort
589 def test_index_sort
590 get :index, :sort => 'tracker,id:desc'
590 get :index, :sort => 'tracker,id:desc'
591 assert_response :success
591 assert_response :success
592
592
593 sort_params = @request.session['issues_index_sort']
593 sort_params = @request.session['issues_index_sort']
594 assert sort_params.is_a?(String)
594 assert sort_params.is_a?(String)
595 assert_equal 'tracker,id:desc', sort_params
595 assert_equal 'tracker,id:desc', sort_params
596
596
597 issues = assigns(:issues)
597 issues = assigns(:issues)
598 assert_not_nil issues
598 assert_not_nil issues
599 assert !issues.empty?
599 assert !issues.empty?
600 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
600 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
601 end
601 end
602
602
603 def test_index_sort_by_field_not_included_in_columns
603 def test_index_sort_by_field_not_included_in_columns
604 Setting.issue_list_default_columns = %w(subject author)
604 Setting.issue_list_default_columns = %w(subject author)
605 get :index, :sort => 'tracker'
605 get :index, :sort => 'tracker'
606 end
606 end
607
607
608 def test_index_sort_by_assigned_to
608 def test_index_sort_by_assigned_to
609 get :index, :sort => 'assigned_to'
609 get :index, :sort => 'assigned_to'
610 assert_response :success
610 assert_response :success
611 assignees = assigns(:issues).collect(&:assigned_to).compact
611 assignees = assigns(:issues).collect(&:assigned_to).compact
612 assert_equal assignees.sort, assignees
612 assert_equal assignees.sort, assignees
613 end
613 end
614
614
615 def test_index_sort_by_assigned_to_desc
615 def test_index_sort_by_assigned_to_desc
616 get :index, :sort => 'assigned_to:desc'
616 get :index, :sort => 'assigned_to:desc'
617 assert_response :success
617 assert_response :success
618 assignees = assigns(:issues).collect(&:assigned_to).compact
618 assignees = assigns(:issues).collect(&:assigned_to).compact
619 assert_equal assignees.sort.reverse, assignees
619 assert_equal assignees.sort.reverse, assignees
620 end
620 end
621
621
622 def test_index_group_by_assigned_to
622 def test_index_group_by_assigned_to
623 get :index, :group_by => 'assigned_to', :sort => 'priority'
623 get :index, :group_by => 'assigned_to', :sort => 'priority'
624 assert_response :success
624 assert_response :success
625 end
625 end
626
626
627 def test_index_sort_by_author
627 def test_index_sort_by_author
628 get :index, :sort => 'author'
628 get :index, :sort => 'author'
629 assert_response :success
629 assert_response :success
630 authors = assigns(:issues).collect(&:author)
630 authors = assigns(:issues).collect(&:author)
631 assert_equal authors.sort, authors
631 assert_equal authors.sort, authors
632 end
632 end
633
633
634 def test_index_sort_by_author_desc
634 def test_index_sort_by_author_desc
635 get :index, :sort => 'author:desc'
635 get :index, :sort => 'author:desc'
636 assert_response :success
636 assert_response :success
637 authors = assigns(:issues).collect(&:author)
637 authors = assigns(:issues).collect(&:author)
638 assert_equal authors.sort.reverse, authors
638 assert_equal authors.sort.reverse, authors
639 end
639 end
640
640
641 def test_index_group_by_author
641 def test_index_group_by_author
642 get :index, :group_by => 'author', :sort => 'priority'
642 get :index, :group_by => 'author', :sort => 'priority'
643 assert_response :success
643 assert_response :success
644 end
644 end
645
645
646 def test_index_sort_by_spent_hours
646 def test_index_sort_by_spent_hours
647 get :index, :sort => 'spent_hours:desc'
647 get :index, :sort => 'spent_hours:desc'
648 assert_response :success
648 assert_response :success
649 hours = assigns(:issues).collect(&:spent_hours)
649 hours = assigns(:issues).collect(&:spent_hours)
650 assert_equal hours.sort.reverse, hours
650 assert_equal hours.sort.reverse, hours
651 end
651 end
652
652
653 def test_index_sort_by_user_custom_field
653 def test_index_sort_by_user_custom_field
654 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
654 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
655 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
655 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
656 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
656 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
657 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
657 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
658 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
658 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
659
659
660 get :index, :project_id => 1, :set_filter => 1, :sort => "cf_#{cf.id},id"
660 get :index, :project_id => 1, :set_filter => 1, :sort => "cf_#{cf.id},id"
661 assert_response :success
661 assert_response :success
662
662
663 assert_equal [2, 3, 1], assigns(:issues).select {|issue| issue.custom_field_value(cf).present?}.map(&:id)
663 assert_equal [2, 3, 1], assigns(:issues).select {|issue| issue.custom_field_value(cf).present?}.map(&:id)
664 end
664 end
665
665
666 def test_index_with_columns
666 def test_index_with_columns
667 columns = ['tracker', 'subject', 'assigned_to']
667 columns = ['tracker', 'subject', 'assigned_to']
668 get :index, :set_filter => 1, :c => columns
668 get :index, :set_filter => 1, :c => columns
669 assert_response :success
669 assert_response :success
670
670
671 # query should use specified columns
671 # query should use specified columns
672 query = assigns(:query)
672 query = assigns(:query)
673 assert_kind_of Query, query
673 assert_kind_of Query, query
674 assert_equal columns, query.column_names.map(&:to_s)
674 assert_equal columns, query.column_names.map(&:to_s)
675
675
676 # columns should be stored in session
676 # columns should be stored in session
677 assert_kind_of Hash, session[:query]
677 assert_kind_of Hash, session[:query]
678 assert_kind_of Array, session[:query][:column_names]
678 assert_kind_of Array, session[:query][:column_names]
679 assert_equal columns, session[:query][:column_names].map(&:to_s)
679 assert_equal columns, session[:query][:column_names].map(&:to_s)
680
680
681 # ensure only these columns are kept in the selected columns list
681 # ensure only these columns are kept in the selected columns list
682 assert_select 'select#selected_columns option' do
682 assert_select 'select#selected_columns option' do
683 assert_select 'option', 3
683 assert_select 'option', 3
684 assert_select 'option[value=tracker]'
684 assert_select 'option[value=tracker]'
685 assert_select 'option[value=project]', 0
685 assert_select 'option[value=project]', 0
686 end
686 end
687 end
687 end
688
688
689 def test_index_without_project_should_implicitly_add_project_column_to_default_columns
689 def test_index_without_project_should_implicitly_add_project_column_to_default_columns
690 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
690 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
691 get :index, :set_filter => 1
691 get :index, :set_filter => 1
692
692
693 # query should use specified columns
693 # query should use specified columns
694 query = assigns(:query)
694 query = assigns(:query)
695 assert_kind_of Query, query
695 assert_kind_of Query, query
696 assert_equal [:project, :tracker, :subject, :assigned_to], query.columns.map(&:name)
696 assert_equal [:project, :tracker, :subject, :assigned_to], query.columns.map(&:name)
697 end
697 end
698
698
699 def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
699 def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
700 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
700 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
701 columns = ['tracker', 'subject', 'assigned_to']
701 columns = ['tracker', 'subject', 'assigned_to']
702 get :index, :set_filter => 1, :c => columns
702 get :index, :set_filter => 1, :c => columns
703
703
704 # query should use specified columns
704 # query should use specified columns
705 query = assigns(:query)
705 query = assigns(:query)
706 assert_kind_of Query, query
706 assert_kind_of Query, query
707 assert_equal columns.map(&:to_sym), query.columns.map(&:name)
707 assert_equal columns.map(&:to_sym), query.columns.map(&:name)
708 end
708 end
709
709
710 def test_index_with_custom_field_column
710 def test_index_with_custom_field_column
711 columns = %w(tracker subject cf_2)
711 columns = %w(tracker subject cf_2)
712 get :index, :set_filter => 1, :c => columns
712 get :index, :set_filter => 1, :c => columns
713 assert_response :success
713 assert_response :success
714
714
715 # query should use specified columns
715 # query should use specified columns
716 query = assigns(:query)
716 query = assigns(:query)
717 assert_kind_of Query, query
717 assert_kind_of Query, query
718 assert_equal columns, query.column_names.map(&:to_s)
718 assert_equal columns, query.column_names.map(&:to_s)
719
719
720 assert_select 'table.issues td.cf_2.string'
720 assert_select 'table.issues td.cf_2.string'
721 end
721 end
722
722
723 def test_index_with_multi_custom_field_column
723 def test_index_with_multi_custom_field_column
724 field = CustomField.find(1)
724 field = CustomField.find(1)
725 field.update_attribute :multiple, true
725 field.update_attribute :multiple, true
726 issue = Issue.find(1)
726 issue = Issue.find(1)
727 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
727 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
728 issue.save!
728 issue.save!
729
729
730 get :index, :set_filter => 1, :c => %w(tracker subject cf_1)
730 get :index, :set_filter => 1, :c => %w(tracker subject cf_1)
731 assert_response :success
731 assert_response :success
732
732
733 assert_select 'table.issues td.cf_1', :text => 'MySQL, Oracle'
733 assert_select 'table.issues td.cf_1', :text => 'MySQL, Oracle'
734 end
734 end
735
735
736 def test_index_with_multi_user_custom_field_column
736 def test_index_with_multi_user_custom_field_column
737 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
737 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
738 :tracker_ids => [1], :is_for_all => true)
738 :tracker_ids => [1], :is_for_all => true)
739 issue = Issue.find(1)
739 issue = Issue.find(1)
740 issue.custom_field_values = {field.id => ['2', '3']}
740 issue.custom_field_values = {field.id => ['2', '3']}
741 issue.save!
741 issue.save!
742
742
743 get :index, :set_filter => 1, :c => ['tracker', 'subject', "cf_#{field.id}"]
743 get :index, :set_filter => 1, :c => ['tracker', 'subject', "cf_#{field.id}"]
744 assert_response :success
744 assert_response :success
745
745
746 assert_select "table.issues td.cf_#{field.id}" do
746 assert_select "table.issues td.cf_#{field.id}" do
747 assert_select 'a', 2
747 assert_select 'a', 2
748 assert_select 'a[href=?]', '/users/2', :text => 'John Smith'
748 assert_select 'a[href=?]', '/users/2', :text => 'John Smith'
749 assert_select 'a[href=?]', '/users/3', :text => 'Dave Lopper'
749 assert_select 'a[href=?]', '/users/3', :text => 'Dave Lopper'
750 end
750 end
751 end
751 end
752
752
753 def test_index_with_date_column
753 def test_index_with_date_column
754 with_settings :date_format => '%d/%m/%Y' do
754 with_settings :date_format => '%d/%m/%Y' do
755 Issue.find(1).update_attribute :start_date, '1987-08-24'
755 Issue.find(1).update_attribute :start_date, '1987-08-24'
756
756
757 get :index, :set_filter => 1, :c => %w(start_date)
757 get :index, :set_filter => 1, :c => %w(start_date)
758
758
759 assert_select "table.issues td.start_date", :text => '24/08/1987'
759 assert_select "table.issues td.start_date", :text => '24/08/1987'
760 end
760 end
761 end
761 end
762
762
763 def test_index_with_done_ratio_column
763 def test_index_with_done_ratio_column
764 Issue.find(1).update_attribute :done_ratio, 40
764 Issue.find(1).update_attribute :done_ratio, 40
765
765
766 get :index, :set_filter => 1, :c => %w(done_ratio)
766 get :index, :set_filter => 1, :c => %w(done_ratio)
767
767
768 assert_select 'table.issues td.done_ratio' do
768 assert_select 'table.issues td.done_ratio' do
769 assert_select 'table.progress' do
769 assert_select 'table.progress' do
770 assert_select 'td.closed[style=?]', 'width: 40%;'
770 assert_select 'td.closed[style=?]', 'width: 40%;'
771 end
771 end
772 end
772 end
773 end
773 end
774
774
775 def test_index_with_spent_hours_column
775 def test_index_with_spent_hours_column
776 get :index, :set_filter => 1, :c => %w(subject spent_hours)
776 get :index, :set_filter => 1, :c => %w(subject spent_hours)
777
777
778 assert_select 'table.issues tr#issue-3 td.spent_hours', :text => '1.00'
778 assert_select 'table.issues tr#issue-3 td.spent_hours', :text => '1.00'
779 end
779 end
780
780
781 def test_index_should_not_show_spent_hours_column_without_permission
781 def test_index_should_not_show_spent_hours_column_without_permission
782 Role.anonymous.remove_permission! :view_time_entries
782 Role.anonymous.remove_permission! :view_time_entries
783 get :index, :set_filter => 1, :c => %w(subject spent_hours)
783 get :index, :set_filter => 1, :c => %w(subject spent_hours)
784
784
785 assert_select 'td.spent_hours', 0
785 assert_select 'td.spent_hours', 0
786 end
786 end
787
787
788 def test_index_with_fixed_version_column
788 def test_index_with_fixed_version_column
789 get :index, :set_filter => 1, :c => %w(fixed_version)
789 get :index, :set_filter => 1, :c => %w(fixed_version)
790
790
791 assert_select 'table.issues td.fixed_version' do
791 assert_select 'table.issues td.fixed_version' do
792 assert_select 'a[href=?]', '/versions/2', :text => '1.0'
792 assert_select 'a[href=?]', '/versions/2', :text => '1.0'
793 end
793 end
794 end
794 end
795
795
796 def test_index_with_relations_column
796 def test_index_with_relations_column
797 IssueRelation.delete_all
797 IssueRelation.delete_all
798 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(7))
798 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(7))
799 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(8), :issue_to => Issue.find(1))
799 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(8), :issue_to => Issue.find(1))
800 IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(1), :issue_to => Issue.find(11))
800 IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(1), :issue_to => Issue.find(11))
801 IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(12), :issue_to => Issue.find(2))
801 IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(12), :issue_to => Issue.find(2))
802
802
803 get :index, :set_filter => 1, :c => %w(subject relations)
803 get :index, :set_filter => 1, :c => %w(subject relations)
804 assert_response :success
804 assert_response :success
805 assert_select "tr#issue-1 td.relations" do
805 assert_select "tr#issue-1 td.relations" do
806 assert_select "span", 3
806 assert_select "span", 3
807 assert_select "span", :text => "Related to #7"
807 assert_select "span", :text => "Related to #7"
808 assert_select "span", :text => "Related to #8"
808 assert_select "span", :text => "Related to #8"
809 assert_select "span", :text => "Blocks #11"
809 assert_select "span", :text => "Blocks #11"
810 end
810 end
811 assert_select "tr#issue-2 td.relations" do
811 assert_select "tr#issue-2 td.relations" do
812 assert_select "span", 1
812 assert_select "span", 1
813 assert_select "span", :text => "Blocked by #12"
813 assert_select "span", :text => "Blocked by #12"
814 end
814 end
815 assert_select "tr#issue-3 td.relations" do
815 assert_select "tr#issue-3 td.relations" do
816 assert_select "span", 0
816 assert_select "span", 0
817 end
817 end
818
818
819 get :index, :set_filter => 1, :c => %w(relations), :format => 'csv'
819 get :index, :set_filter => 1, :c => %w(relations), :format => 'csv'
820 assert_response :success
820 assert_response :success
821 assert_equal 'text/csv; header=present', response.content_type
821 assert_equal 'text/csv; header=present', response.content_type
822 lines = response.body.chomp.split("\n")
822 lines = response.body.chomp.split("\n")
823 assert_include '1,"Related to #7, Related to #8, Blocks #11"', lines
823 assert_include '1,"Related to #7, Related to #8, Blocks #11"', lines
824 assert_include '2,Blocked by #12', lines
824 assert_include '2,Blocked by #12', lines
825 assert_include '3,""', lines
825 assert_include '3,""', lines
826
826
827 get :index, :set_filter => 1, :c => %w(subject relations), :format => 'pdf'
827 get :index, :set_filter => 1, :c => %w(subject relations), :format => 'pdf'
828 assert_response :success
828 assert_response :success
829 assert_equal 'application/pdf', response.content_type
829 assert_equal 'application/pdf', response.content_type
830 end
830 end
831
831
832 def test_index_with_description_column
832 def test_index_with_description_column
833 get :index, :set_filter => 1, :c => %w(subject description)
833 get :index, :set_filter => 1, :c => %w(subject description)
834
834
835 assert_select 'table.issues thead th', 3 # columns: chekbox + id + subject
835 assert_select 'table.issues thead th', 3 # columns: chekbox + id + subject
836 assert_select 'td.description[colspan=3]', :text => 'Unable to print recipes'
836 assert_select 'td.description[colspan=3]', :text => 'Unable to print recipes'
837
837
838 get :index, :set_filter => 1, :c => %w(subject description), :format => 'pdf'
838 get :index, :set_filter => 1, :c => %w(subject description), :format => 'pdf'
839 assert_response :success
839 assert_response :success
840 assert_equal 'application/pdf', response.content_type
840 assert_equal 'application/pdf', response.content_type
841 end
841 end
842
842
843 def test_index_send_html_if_query_is_invalid
843 def test_index_send_html_if_query_is_invalid
844 get :index, :f => ['start_date'], :op => {:start_date => '='}
844 get :index, :f => ['start_date'], :op => {:start_date => '='}
845 assert_equal 'text/html', @response.content_type
845 assert_equal 'text/html', @response.content_type
846 assert_template 'index'
846 assert_template 'index'
847 end
847 end
848
848
849 def test_index_send_nothing_if_query_is_invalid
849 def test_index_send_nothing_if_query_is_invalid
850 get :index, :f => ['start_date'], :op => {:start_date => '='}, :format => 'csv'
850 get :index, :f => ['start_date'], :op => {:start_date => '='}, :format => 'csv'
851 assert_equal 'text/csv', @response.content_type
851 assert_equal 'text/csv', @response.content_type
852 assert @response.body.blank?
852 assert @response.body.blank?
853 end
853 end
854
854
855 def test_show_by_anonymous
855 def test_show_by_anonymous
856 get :show, :id => 1
856 get :show, :id => 1
857 assert_response :success
857 assert_response :success
858 assert_template 'show'
858 assert_template 'show'
859 assert_equal Issue.find(1), assigns(:issue)
859 assert_equal Issue.find(1), assigns(:issue)
860
860
861 assert_select 'div.issue div.description', :text => /Unable to print recipes/
861 assert_select 'div.issue div.description', :text => /Unable to print recipes/
862
862
863 # anonymous role is allowed to add a note
863 # anonymous role is allowed to add a note
864 assert_select 'form#issue-form' do
864 assert_select 'form#issue-form' do
865 assert_select 'fieldset' do
865 assert_select 'fieldset' do
866 assert_select 'legend', :text => 'Notes'
866 assert_select 'legend', :text => 'Notes'
867 assert_select 'textarea[name=?]', 'issue[notes]'
867 assert_select 'textarea[name=?]', 'issue[notes]'
868 end
868 end
869 end
869 end
870
870
871 assert_select 'title', :text => "Bug #1: Can&#x27;t print recipes - eCookbook - Redmine"
871 assert_select 'title', :text => "Bug #1: Can&#x27;t print recipes - eCookbook - Redmine"
872 end
872 end
873
873
874 def test_show_by_manager
874 def test_show_by_manager
875 @request.session[:user_id] = 2
875 @request.session[:user_id] = 2
876 get :show, :id => 1
876 get :show, :id => 1
877 assert_response :success
877 assert_response :success
878
878
879 assert_select 'a', :text => /Quote/
879 assert_select 'a', :text => /Quote/
880
880
881 assert_select 'form#issue-form' do
881 assert_select 'form#issue-form' do
882 assert_select 'fieldset' do
882 assert_select 'fieldset' do
883 assert_select 'legend', :text => 'Change properties'
883 assert_select 'legend', :text => 'Change properties'
884 assert_select 'input[name=?]', 'issue[subject]'
884 assert_select 'input[name=?]', 'issue[subject]'
885 end
885 end
886 assert_select 'fieldset' do
886 assert_select 'fieldset' do
887 assert_select 'legend', :text => 'Log time'
887 assert_select 'legend', :text => 'Log time'
888 assert_select 'input[name=?]', 'time_entry[hours]'
888 assert_select 'input[name=?]', 'time_entry[hours]'
889 end
889 end
890 assert_select 'fieldset' do
890 assert_select 'fieldset' do
891 assert_select 'legend', :text => 'Notes'
891 assert_select 'legend', :text => 'Notes'
892 assert_select 'textarea[name=?]', 'issue[notes]'
892 assert_select 'textarea[name=?]', 'issue[notes]'
893 end
893 end
894 end
894 end
895 end
895 end
896
896
897 def test_show_should_display_update_form
897 def test_show_should_display_update_form
898 @request.session[:user_id] = 2
898 @request.session[:user_id] = 2
899 get :show, :id => 1
899 get :show, :id => 1
900 assert_response :success
900 assert_response :success
901
901
902 assert_tag 'form', :attributes => {:id => 'issue-form'}
902 assert_tag 'form', :attributes => {:id => 'issue-form'}
903 assert_tag 'input', :attributes => {:name => 'issue[is_private]'}
903 assert_tag 'input', :attributes => {:name => 'issue[is_private]'}
904 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
904 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
905 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
905 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
906 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
906 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
907 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
907 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
908 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
908 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
909 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
909 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
910 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
910 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
911 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
911 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
912 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
912 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
913 assert_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
913 assert_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
914 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
914 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
915 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
915 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
916 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
916 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
917 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
917 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
918 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
918 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
919 assert_tag 'textarea', :attributes => {:name => 'issue[notes]'}
919 assert_tag 'textarea', :attributes => {:name => 'issue[notes]'}
920 end
920 end
921
921
922 def test_show_should_display_update_form_with_minimal_permissions
922 def test_show_should_display_update_form_with_minimal_permissions
923 Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
923 Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
924 WorkflowTransition.delete_all :role_id => 1
924 WorkflowTransition.delete_all :role_id => 1
925
925
926 @request.session[:user_id] = 2
926 @request.session[:user_id] = 2
927 get :show, :id => 1
927 get :show, :id => 1
928 assert_response :success
928 assert_response :success
929
929
930 assert_tag 'form', :attributes => {:id => 'issue-form'}
930 assert_tag 'form', :attributes => {:id => 'issue-form'}
931 assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
931 assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
932 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
932 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
933 assert_no_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
933 assert_no_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
934 assert_no_tag 'input', :attributes => {:name => 'issue[subject]'}
934 assert_no_tag 'input', :attributes => {:name => 'issue[subject]'}
935 assert_no_tag 'textarea', :attributes => {:name => 'issue[description]'}
935 assert_no_tag 'textarea', :attributes => {:name => 'issue[description]'}
936 assert_no_tag 'select', :attributes => {:name => 'issue[status_id]'}
936 assert_no_tag 'select', :attributes => {:name => 'issue[status_id]'}
937 assert_no_tag 'select', :attributes => {:name => 'issue[priority_id]'}
937 assert_no_tag 'select', :attributes => {:name => 'issue[priority_id]'}
938 assert_no_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
938 assert_no_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
939 assert_no_tag 'select', :attributes => {:name => 'issue[category_id]'}
939 assert_no_tag 'select', :attributes => {:name => 'issue[category_id]'}
940 assert_no_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
940 assert_no_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
941 assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
941 assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
942 assert_no_tag 'input', :attributes => {:name => 'issue[start_date]'}
942 assert_no_tag 'input', :attributes => {:name => 'issue[start_date]'}
943 assert_no_tag 'input', :attributes => {:name => 'issue[due_date]'}
943 assert_no_tag 'input', :attributes => {:name => 'issue[due_date]'}
944 assert_no_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
944 assert_no_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
945 assert_no_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
945 assert_no_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
946 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
946 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
947 assert_tag 'textarea', :attributes => {:name => 'issue[notes]'}
947 assert_tag 'textarea', :attributes => {:name => 'issue[notes]'}
948 end
948 end
949
949
950 def test_show_should_display_update_form_with_workflow_permissions
950 def test_show_should_display_update_form_with_workflow_permissions
951 Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
951 Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
952
952
953 @request.session[:user_id] = 2
953 @request.session[:user_id] = 2
954 get :show, :id => 1
954 get :show, :id => 1
955 assert_response :success
955 assert_response :success
956
956
957 assert_tag 'form', :attributes => {:id => 'issue-form'}
957 assert_tag 'form', :attributes => {:id => 'issue-form'}
958 assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
958 assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
959 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
959 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
960 assert_no_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
960 assert_no_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
961 assert_no_tag 'input', :attributes => {:name => 'issue[subject]'}
961 assert_no_tag 'input', :attributes => {:name => 'issue[subject]'}
962 assert_no_tag 'textarea', :attributes => {:name => 'issue[description]'}
962 assert_no_tag 'textarea', :attributes => {:name => 'issue[description]'}
963 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
963 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
964 assert_no_tag 'select', :attributes => {:name => 'issue[priority_id]'}
964 assert_no_tag 'select', :attributes => {:name => 'issue[priority_id]'}
965 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
965 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
966 assert_no_tag 'select', :attributes => {:name => 'issue[category_id]'}
966 assert_no_tag 'select', :attributes => {:name => 'issue[category_id]'}
967 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
967 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
968 assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
968 assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
969 assert_no_tag 'input', :attributes => {:name => 'issue[start_date]'}
969 assert_no_tag 'input', :attributes => {:name => 'issue[start_date]'}
970 assert_no_tag 'input', :attributes => {:name => 'issue[due_date]'}
970 assert_no_tag 'input', :attributes => {:name => 'issue[due_date]'}
971 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
971 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
972 assert_no_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
972 assert_no_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
973 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
973 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
974 assert_tag 'textarea', :attributes => {:name => 'issue[notes]'}
974 assert_tag 'textarea', :attributes => {:name => 'issue[notes]'}
975 end
975 end
976
976
977 def test_show_should_not_display_update_form_without_permissions
977 def test_show_should_not_display_update_form_without_permissions
978 Role.find(1).update_attribute :permissions, [:view_issues]
978 Role.find(1).update_attribute :permissions, [:view_issues]
979
979
980 @request.session[:user_id] = 2
980 @request.session[:user_id] = 2
981 get :show, :id => 1
981 get :show, :id => 1
982 assert_response :success
982 assert_response :success
983
983
984 assert_select 'form#issue-form', 0
984 assert_select 'form#issue-form', 0
985 end
985 end
986
986
987 def test_update_form_should_not_display_inactive_enumerations
987 def test_update_form_should_not_display_inactive_enumerations
988 assert !IssuePriority.find(15).active?
988 assert !IssuePriority.find(15).active?
989
989
990 @request.session[:user_id] = 2
990 @request.session[:user_id] = 2
991 get :show, :id => 1
991 get :show, :id => 1
992 assert_response :success
992 assert_response :success
993
993
994 assert_select 'form#issue-form' do
994 assert_select 'form#issue-form' do
995 assert_select 'select[name=?]', 'issue[priority_id]' do
995 assert_select 'select[name=?]', 'issue[priority_id]' do
996 assert_select 'option[value=4]'
996 assert_select 'option[value=4]'
997 assert_select 'option[value=15]', 0
997 assert_select 'option[value=15]', 0
998 end
998 end
999 end
999 end
1000 end
1000 end
1001
1001
1002 def test_update_form_should_allow_attachment_upload
1002 def test_update_form_should_allow_attachment_upload
1003 @request.session[:user_id] = 2
1003 @request.session[:user_id] = 2
1004 get :show, :id => 1
1004 get :show, :id => 1
1005
1005
1006 assert_select 'form#issue-form[method=post][enctype=multipart/form-data]' do
1006 assert_select 'form#issue-form[method=post][enctype=multipart/form-data]' do
1007 assert_select 'input[type=file][name=?]', 'attachments[1][file]'
1007 assert_select 'input[type=file][name=?]', 'attachments[1][file]'
1008 end
1008 end
1009 end
1009 end
1010
1010
1011 def test_show_should_deny_anonymous_access_without_permission
1011 def test_show_should_deny_anonymous_access_without_permission
1012 Role.anonymous.remove_permission!(:view_issues)
1012 Role.anonymous.remove_permission!(:view_issues)
1013 get :show, :id => 1
1013 get :show, :id => 1
1014 assert_response :redirect
1014 assert_response :redirect
1015 end
1015 end
1016
1016
1017 def test_show_should_deny_anonymous_access_to_private_issue
1017 def test_show_should_deny_anonymous_access_to_private_issue
1018 Issue.update_all(["is_private = ?", true], "id = 1")
1018 Issue.update_all(["is_private = ?", true], "id = 1")
1019 get :show, :id => 1
1019 get :show, :id => 1
1020 assert_response :redirect
1020 assert_response :redirect
1021 end
1021 end
1022
1022
1023 def test_show_should_deny_non_member_access_without_permission
1023 def test_show_should_deny_non_member_access_without_permission
1024 Role.non_member.remove_permission!(:view_issues)
1024 Role.non_member.remove_permission!(:view_issues)
1025 @request.session[:user_id] = 9
1025 @request.session[:user_id] = 9
1026 get :show, :id => 1
1026 get :show, :id => 1
1027 assert_response 403
1027 assert_response 403
1028 end
1028 end
1029
1029
1030 def test_show_should_deny_non_member_access_to_private_issue
1030 def test_show_should_deny_non_member_access_to_private_issue
1031 Issue.update_all(["is_private = ?", true], "id = 1")
1031 Issue.update_all(["is_private = ?", true], "id = 1")
1032 @request.session[:user_id] = 9
1032 @request.session[:user_id] = 9
1033 get :show, :id => 1
1033 get :show, :id => 1
1034 assert_response 403
1034 assert_response 403
1035 end
1035 end
1036
1036
1037 def test_show_should_deny_member_access_without_permission
1037 def test_show_should_deny_member_access_without_permission
1038 Role.find(1).remove_permission!(:view_issues)
1038 Role.find(1).remove_permission!(:view_issues)
1039 @request.session[:user_id] = 2
1039 @request.session[:user_id] = 2
1040 get :show, :id => 1
1040 get :show, :id => 1
1041 assert_response 403
1041 assert_response 403
1042 end
1042 end
1043
1043
1044 def test_show_should_deny_member_access_to_private_issue_without_permission
1044 def test_show_should_deny_member_access_to_private_issue_without_permission
1045 Issue.update_all(["is_private = ?", true], "id = 1")
1045 Issue.update_all(["is_private = ?", true], "id = 1")
1046 @request.session[:user_id] = 3
1046 @request.session[:user_id] = 3
1047 get :show, :id => 1
1047 get :show, :id => 1
1048 assert_response 403
1048 assert_response 403
1049 end
1049 end
1050
1050
1051 def test_show_should_allow_author_access_to_private_issue
1051 def test_show_should_allow_author_access_to_private_issue
1052 Issue.update_all(["is_private = ?, author_id = 3", true], "id = 1")
1052 Issue.update_all(["is_private = ?, author_id = 3", true], "id = 1")
1053 @request.session[:user_id] = 3
1053 @request.session[:user_id] = 3
1054 get :show, :id => 1
1054 get :show, :id => 1
1055 assert_response :success
1055 assert_response :success
1056 end
1056 end
1057
1057
1058 def test_show_should_allow_assignee_access_to_private_issue
1058 def test_show_should_allow_assignee_access_to_private_issue
1059 Issue.update_all(["is_private = ?, assigned_to_id = 3", true], "id = 1")
1059 Issue.update_all(["is_private = ?, assigned_to_id = 3", true], "id = 1")
1060 @request.session[:user_id] = 3
1060 @request.session[:user_id] = 3
1061 get :show, :id => 1
1061 get :show, :id => 1
1062 assert_response :success
1062 assert_response :success
1063 end
1063 end
1064
1064
1065 def test_show_should_allow_member_access_to_private_issue_with_permission
1065 def test_show_should_allow_member_access_to_private_issue_with_permission
1066 Issue.update_all(["is_private = ?", true], "id = 1")
1066 Issue.update_all(["is_private = ?", true], "id = 1")
1067 User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
1067 User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
1068 @request.session[:user_id] = 3
1068 @request.session[:user_id] = 3
1069 get :show, :id => 1
1069 get :show, :id => 1
1070 assert_response :success
1070 assert_response :success
1071 end
1071 end
1072
1072
1073 def test_show_should_not_disclose_relations_to_invisible_issues
1073 def test_show_should_not_disclose_relations_to_invisible_issues
1074 Setting.cross_project_issue_relations = '1'
1074 Setting.cross_project_issue_relations = '1'
1075 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
1075 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
1076 # Relation to a private project issue
1076 # Relation to a private project issue
1077 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
1077 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
1078
1078
1079 get :show, :id => 1
1079 get :show, :id => 1
1080 assert_response :success
1080 assert_response :success
1081
1081
1082 assert_select 'div#relations' do
1082 assert_select 'div#relations' do
1083 assert_select 'a', :text => /#2$/
1083 assert_select 'a', :text => /#2$/
1084 assert_select 'a', :text => /#4$/, :count => 0
1084 assert_select 'a', :text => /#4$/, :count => 0
1085 end
1085 end
1086 end
1086 end
1087
1087
1088 def test_show_should_list_subtasks
1088 def test_show_should_list_subtasks
1089 Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1089 Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1090
1090
1091 get :show, :id => 1
1091 get :show, :id => 1
1092 assert_response :success
1092 assert_response :success
1093
1093
1094 assert_select 'div#issue_tree' do
1094 assert_select 'div#issue_tree' do
1095 assert_select 'td.subject', :text => /Child Issue/
1095 assert_select 'td.subject', :text => /Child Issue/
1096 end
1096 end
1097 end
1097 end
1098
1098
1099 def test_show_should_list_parents
1099 def test_show_should_list_parents
1100 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1100 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1101
1101
1102 get :show, :id => issue.id
1102 get :show, :id => issue.id
1103 assert_response :success
1103 assert_response :success
1104
1104
1105 assert_select 'div.subject' do
1105 assert_select 'div.subject' do
1106 assert_select 'h3', 'Child Issue'
1106 assert_select 'h3', 'Child Issue'
1107 assert_select 'a[href=/issues/1]'
1107 assert_select 'a[href=/issues/1]'
1108 end
1108 end
1109 end
1109 end
1110
1110
1111 def test_show_should_not_display_prev_next_links_without_query_in_session
1111 def test_show_should_not_display_prev_next_links_without_query_in_session
1112 get :show, :id => 1
1112 get :show, :id => 1
1113 assert_response :success
1113 assert_response :success
1114 assert_nil assigns(:prev_issue_id)
1114 assert_nil assigns(:prev_issue_id)
1115 assert_nil assigns(:next_issue_id)
1115 assert_nil assigns(:next_issue_id)
1116
1116
1117 assert_select 'div.next-prev-links', 0
1117 assert_select 'div.next-prev-links', 0
1118 end
1118 end
1119
1119
1120 def test_show_should_display_prev_next_links_with_query_in_session
1120 def test_show_should_display_prev_next_links_with_query_in_session
1121 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1121 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1122 @request.session['issues_index_sort'] = 'id'
1122 @request.session['issues_index_sort'] = 'id'
1123
1123
1124 with_settings :display_subprojects_issues => '0' do
1124 with_settings :display_subprojects_issues => '0' do
1125 get :show, :id => 3
1125 get :show, :id => 3
1126 end
1126 end
1127
1127
1128 assert_response :success
1128 assert_response :success
1129 # Previous and next issues for all projects
1129 # Previous and next issues for all projects
1130 assert_equal 2, assigns(:prev_issue_id)
1130 assert_equal 2, assigns(:prev_issue_id)
1131 assert_equal 5, assigns(:next_issue_id)
1131 assert_equal 5, assigns(:next_issue_id)
1132
1132
1133 count = Issue.open.visible.count
1133 count = Issue.open.visible.count
1134
1134
1135 assert_select 'div.next-prev-links' do
1135 assert_select 'div.next-prev-links' do
1136 assert_select 'a[href=/issues/2]', :text => /Previous/
1136 assert_select 'a[href=/issues/2]', :text => /Previous/
1137 assert_select 'a[href=/issues/5]', :text => /Next/
1137 assert_select 'a[href=/issues/5]', :text => /Next/
1138 assert_select 'span.position', :text => "3 of #{count}"
1138 assert_select 'span.position', :text => "3 of #{count}"
1139 end
1139 end
1140 end
1140 end
1141
1141
1142 def test_show_should_display_prev_next_links_with_saved_query_in_session
1142 def test_show_should_display_prev_next_links_with_saved_query_in_session
1143 query = Query.create!(:name => 'test', :is_public => true, :user_id => 1,
1143 query = Query.create!(:name => 'test', :is_public => true, :user_id => 1,
1144 :filters => {'status_id' => {:values => ['5'], :operator => '='}},
1144 :filters => {'status_id' => {:values => ['5'], :operator => '='}},
1145 :sort_criteria => [['id', 'asc']])
1145 :sort_criteria => [['id', 'asc']])
1146 @request.session[:query] = {:id => query.id, :project_id => nil}
1146 @request.session[:query] = {:id => query.id, :project_id => nil}
1147
1147
1148 get :show, :id => 11
1148 get :show, :id => 11
1149
1149
1150 assert_response :success
1150 assert_response :success
1151 assert_equal query, assigns(:query)
1151 assert_equal query, assigns(:query)
1152 # Previous and next issues for all projects
1152 # Previous and next issues for all projects
1153 assert_equal 8, assigns(:prev_issue_id)
1153 assert_equal 8, assigns(:prev_issue_id)
1154 assert_equal 12, assigns(:next_issue_id)
1154 assert_equal 12, assigns(:next_issue_id)
1155
1155
1156 assert_select 'div.next-prev-links' do
1156 assert_select 'div.next-prev-links' do
1157 assert_select 'a[href=/issues/8]', :text => /Previous/
1157 assert_select 'a[href=/issues/8]', :text => /Previous/
1158 assert_select 'a[href=/issues/12]', :text => /Next/
1158 assert_select 'a[href=/issues/12]', :text => /Next/
1159 end
1159 end
1160 end
1160 end
1161
1161
1162 def test_show_should_display_prev_next_links_with_query_and_sort_on_association
1162 def test_show_should_display_prev_next_links_with_query_and_sort_on_association
1163 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1163 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1164
1164
1165 %w(project tracker status priority author assigned_to category fixed_version).each do |assoc_sort|
1165 %w(project tracker status priority author assigned_to category fixed_version).each do |assoc_sort|
1166 @request.session['issues_index_sort'] = assoc_sort
1166 @request.session['issues_index_sort'] = assoc_sort
1167
1167
1168 get :show, :id => 3
1168 get :show, :id => 3
1169 assert_response :success, "Wrong response status for #{assoc_sort} sort"
1169 assert_response :success, "Wrong response status for #{assoc_sort} sort"
1170
1170
1171 assert_select 'div.next-prev-links' do
1171 assert_select 'div.next-prev-links' do
1172 assert_select 'a', :text => /(Previous|Next)/
1172 assert_select 'a', :text => /(Previous|Next)/
1173 end
1173 end
1174 end
1174 end
1175 end
1175 end
1176
1176
1177 def test_show_should_display_prev_next_links_with_project_query_in_session
1177 def test_show_should_display_prev_next_links_with_project_query_in_session
1178 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1178 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1179 @request.session['issues_index_sort'] = 'id'
1179 @request.session['issues_index_sort'] = 'id'
1180
1180
1181 with_settings :display_subprojects_issues => '0' do
1181 with_settings :display_subprojects_issues => '0' do
1182 get :show, :id => 3
1182 get :show, :id => 3
1183 end
1183 end
1184
1184
1185 assert_response :success
1185 assert_response :success
1186 # Previous and next issues inside project
1186 # Previous and next issues inside project
1187 assert_equal 2, assigns(:prev_issue_id)
1187 assert_equal 2, assigns(:prev_issue_id)
1188 assert_equal 7, assigns(:next_issue_id)
1188 assert_equal 7, assigns(:next_issue_id)
1189
1189
1190 assert_select 'div.next-prev-links' do
1190 assert_select 'div.next-prev-links' do
1191 assert_select 'a[href=/issues/2]', :text => /Previous/
1191 assert_select 'a[href=/issues/2]', :text => /Previous/
1192 assert_select 'a[href=/issues/7]', :text => /Next/
1192 assert_select 'a[href=/issues/7]', :text => /Next/
1193 end
1193 end
1194 end
1194 end
1195
1195
1196 def test_show_should_not_display_prev_link_for_first_issue
1196 def test_show_should_not_display_prev_link_for_first_issue
1197 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1197 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1198 @request.session['issues_index_sort'] = 'id'
1198 @request.session['issues_index_sort'] = 'id'
1199
1199
1200 with_settings :display_subprojects_issues => '0' do
1200 with_settings :display_subprojects_issues => '0' do
1201 get :show, :id => 1
1201 get :show, :id => 1
1202 end
1202 end
1203
1203
1204 assert_response :success
1204 assert_response :success
1205 assert_nil assigns(:prev_issue_id)
1205 assert_nil assigns(:prev_issue_id)
1206 assert_equal 2, assigns(:next_issue_id)
1206 assert_equal 2, assigns(:next_issue_id)
1207
1207
1208 assert_select 'div.next-prev-links' do
1208 assert_select 'div.next-prev-links' do
1209 assert_select 'a', :text => /Previous/, :count => 0
1209 assert_select 'a', :text => /Previous/, :count => 0
1210 assert_select 'a[href=/issues/2]', :text => /Next/
1210 assert_select 'a[href=/issues/2]', :text => /Next/
1211 end
1211 end
1212 end
1212 end
1213
1213
1214 def test_show_should_not_display_prev_next_links_for_issue_not_in_query_results
1214 def test_show_should_not_display_prev_next_links_for_issue_not_in_query_results
1215 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'c'}}, :project_id => 1}
1215 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'c'}}, :project_id => 1}
1216 @request.session['issues_index_sort'] = 'id'
1216 @request.session['issues_index_sort'] = 'id'
1217
1217
1218 get :show, :id => 1
1218 get :show, :id => 1
1219
1219
1220 assert_response :success
1220 assert_response :success
1221 assert_nil assigns(:prev_issue_id)
1221 assert_nil assigns(:prev_issue_id)
1222 assert_nil assigns(:next_issue_id)
1222 assert_nil assigns(:next_issue_id)
1223
1223
1224 assert_select 'a', :text => /Previous/, :count => 0
1224 assert_select 'a', :text => /Previous/, :count => 0
1225 assert_select 'a', :text => /Next/, :count => 0
1225 assert_select 'a', :text => /Next/, :count => 0
1226 end
1226 end
1227
1227
1228 def test_show_show_should_display_prev_next_links_with_query_sort_by_user_custom_field
1228 def test_show_show_should_display_prev_next_links_with_query_sort_by_user_custom_field
1229 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
1229 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
1230 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
1230 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
1231 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
1231 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
1232 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
1232 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
1233 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
1233 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
1234
1234
1235 query = Query.create!(:name => 'test', :is_public => true, :user_id => 1, :filters => {},
1235 query = Query.create!(:name => 'test', :is_public => true, :user_id => 1, :filters => {},
1236 :sort_criteria => [["cf_#{cf.id}", 'asc'], ['id', 'asc']])
1236 :sort_criteria => [["cf_#{cf.id}", 'asc'], ['id', 'asc']])
1237 @request.session[:query] = {:id => query.id, :project_id => nil}
1237 @request.session[:query] = {:id => query.id, :project_id => nil}
1238
1238
1239 get :show, :id => 3
1239 get :show, :id => 3
1240 assert_response :success
1240 assert_response :success
1241
1241
1242 assert_equal 2, assigns(:prev_issue_id)
1242 assert_equal 2, assigns(:prev_issue_id)
1243 assert_equal 1, assigns(:next_issue_id)
1243 assert_equal 1, assigns(:next_issue_id)
1244
1244
1245 assert_select 'div.next-prev-links' do
1245 assert_select 'div.next-prev-links' do
1246 assert_select 'a[href=/issues/2]', :text => /Previous/
1246 assert_select 'a[href=/issues/2]', :text => /Previous/
1247 assert_select 'a[href=/issues/1]', :text => /Next/
1247 assert_select 'a[href=/issues/1]', :text => /Next/
1248 end
1248 end
1249 end
1249 end
1250
1250
1251 def test_show_should_display_link_to_the_assignee
1251 def test_show_should_display_link_to_the_assignee
1252 get :show, :id => 2
1252 get :show, :id => 2
1253 assert_response :success
1253 assert_response :success
1254 assert_select '.assigned-to' do
1254 assert_select '.assigned-to' do
1255 assert_select 'a[href=/users/3]'
1255 assert_select 'a[href=/users/3]'
1256 end
1256 end
1257 end
1257 end
1258
1258
1259 def test_show_should_display_visible_changesets_from_other_projects
1259 def test_show_should_display_visible_changesets_from_other_projects
1260 project = Project.find(2)
1260 project = Project.find(2)
1261 issue = project.issues.first
1261 issue = project.issues.first
1262 issue.changeset_ids = [102]
1262 issue.changeset_ids = [102]
1263 issue.save!
1263 issue.save!
1264 # changesets from other projects should be displayed even if repository
1264 # changesets from other projects should be displayed even if repository
1265 # is disabled on issue's project
1265 # is disabled on issue's project
1266 project.disable_module! :repository
1266 project.disable_module! :repository
1267
1267
1268 @request.session[:user_id] = 2
1268 @request.session[:user_id] = 2
1269 get :show, :id => issue.id
1269 get :show, :id => issue.id
1270
1270
1271 assert_select 'a[href=?]', '/projects/ecookbook/repository/revisions/3'
1271 assert_select 'a[href=?]', '/projects/ecookbook/repository/revisions/3'
1272 end
1272 end
1273
1273
1274 def test_show_should_display_watchers
1274 def test_show_should_display_watchers
1275 @request.session[:user_id] = 2
1275 @request.session[:user_id] = 2
1276 Issue.find(1).add_watcher User.find(2)
1276 Issue.find(1).add_watcher User.find(2)
1277
1277
1278 get :show, :id => 1
1278 get :show, :id => 1
1279 assert_select 'div#watchers ul' do
1279 assert_select 'div#watchers ul' do
1280 assert_select 'li' do
1280 assert_select 'li' do
1281 assert_select 'a[href=/users/2]'
1281 assert_select 'a[href=/users/2]'
1282 assert_select 'a img[alt=Delete]'
1282 assert_select 'a img[alt=Delete]'
1283 end
1283 end
1284 end
1284 end
1285 end
1285 end
1286
1286
1287 def test_show_should_display_watchers_with_gravatars
1287 def test_show_should_display_watchers_with_gravatars
1288 @request.session[:user_id] = 2
1288 @request.session[:user_id] = 2
1289 Issue.find(1).add_watcher User.find(2)
1289 Issue.find(1).add_watcher User.find(2)
1290
1290
1291 with_settings :gravatar_enabled => '1' do
1291 with_settings :gravatar_enabled => '1' do
1292 get :show, :id => 1
1292 get :show, :id => 1
1293 end
1293 end
1294
1294
1295 assert_select 'div#watchers ul' do
1295 assert_select 'div#watchers ul' do
1296 assert_select 'li' do
1296 assert_select 'li' do
1297 assert_select 'img.gravatar'
1297 assert_select 'img.gravatar'
1298 assert_select 'a[href=/users/2]'
1298 assert_select 'a[href=/users/2]'
1299 assert_select 'a img[alt=Delete]'
1299 assert_select 'a img[alt=Delete]'
1300 end
1300 end
1301 end
1301 end
1302 end
1302 end
1303
1303
1304 def test_show_with_thumbnails_enabled_should_display_thumbnails
1304 def test_show_with_thumbnails_enabled_should_display_thumbnails
1305 @request.session[:user_id] = 2
1305 @request.session[:user_id] = 2
1306
1306
1307 with_settings :thumbnails_enabled => '1' do
1307 with_settings :thumbnails_enabled => '1' do
1308 get :show, :id => 14
1308 get :show, :id => 14
1309 assert_response :success
1309 assert_response :success
1310 end
1310 end
1311
1311
1312 assert_select 'div.thumbnails' do
1312 assert_select 'div.thumbnails' do
1313 assert_select 'a[href=/attachments/16/testfile.png]' do
1313 assert_select 'a[href=/attachments/16/testfile.png]' do
1314 assert_select 'img[src=/attachments/thumbnail/16]'
1314 assert_select 'img[src=/attachments/thumbnail/16]'
1315 end
1315 end
1316 end
1316 end
1317 end
1317 end
1318
1318
1319 def test_show_with_thumbnails_disabled_should_not_display_thumbnails
1319 def test_show_with_thumbnails_disabled_should_not_display_thumbnails
1320 @request.session[:user_id] = 2
1320 @request.session[:user_id] = 2
1321
1321
1322 with_settings :thumbnails_enabled => '0' do
1322 with_settings :thumbnails_enabled => '0' do
1323 get :show, :id => 14
1323 get :show, :id => 14
1324 assert_response :success
1324 assert_response :success
1325 end
1325 end
1326
1326
1327 assert_select 'div.thumbnails', 0
1327 assert_select 'div.thumbnails', 0
1328 end
1328 end
1329
1329
1330 def test_show_with_multi_custom_field
1330 def test_show_with_multi_custom_field
1331 field = CustomField.find(1)
1331 field = CustomField.find(1)
1332 field.update_attribute :multiple, true
1332 field.update_attribute :multiple, true
1333 issue = Issue.find(1)
1333 issue = Issue.find(1)
1334 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
1334 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
1335 issue.save!
1335 issue.save!
1336
1336
1337 get :show, :id => 1
1337 get :show, :id => 1
1338 assert_response :success
1338 assert_response :success
1339
1339
1340 assert_select 'td', :text => 'MySQL, Oracle'
1340 assert_select 'td', :text => 'MySQL, Oracle'
1341 end
1341 end
1342
1342
1343 def test_show_with_multi_user_custom_field
1343 def test_show_with_multi_user_custom_field
1344 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1344 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1345 :tracker_ids => [1], :is_for_all => true)
1345 :tracker_ids => [1], :is_for_all => true)
1346 issue = Issue.find(1)
1346 issue = Issue.find(1)
1347 issue.custom_field_values = {field.id => ['2', '3']}
1347 issue.custom_field_values = {field.id => ['2', '3']}
1348 issue.save!
1348 issue.save!
1349
1349
1350 get :show, :id => 1
1350 get :show, :id => 1
1351 assert_response :success
1351 assert_response :success
1352
1352
1353 # TODO: should display links
1353 # TODO: should display links
1354 assert_select 'td', :text => 'Dave Lopper, John Smith'
1354 assert_select 'td', :text => 'Dave Lopper, John Smith'
1355 end
1355 end
1356
1356
1357 def test_show_should_display_private_notes_with_permission_only
1357 def test_show_should_display_private_notes_with_permission_only
1358 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
1358 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
1359 @request.session[:user_id] = 2
1359 @request.session[:user_id] = 2
1360
1360
1361 get :show, :id => 2
1361 get :show, :id => 2
1362 assert_response :success
1362 assert_response :success
1363 assert_include journal, assigns(:journals)
1363 assert_include journal, assigns(:journals)
1364
1364
1365 Role.find(1).remove_permission! :view_private_notes
1365 Role.find(1).remove_permission! :view_private_notes
1366 get :show, :id => 2
1366 get :show, :id => 2
1367 assert_response :success
1367 assert_response :success
1368 assert_not_include journal, assigns(:journals)
1368 assert_not_include journal, assigns(:journals)
1369 end
1369 end
1370
1370
1371 def test_show_atom
1371 def test_show_atom
1372 get :show, :id => 2, :format => 'atom'
1372 get :show, :id => 2, :format => 'atom'
1373 assert_response :success
1373 assert_response :success
1374 assert_template 'journals/index'
1374 assert_template 'journals/index'
1375 # Inline image
1375 # Inline image
1376 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
1376 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
1377 end
1377 end
1378
1378
1379 def test_show_export_to_pdf
1379 def test_show_export_to_pdf
1380 get :show, :id => 3, :format => 'pdf'
1380 get :show, :id => 3, :format => 'pdf'
1381 assert_response :success
1381 assert_response :success
1382 assert_equal 'application/pdf', @response.content_type
1382 assert_equal 'application/pdf', @response.content_type
1383 assert @response.body.starts_with?('%PDF')
1383 assert @response.body.starts_with?('%PDF')
1384 assert_not_nil assigns(:issue)
1384 assert_not_nil assigns(:issue)
1385 end
1385 end
1386
1386
1387 def test_show_export_to_pdf_with_ancestors
1387 def test_show_export_to_pdf_with_ancestors
1388 issue = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1388 issue = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1389
1389
1390 get :show, :id => issue.id, :format => 'pdf'
1390 get :show, :id => issue.id, :format => 'pdf'
1391 assert_response :success
1391 assert_response :success
1392 assert_equal 'application/pdf', @response.content_type
1392 assert_equal 'application/pdf', @response.content_type
1393 assert @response.body.starts_with?('%PDF')
1393 assert @response.body.starts_with?('%PDF')
1394 end
1394 end
1395
1395
1396 def test_show_export_to_pdf_with_descendants
1396 def test_show_export_to_pdf_with_descendants
1397 c1 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1397 c1 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1398 c2 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1398 c2 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1399 c3 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => c1.id)
1399 c3 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => c1.id)
1400
1400
1401 get :show, :id => 1, :format => 'pdf'
1401 get :show, :id => 1, :format => 'pdf'
1402 assert_response :success
1402 assert_response :success
1403 assert_equal 'application/pdf', @response.content_type
1403 assert_equal 'application/pdf', @response.content_type
1404 assert @response.body.starts_with?('%PDF')
1404 assert @response.body.starts_with?('%PDF')
1405 end
1405 end
1406
1406
1407 def test_show_export_to_pdf_with_journals
1407 def test_show_export_to_pdf_with_journals
1408 get :show, :id => 1, :format => 'pdf'
1408 get :show, :id => 1, :format => 'pdf'
1409 assert_response :success
1409 assert_response :success
1410 assert_equal 'application/pdf', @response.content_type
1410 assert_equal 'application/pdf', @response.content_type
1411 assert @response.body.starts_with?('%PDF')
1411 assert @response.body.starts_with?('%PDF')
1412 end
1412 end
1413
1413
1414 def test_show_export_to_pdf_with_changesets
1414 def test_show_export_to_pdf_with_changesets
1415 Issue.find(3).changesets = Changeset.find_all_by_id(100, 101, 102)
1415 Issue.find(3).changesets = Changeset.find_all_by_id(100, 101, 102)
1416
1416
1417 get :show, :id => 3, :format => 'pdf'
1417 get :show, :id => 3, :format => 'pdf'
1418 assert_response :success
1418 assert_response :success
1419 assert_equal 'application/pdf', @response.content_type
1419 assert_equal 'application/pdf', @response.content_type
1420 assert @response.body.starts_with?('%PDF')
1420 assert @response.body.starts_with?('%PDF')
1421 end
1421 end
1422
1422
1423 def test_get_new
1423 def test_get_new
1424 @request.session[:user_id] = 2
1424 @request.session[:user_id] = 2
1425 get :new, :project_id => 1, :tracker_id => 1
1425 get :new, :project_id => 1, :tracker_id => 1
1426 assert_response :success
1426 assert_response :success
1427 assert_template 'new'
1427 assert_template 'new'
1428
1428
1429 assert_tag 'input', :attributes => {:name => 'issue[is_private]'}
1429 assert_tag 'input', :attributes => {:name => 'issue[is_private]'}
1430 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
1430 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
1431 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
1431 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
1432 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
1432 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
1433 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
1433 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
1434 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
1434 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
1435 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
1435 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
1436 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
1436 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
1437 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
1437 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
1438 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
1438 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
1439 assert_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
1439 assert_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
1440 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
1440 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
1441 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
1441 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
1442 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
1442 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
1443 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]', :value => 'Default string' }
1443 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]', :value => 'Default string' }
1444 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
1444 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
1445
1445
1446 # Be sure we don't display inactive IssuePriorities
1446 # Be sure we don't display inactive IssuePriorities
1447 assert ! IssuePriority.find(15).active?
1447 assert ! IssuePriority.find(15).active?
1448 assert_no_tag :option, :attributes => {:value => '15'},
1448 assert_no_tag :option, :attributes => {:value => '15'},
1449 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
1449 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
1450 end
1450 end
1451
1451
1452 def test_get_new_with_minimal_permissions
1452 def test_get_new_with_minimal_permissions
1453 Role.find(1).update_attribute :permissions, [:add_issues]
1453 Role.find(1).update_attribute :permissions, [:add_issues]
1454 WorkflowTransition.delete_all :role_id => 1
1454 WorkflowTransition.delete_all :role_id => 1
1455
1455
1456 @request.session[:user_id] = 2
1456 @request.session[:user_id] = 2
1457 get :new, :project_id => 1, :tracker_id => 1
1457 get :new, :project_id => 1, :tracker_id => 1
1458 assert_response :success
1458 assert_response :success
1459 assert_template 'new'
1459 assert_template 'new'
1460
1460
1461 assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
1461 assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
1462 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
1462 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
1463 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
1463 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
1464 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
1464 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
1465 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
1465 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
1466 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
1466 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
1467 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
1467 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
1468 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
1468 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
1469 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
1469 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
1470 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
1470 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
1471 assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
1471 assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
1472 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
1472 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
1473 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
1473 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
1474 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
1474 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
1475 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]', :value => 'Default string' }
1475 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]', :value => 'Default string' }
1476 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
1476 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
1477 end
1477 end
1478
1478
1479 def test_get_new_with_list_custom_field
1479 def test_get_new_with_list_custom_field
1480 @request.session[:user_id] = 2
1480 @request.session[:user_id] = 2
1481 get :new, :project_id => 1, :tracker_id => 1
1481 get :new, :project_id => 1, :tracker_id => 1
1482 assert_response :success
1482 assert_response :success
1483 assert_template 'new'
1483 assert_template 'new'
1484
1484
1485 assert_select 'select.list_cf[name=?]', 'issue[custom_field_values][1]' do
1485 assert_select 'select.list_cf[name=?]', 'issue[custom_field_values][1]' do
1486 assert_select 'option', 4
1486 assert_select 'option', 4
1487 assert_select 'option[value=MySQL]', :text => 'MySQL'
1487 assert_select 'option[value=MySQL]', :text => 'MySQL'
1488 end
1488 end
1489 end
1489 end
1490
1490
1491 def test_get_new_with_multi_custom_field
1491 def test_get_new_with_multi_custom_field
1492 field = IssueCustomField.find(1)
1492 field = IssueCustomField.find(1)
1493 field.update_attribute :multiple, true
1493 field.update_attribute :multiple, true
1494
1494
1495 @request.session[:user_id] = 2
1495 @request.session[:user_id] = 2
1496 get :new, :project_id => 1, :tracker_id => 1
1496 get :new, :project_id => 1, :tracker_id => 1
1497 assert_response :success
1497 assert_response :success
1498 assert_template 'new'
1498 assert_template 'new'
1499
1499
1500 assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
1500 assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
1501 assert_select 'option', 3
1501 assert_select 'option', 3
1502 assert_select 'option[value=MySQL]', :text => 'MySQL'
1502 assert_select 'option[value=MySQL]', :text => 'MySQL'
1503 end
1503 end
1504 assert_select 'input[name=?][type=hidden][value=?]', 'issue[custom_field_values][1][]', ''
1504 assert_select 'input[name=?][type=hidden][value=?]', 'issue[custom_field_values][1][]', ''
1505 end
1505 end
1506
1506
1507 def test_get_new_with_multi_user_custom_field
1507 def test_get_new_with_multi_user_custom_field
1508 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1508 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1509 :tracker_ids => [1], :is_for_all => true)
1509 :tracker_ids => [1], :is_for_all => true)
1510
1510
1511 @request.session[:user_id] = 2
1511 @request.session[:user_id] = 2
1512 get :new, :project_id => 1, :tracker_id => 1
1512 get :new, :project_id => 1, :tracker_id => 1
1513 assert_response :success
1513 assert_response :success
1514 assert_template 'new'
1514 assert_template 'new'
1515
1515
1516 assert_select 'select[name=?][multiple=multiple]', "issue[custom_field_values][#{field.id}][]" do
1516 assert_select 'select[name=?][multiple=multiple]', "issue[custom_field_values][#{field.id}][]" do
1517 assert_select 'option', Project.find(1).users.count
1517 assert_select 'option', Project.find(1).users.count
1518 assert_select 'option[value=2]', :text => 'John Smith'
1518 assert_select 'option[value=2]', :text => 'John Smith'
1519 end
1519 end
1520 assert_select 'input[name=?][type=hidden][value=?]', "issue[custom_field_values][#{field.id}][]", ''
1520 assert_select 'input[name=?][type=hidden][value=?]', "issue[custom_field_values][#{field.id}][]", ''
1521 end
1521 end
1522
1522
1523 def test_get_new_with_date_custom_field
1523 def test_get_new_with_date_custom_field
1524 field = IssueCustomField.create!(:name => 'Date', :field_format => 'date', :tracker_ids => [1], :is_for_all => true)
1524 field = IssueCustomField.create!(:name => 'Date', :field_format => 'date', :tracker_ids => [1], :is_for_all => true)
1525
1525
1526 @request.session[:user_id] = 2
1526 @request.session[:user_id] = 2
1527 get :new, :project_id => 1, :tracker_id => 1
1527 get :new, :project_id => 1, :tracker_id => 1
1528 assert_response :success
1528 assert_response :success
1529
1529
1530 assert_select 'input[name=?]', "issue[custom_field_values][#{field.id}]"
1530 assert_select 'input[name=?]', "issue[custom_field_values][#{field.id}]"
1531 end
1531 end
1532
1532
1533 def test_get_new_with_text_custom_field
1533 def test_get_new_with_text_custom_field
1534 field = IssueCustomField.create!(:name => 'Text', :field_format => 'text', :tracker_ids => [1], :is_for_all => true)
1534 field = IssueCustomField.create!(:name => 'Text', :field_format => 'text', :tracker_ids => [1], :is_for_all => true)
1535
1535
1536 @request.session[:user_id] = 2
1536 @request.session[:user_id] = 2
1537 get :new, :project_id => 1, :tracker_id => 1
1537 get :new, :project_id => 1, :tracker_id => 1
1538 assert_response :success
1538 assert_response :success
1539
1539
1540 assert_select 'textarea[name=?]', "issue[custom_field_values][#{field.id}]"
1540 assert_select 'textarea[name=?]', "issue[custom_field_values][#{field.id}]"
1541 end
1541 end
1542
1542
1543 def test_get_new_without_default_start_date_is_creation_date
1543 def test_get_new_without_default_start_date_is_creation_date
1544 Setting.default_issue_start_date_to_creation_date = 0
1544 Setting.default_issue_start_date_to_creation_date = 0
1545
1545
1546 @request.session[:user_id] = 2
1546 @request.session[:user_id] = 2
1547 get :new, :project_id => 1, :tracker_id => 1
1547 get :new, :project_id => 1, :tracker_id => 1
1548 assert_response :success
1548 assert_response :success
1549 assert_template 'new'
1549 assert_template 'new'
1550
1550
1551 assert_select 'input[name=?]', 'issue[start_date]'
1551 assert_select 'input[name=?]', 'issue[start_date]'
1552 assert_select 'input[name=?][value]', 'issue[start_date]', 0
1552 assert_select 'input[name=?][value]', 'issue[start_date]', 0
1553 end
1553 end
1554
1554
1555 def test_get_new_with_default_start_date_is_creation_date
1555 def test_get_new_with_default_start_date_is_creation_date
1556 Setting.default_issue_start_date_to_creation_date = 1
1556 Setting.default_issue_start_date_to_creation_date = 1
1557
1557
1558 @request.session[:user_id] = 2
1558 @request.session[:user_id] = 2
1559 get :new, :project_id => 1, :tracker_id => 1
1559 get :new, :project_id => 1, :tracker_id => 1
1560 assert_response :success
1560 assert_response :success
1561 assert_template 'new'
1561 assert_template 'new'
1562
1562
1563 assert_select 'input[name=?][value=?]', 'issue[start_date]', Date.today.to_s
1563 assert_select 'input[name=?][value=?]', 'issue[start_date]', Date.today.to_s
1564 end
1564 end
1565
1565
1566 def test_get_new_form_should_allow_attachment_upload
1566 def test_get_new_form_should_allow_attachment_upload
1567 @request.session[:user_id] = 2
1567 @request.session[:user_id] = 2
1568 get :new, :project_id => 1, :tracker_id => 1
1568 get :new, :project_id => 1, :tracker_id => 1
1569
1569
1570 assert_select 'form[id=issue-form][method=post][enctype=multipart/form-data]' do
1570 assert_select 'form[id=issue-form][method=post][enctype=multipart/form-data]' do
1571 assert_select 'input[name=?][type=file]', 'attachments[1][file]'
1571 assert_select 'input[name=?][type=file]', 'attachments[1][file]'
1572 assert_select 'input[name=?][maxlength=255]', 'attachments[1][description]'
1572 assert_select 'input[name=?][maxlength=255]', 'attachments[1][description]'
1573 end
1573 end
1574 end
1574 end
1575
1575
1576 def test_get_new_should_prefill_the_form_from_params
1576 def test_get_new_should_prefill_the_form_from_params
1577 @request.session[:user_id] = 2
1577 @request.session[:user_id] = 2
1578 get :new, :project_id => 1,
1578 get :new, :project_id => 1,
1579 :issue => {:tracker_id => 3, :description => 'Prefilled', :custom_field_values => {'2' => 'Custom field value'}}
1579 :issue => {:tracker_id => 3, :description => 'Prefilled', :custom_field_values => {'2' => 'Custom field value'}}
1580
1580
1581 issue = assigns(:issue)
1581 issue = assigns(:issue)
1582 assert_equal 3, issue.tracker_id
1582 assert_equal 3, issue.tracker_id
1583 assert_equal 'Prefilled', issue.description
1583 assert_equal 'Prefilled', issue.description
1584 assert_equal 'Custom field value', issue.custom_field_value(2)
1584 assert_equal 'Custom field value', issue.custom_field_value(2)
1585
1585
1586 assert_select 'select[name=?]', 'issue[tracker_id]' do
1586 assert_select 'select[name=?]', 'issue[tracker_id]' do
1587 assert_select 'option[value=3][selected=selected]'
1587 assert_select 'option[value=3][selected=selected]'
1588 end
1588 end
1589 assert_select 'textarea[name=?]', 'issue[description]', :text => /Prefilled/
1589 assert_select 'textarea[name=?]', 'issue[description]', :text => /Prefilled/
1590 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Custom field value'
1590 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Custom field value'
1591 end
1591 end
1592
1592
1593 def test_get_new_should_mark_required_fields
1593 def test_get_new_should_mark_required_fields
1594 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1594 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1595 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1595 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1596 WorkflowPermission.delete_all
1596 WorkflowPermission.delete_all
1597 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
1597 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
1598 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
1598 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
1599 @request.session[:user_id] = 2
1599 @request.session[:user_id] = 2
1600
1600
1601 get :new, :project_id => 1
1601 get :new, :project_id => 1
1602 assert_response :success
1602 assert_response :success
1603 assert_template 'new'
1603 assert_template 'new'
1604
1604
1605 assert_select 'label[for=issue_start_date]' do
1605 assert_select 'label[for=issue_start_date]' do
1606 assert_select 'span[class=required]', 0
1606 assert_select 'span[class=required]', 0
1607 end
1607 end
1608 assert_select 'label[for=issue_due_date]' do
1608 assert_select 'label[for=issue_due_date]' do
1609 assert_select 'span[class=required]'
1609 assert_select 'span[class=required]'
1610 end
1610 end
1611 assert_select 'label[for=?]', "issue_custom_field_values_#{cf1.id}" do
1611 assert_select 'label[for=?]', "issue_custom_field_values_#{cf1.id}" do
1612 assert_select 'span[class=required]', 0
1612 assert_select 'span[class=required]', 0
1613 end
1613 end
1614 assert_select 'label[for=?]', "issue_custom_field_values_#{cf2.id}" do
1614 assert_select 'label[for=?]', "issue_custom_field_values_#{cf2.id}" do
1615 assert_select 'span[class=required]'
1615 assert_select 'span[class=required]'
1616 end
1616 end
1617 end
1617 end
1618
1618
1619 def test_get_new_should_not_display_readonly_fields
1619 def test_get_new_should_not_display_readonly_fields
1620 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1620 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1621 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1621 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1622 WorkflowPermission.delete_all
1622 WorkflowPermission.delete_all
1623 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
1623 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
1624 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
1624 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
1625 @request.session[:user_id] = 2
1625 @request.session[:user_id] = 2
1626
1626
1627 get :new, :project_id => 1
1627 get :new, :project_id => 1
1628 assert_response :success
1628 assert_response :success
1629 assert_template 'new'
1629 assert_template 'new'
1630
1630
1631 assert_select 'input[name=?]', 'issue[start_date]'
1631 assert_select 'input[name=?]', 'issue[start_date]'
1632 assert_select 'input[name=?]', 'issue[due_date]', 0
1632 assert_select 'input[name=?]', 'issue[due_date]', 0
1633 assert_select 'input[name=?]', "issue[custom_field_values][#{cf1.id}]"
1633 assert_select 'input[name=?]', "issue[custom_field_values][#{cf1.id}]"
1634 assert_select 'input[name=?]', "issue[custom_field_values][#{cf2.id}]", 0
1634 assert_select 'input[name=?]', "issue[custom_field_values][#{cf2.id}]", 0
1635 end
1635 end
1636
1636
1637 def test_get_new_without_tracker_id
1637 def test_get_new_without_tracker_id
1638 @request.session[:user_id] = 2
1638 @request.session[:user_id] = 2
1639 get :new, :project_id => 1
1639 get :new, :project_id => 1
1640 assert_response :success
1640 assert_response :success
1641 assert_template 'new'
1641 assert_template 'new'
1642
1642
1643 issue = assigns(:issue)
1643 issue = assigns(:issue)
1644 assert_not_nil issue
1644 assert_not_nil issue
1645 assert_equal Project.find(1).trackers.first, issue.tracker
1645 assert_equal Project.find(1).trackers.first, issue.tracker
1646 end
1646 end
1647
1647
1648 def test_get_new_with_no_default_status_should_display_an_error
1648 def test_get_new_with_no_default_status_should_display_an_error
1649 @request.session[:user_id] = 2
1649 @request.session[:user_id] = 2
1650 IssueStatus.delete_all
1650 IssueStatus.delete_all
1651
1651
1652 get :new, :project_id => 1
1652 get :new, :project_id => 1
1653 assert_response 500
1653 assert_response 500
1654 assert_error_tag :content => /No default issue/
1654 assert_error_tag :content => /No default issue/
1655 end
1655 end
1656
1656
1657 def test_get_new_with_no_tracker_should_display_an_error
1657 def test_get_new_with_no_tracker_should_display_an_error
1658 @request.session[:user_id] = 2
1658 @request.session[:user_id] = 2
1659 Tracker.delete_all
1659 Tracker.delete_all
1660
1660
1661 get :new, :project_id => 1
1661 get :new, :project_id => 1
1662 assert_response 500
1662 assert_response 500
1663 assert_error_tag :content => /No tracker/
1663 assert_error_tag :content => /No tracker/
1664 end
1664 end
1665
1665
1666 def test_update_new_form
1666 def test_update_new_form
1667 @request.session[:user_id] = 2
1667 @request.session[:user_id] = 2
1668 xhr :post, :new, :project_id => 1,
1668 xhr :post, :new, :project_id => 1,
1669 :issue => {:tracker_id => 2,
1669 :issue => {:tracker_id => 2,
1670 :subject => 'This is the test_new issue',
1670 :subject => 'This is the test_new issue',
1671 :description => 'This is the description',
1671 :description => 'This is the description',
1672 :priority_id => 5}
1672 :priority_id => 5}
1673 assert_response :success
1673 assert_response :success
1674 assert_template 'update_form'
1674 assert_template 'update_form'
1675 assert_template 'form'
1675 assert_template 'form'
1676 assert_equal 'text/javascript', response.content_type
1676 assert_equal 'text/javascript', response.content_type
1677
1677
1678 issue = assigns(:issue)
1678 issue = assigns(:issue)
1679 assert_kind_of Issue, issue
1679 assert_kind_of Issue, issue
1680 assert_equal 1, issue.project_id
1680 assert_equal 1, issue.project_id
1681 assert_equal 2, issue.tracker_id
1681 assert_equal 2, issue.tracker_id
1682 assert_equal 'This is the test_new issue', issue.subject
1682 assert_equal 'This is the test_new issue', issue.subject
1683 end
1683 end
1684
1684
1685 def test_update_new_form_should_propose_transitions_based_on_initial_status
1685 def test_update_new_form_should_propose_transitions_based_on_initial_status
1686 @request.session[:user_id] = 2
1686 @request.session[:user_id] = 2
1687 WorkflowTransition.delete_all
1687 WorkflowTransition.delete_all
1688 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2)
1688 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2)
1689 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5)
1689 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5)
1690 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
1690 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
1691
1691
1692 xhr :post, :new, :project_id => 1,
1692 xhr :post, :new, :project_id => 1,
1693 :issue => {:tracker_id => 1,
1693 :issue => {:tracker_id => 1,
1694 :status_id => 5,
1694 :status_id => 5,
1695 :subject => 'This is an issue'}
1695 :subject => 'This is an issue'}
1696
1696
1697 assert_equal 5, assigns(:issue).status_id
1697 assert_equal 5, assigns(:issue).status_id
1698 assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
1698 assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
1699 end
1699 end
1700
1700
1701 def test_post_create
1701 def test_post_create
1702 @request.session[:user_id] = 2
1702 @request.session[:user_id] = 2
1703 assert_difference 'Issue.count' do
1703 assert_difference 'Issue.count' do
1704 post :create, :project_id => 1,
1704 post :create, :project_id => 1,
1705 :issue => {:tracker_id => 3,
1705 :issue => {:tracker_id => 3,
1706 :status_id => 2,
1706 :status_id => 2,
1707 :subject => 'This is the test_new issue',
1707 :subject => 'This is the test_new issue',
1708 :description => 'This is the description',
1708 :description => 'This is the description',
1709 :priority_id => 5,
1709 :priority_id => 5,
1710 :start_date => '2010-11-07',
1710 :start_date => '2010-11-07',
1711 :estimated_hours => '',
1711 :estimated_hours => '',
1712 :custom_field_values => {'2' => 'Value for field 2'}}
1712 :custom_field_values => {'2' => 'Value for field 2'}}
1713 end
1713 end
1714 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1714 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1715
1715
1716 issue = Issue.find_by_subject('This is the test_new issue')
1716 issue = Issue.find_by_subject('This is the test_new issue')
1717 assert_not_nil issue
1717 assert_not_nil issue
1718 assert_equal 2, issue.author_id
1718 assert_equal 2, issue.author_id
1719 assert_equal 3, issue.tracker_id
1719 assert_equal 3, issue.tracker_id
1720 assert_equal 2, issue.status_id
1720 assert_equal 2, issue.status_id
1721 assert_equal Date.parse('2010-11-07'), issue.start_date
1721 assert_equal Date.parse('2010-11-07'), issue.start_date
1722 assert_nil issue.estimated_hours
1722 assert_nil issue.estimated_hours
1723 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
1723 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
1724 assert_not_nil v
1724 assert_not_nil v
1725 assert_equal 'Value for field 2', v.value
1725 assert_equal 'Value for field 2', v.value
1726 end
1726 end
1727
1727
1728 def test_post_new_with_group_assignment
1728 def test_post_new_with_group_assignment
1729 group = Group.find(11)
1729 group = Group.find(11)
1730 project = Project.find(1)
1730 project = Project.find(1)
1731 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
1731 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
1732
1732
1733 with_settings :issue_group_assignment => '1' do
1733 with_settings :issue_group_assignment => '1' do
1734 @request.session[:user_id] = 2
1734 @request.session[:user_id] = 2
1735 assert_difference 'Issue.count' do
1735 assert_difference 'Issue.count' do
1736 post :create, :project_id => project.id,
1736 post :create, :project_id => project.id,
1737 :issue => {:tracker_id => 3,
1737 :issue => {:tracker_id => 3,
1738 :status_id => 1,
1738 :status_id => 1,
1739 :subject => 'This is the test_new_with_group_assignment issue',
1739 :subject => 'This is the test_new_with_group_assignment issue',
1740 :assigned_to_id => group.id}
1740 :assigned_to_id => group.id}
1741 end
1741 end
1742 end
1742 end
1743 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1743 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1744
1744
1745 issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
1745 issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
1746 assert_not_nil issue
1746 assert_not_nil issue
1747 assert_equal group, issue.assigned_to
1747 assert_equal group, issue.assigned_to
1748 end
1748 end
1749
1749
1750 def test_post_create_without_start_date_and_default_start_date_is_not_creation_date
1750 def test_post_create_without_start_date_and_default_start_date_is_not_creation_date
1751 Setting.default_issue_start_date_to_creation_date = 0
1751 Setting.default_issue_start_date_to_creation_date = 0
1752
1752
1753 @request.session[:user_id] = 2
1753 @request.session[:user_id] = 2
1754 assert_difference 'Issue.count' do
1754 assert_difference 'Issue.count' do
1755 post :create, :project_id => 1,
1755 post :create, :project_id => 1,
1756 :issue => {:tracker_id => 3,
1756 :issue => {:tracker_id => 3,
1757 :status_id => 2,
1757 :status_id => 2,
1758 :subject => 'This is the test_new issue',
1758 :subject => 'This is the test_new issue',
1759 :description => 'This is the description',
1759 :description => 'This is the description',
1760 :priority_id => 5,
1760 :priority_id => 5,
1761 :estimated_hours => '',
1761 :estimated_hours => '',
1762 :custom_field_values => {'2' => 'Value for field 2'}}
1762 :custom_field_values => {'2' => 'Value for field 2'}}
1763 end
1763 end
1764 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1764 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1765
1765
1766 issue = Issue.find_by_subject('This is the test_new issue')
1766 issue = Issue.find_by_subject('This is the test_new issue')
1767 assert_not_nil issue
1767 assert_not_nil issue
1768 assert_nil issue.start_date
1768 assert_nil issue.start_date
1769 end
1769 end
1770
1770
1771 def test_post_create_without_start_date_and_default_start_date_is_creation_date
1771 def test_post_create_without_start_date_and_default_start_date_is_creation_date
1772 Setting.default_issue_start_date_to_creation_date = 1
1772 Setting.default_issue_start_date_to_creation_date = 1
1773
1773
1774 @request.session[:user_id] = 2
1774 @request.session[:user_id] = 2
1775 assert_difference 'Issue.count' do
1775 assert_difference 'Issue.count' do
1776 post :create, :project_id => 1,
1776 post :create, :project_id => 1,
1777 :issue => {:tracker_id => 3,
1777 :issue => {:tracker_id => 3,
1778 :status_id => 2,
1778 :status_id => 2,
1779 :subject => 'This is the test_new issue',
1779 :subject => 'This is the test_new issue',
1780 :description => 'This is the description',
1780 :description => 'This is the description',
1781 :priority_id => 5,
1781 :priority_id => 5,
1782 :estimated_hours => '',
1782 :estimated_hours => '',
1783 :custom_field_values => {'2' => 'Value for field 2'}}
1783 :custom_field_values => {'2' => 'Value for field 2'}}
1784 end
1784 end
1785 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1785 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1786
1786
1787 issue = Issue.find_by_subject('This is the test_new issue')
1787 issue = Issue.find_by_subject('This is the test_new issue')
1788 assert_not_nil issue
1788 assert_not_nil issue
1789 assert_equal Date.today, issue.start_date
1789 assert_equal Date.today, issue.start_date
1790 end
1790 end
1791
1791
1792 def test_post_create_and_continue
1792 def test_post_create_and_continue
1793 @request.session[:user_id] = 2
1793 @request.session[:user_id] = 2
1794 assert_difference 'Issue.count' do
1794 assert_difference 'Issue.count' do
1795 post :create, :project_id => 1,
1795 post :create, :project_id => 1,
1796 :issue => {:tracker_id => 3, :subject => 'This is first issue', :priority_id => 5},
1796 :issue => {:tracker_id => 3, :subject => 'This is first issue', :priority_id => 5},
1797 :continue => ''
1797 :continue => ''
1798 end
1798 end
1799
1799
1800 issue = Issue.first(:order => 'id DESC')
1800 issue = Issue.first(:order => 'id DESC')
1801 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
1801 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
1802 assert_not_nil flash[:notice], "flash was not set"
1802 assert_not_nil flash[:notice], "flash was not set"
1803 assert_include %|<a href="/issues/#{issue.id}" title="This is first issue">##{issue.id}</a>|, flash[:notice], "issue link not found in the flash message"
1803 assert_include %|<a href="/issues/#{issue.id}" title="This is first issue">##{issue.id}</a>|, flash[:notice], "issue link not found in the flash message"
1804 end
1804 end
1805
1805
1806 def test_post_create_without_custom_fields_param
1806 def test_post_create_without_custom_fields_param
1807 @request.session[:user_id] = 2
1807 @request.session[:user_id] = 2
1808 assert_difference 'Issue.count' do
1808 assert_difference 'Issue.count' do
1809 post :create, :project_id => 1,
1809 post :create, :project_id => 1,
1810 :issue => {:tracker_id => 1,
1810 :issue => {:tracker_id => 1,
1811 :subject => 'This is the test_new issue',
1811 :subject => 'This is the test_new issue',
1812 :description => 'This is the description',
1812 :description => 'This is the description',
1813 :priority_id => 5}
1813 :priority_id => 5}
1814 end
1814 end
1815 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1815 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1816 end
1816 end
1817
1817
1818 def test_post_create_with_multi_custom_field
1818 def test_post_create_with_multi_custom_field
1819 field = IssueCustomField.find_by_name('Database')
1819 field = IssueCustomField.find_by_name('Database')
1820 field.update_attribute(:multiple, true)
1820 field.update_attribute(:multiple, true)
1821
1821
1822 @request.session[:user_id] = 2
1822 @request.session[:user_id] = 2
1823 assert_difference 'Issue.count' do
1823 assert_difference 'Issue.count' do
1824 post :create, :project_id => 1,
1824 post :create, :project_id => 1,
1825 :issue => {:tracker_id => 1,
1825 :issue => {:tracker_id => 1,
1826 :subject => 'This is the test_new issue',
1826 :subject => 'This is the test_new issue',
1827 :description => 'This is the description',
1827 :description => 'This is the description',
1828 :priority_id => 5,
1828 :priority_id => 5,
1829 :custom_field_values => {'1' => ['', 'MySQL', 'Oracle']}}
1829 :custom_field_values => {'1' => ['', 'MySQL', 'Oracle']}}
1830 end
1830 end
1831 assert_response 302
1831 assert_response 302
1832 issue = Issue.first(:order => 'id DESC')
1832 issue = Issue.first(:order => 'id DESC')
1833 assert_equal ['MySQL', 'Oracle'], issue.custom_field_value(1).sort
1833 assert_equal ['MySQL', 'Oracle'], issue.custom_field_value(1).sort
1834 end
1834 end
1835
1835
1836 def test_post_create_with_empty_multi_custom_field
1836 def test_post_create_with_empty_multi_custom_field
1837 field = IssueCustomField.find_by_name('Database')
1837 field = IssueCustomField.find_by_name('Database')
1838 field.update_attribute(:multiple, true)
1838 field.update_attribute(:multiple, true)
1839
1839
1840 @request.session[:user_id] = 2
1840 @request.session[:user_id] = 2
1841 assert_difference 'Issue.count' do
1841 assert_difference 'Issue.count' do
1842 post :create, :project_id => 1,
1842 post :create, :project_id => 1,
1843 :issue => {:tracker_id => 1,
1843 :issue => {:tracker_id => 1,
1844 :subject => 'This is the test_new issue',
1844 :subject => 'This is the test_new issue',
1845 :description => 'This is the description',
1845 :description => 'This is the description',
1846 :priority_id => 5,
1846 :priority_id => 5,
1847 :custom_field_values => {'1' => ['']}}
1847 :custom_field_values => {'1' => ['']}}
1848 end
1848 end
1849 assert_response 302
1849 assert_response 302
1850 issue = Issue.first(:order => 'id DESC')
1850 issue = Issue.first(:order => 'id DESC')
1851 assert_equal [''], issue.custom_field_value(1).sort
1851 assert_equal [''], issue.custom_field_value(1).sort
1852 end
1852 end
1853
1853
1854 def test_post_create_with_multi_user_custom_field
1854 def test_post_create_with_multi_user_custom_field
1855 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1855 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1856 :tracker_ids => [1], :is_for_all => true)
1856 :tracker_ids => [1], :is_for_all => true)
1857
1857
1858 @request.session[:user_id] = 2
1858 @request.session[:user_id] = 2
1859 assert_difference 'Issue.count' do
1859 assert_difference 'Issue.count' do
1860 post :create, :project_id => 1,
1860 post :create, :project_id => 1,
1861 :issue => {:tracker_id => 1,
1861 :issue => {:tracker_id => 1,
1862 :subject => 'This is the test_new issue',
1862 :subject => 'This is the test_new issue',
1863 :description => 'This is the description',
1863 :description => 'This is the description',
1864 :priority_id => 5,
1864 :priority_id => 5,
1865 :custom_field_values => {field.id.to_s => ['', '2', '3']}}
1865 :custom_field_values => {field.id.to_s => ['', '2', '3']}}
1866 end
1866 end
1867 assert_response 302
1867 assert_response 302
1868 issue = Issue.first(:order => 'id DESC')
1868 issue = Issue.first(:order => 'id DESC')
1869 assert_equal ['2', '3'], issue.custom_field_value(field).sort
1869 assert_equal ['2', '3'], issue.custom_field_value(field).sort
1870 end
1870 end
1871
1871
1872 def test_post_create_with_required_custom_field_and_without_custom_fields_param
1872 def test_post_create_with_required_custom_field_and_without_custom_fields_param
1873 field = IssueCustomField.find_by_name('Database')
1873 field = IssueCustomField.find_by_name('Database')
1874 field.update_attribute(:is_required, true)
1874 field.update_attribute(:is_required, true)
1875
1875
1876 @request.session[:user_id] = 2
1876 @request.session[:user_id] = 2
1877 assert_no_difference 'Issue.count' do
1877 assert_no_difference 'Issue.count' do
1878 post :create, :project_id => 1,
1878 post :create, :project_id => 1,
1879 :issue => {:tracker_id => 1,
1879 :issue => {:tracker_id => 1,
1880 :subject => 'This is the test_new issue',
1880 :subject => 'This is the test_new issue',
1881 :description => 'This is the description',
1881 :description => 'This is the description',
1882 :priority_id => 5}
1882 :priority_id => 5}
1883 end
1883 end
1884 assert_response :success
1884 assert_response :success
1885 assert_template 'new'
1885 assert_template 'new'
1886 issue = assigns(:issue)
1886 issue = assigns(:issue)
1887 assert_not_nil issue
1887 assert_not_nil issue
1888 assert_error_tag :content => /Database can&#x27;t be blank/
1888 assert_error_tag :content => /Database can&#x27;t be blank/
1889 end
1889 end
1890
1890
1891 def test_create_should_validate_required_fields
1891 def test_create_should_validate_required_fields
1892 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1892 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1893 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1893 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1894 WorkflowPermission.delete_all
1894 WorkflowPermission.delete_all
1895 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'required')
1895 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'required')
1896 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
1896 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
1897 @request.session[:user_id] = 2
1897 @request.session[:user_id] = 2
1898
1898
1899 assert_no_difference 'Issue.count' do
1899 assert_no_difference 'Issue.count' do
1900 post :create, :project_id => 1, :issue => {
1900 post :create, :project_id => 1, :issue => {
1901 :tracker_id => 2,
1901 :tracker_id => 2,
1902 :status_id => 1,
1902 :status_id => 1,
1903 :subject => 'Test',
1903 :subject => 'Test',
1904 :start_date => '',
1904 :start_date => '',
1905 :due_date => '',
1905 :due_date => '',
1906 :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ''}
1906 :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ''}
1907 }
1907 }
1908 assert_response :success
1908 assert_response :success
1909 assert_template 'new'
1909 assert_template 'new'
1910 end
1910 end
1911
1911
1912 assert_error_tag :content => /Due date can&#x27;t be blank/i
1912 assert_error_tag :content => /Due date can&#x27;t be blank/i
1913 assert_error_tag :content => /Bar can&#x27;t be blank/i
1913 assert_error_tag :content => /Bar can&#x27;t be blank/i
1914 end
1914 end
1915
1915
1916 def test_create_should_ignore_readonly_fields
1916 def test_create_should_ignore_readonly_fields
1917 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1917 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1918 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1918 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1919 WorkflowPermission.delete_all
1919 WorkflowPermission.delete_all
1920 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
1920 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
1921 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
1921 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
1922 @request.session[:user_id] = 2
1922 @request.session[:user_id] = 2
1923
1923
1924 assert_difference 'Issue.count' do
1924 assert_difference 'Issue.count' do
1925 post :create, :project_id => 1, :issue => {
1925 post :create, :project_id => 1, :issue => {
1926 :tracker_id => 2,
1926 :tracker_id => 2,
1927 :status_id => 1,
1927 :status_id => 1,
1928 :subject => 'Test',
1928 :subject => 'Test',
1929 :start_date => '2012-07-14',
1929 :start_date => '2012-07-14',
1930 :due_date => '2012-07-16',
1930 :due_date => '2012-07-16',
1931 :custom_field_values => {cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'}
1931 :custom_field_values => {cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'}
1932 }
1932 }
1933 assert_response 302
1933 assert_response 302
1934 end
1934 end
1935
1935
1936 issue = Issue.first(:order => 'id DESC')
1936 issue = Issue.first(:order => 'id DESC')
1937 assert_equal Date.parse('2012-07-14'), issue.start_date
1937 assert_equal Date.parse('2012-07-14'), issue.start_date
1938 assert_nil issue.due_date
1938 assert_nil issue.due_date
1939 assert_equal 'value1', issue.custom_field_value(cf1)
1939 assert_equal 'value1', issue.custom_field_value(cf1)
1940 assert_nil issue.custom_field_value(cf2)
1940 assert_nil issue.custom_field_value(cf2)
1941 end
1941 end
1942
1942
1943 def test_post_create_with_watchers
1943 def test_post_create_with_watchers
1944 @request.session[:user_id] = 2
1944 @request.session[:user_id] = 2
1945 ActionMailer::Base.deliveries.clear
1945 ActionMailer::Base.deliveries.clear
1946
1946
1947 assert_difference 'Watcher.count', 2 do
1947 assert_difference 'Watcher.count', 2 do
1948 post :create, :project_id => 1,
1948 post :create, :project_id => 1,
1949 :issue => {:tracker_id => 1,
1949 :issue => {:tracker_id => 1,
1950 :subject => 'This is a new issue with watchers',
1950 :subject => 'This is a new issue with watchers',
1951 :description => 'This is the description',
1951 :description => 'This is the description',
1952 :priority_id => 5,
1952 :priority_id => 5,
1953 :watcher_user_ids => ['2', '3']}
1953 :watcher_user_ids => ['2', '3']}
1954 end
1954 end
1955 issue = Issue.find_by_subject('This is a new issue with watchers')
1955 issue = Issue.find_by_subject('This is a new issue with watchers')
1956 assert_not_nil issue
1956 assert_not_nil issue
1957 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
1957 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
1958
1958
1959 # Watchers added
1959 # Watchers added
1960 assert_equal [2, 3], issue.watcher_user_ids.sort
1960 assert_equal [2, 3], issue.watcher_user_ids.sort
1961 assert issue.watched_by?(User.find(3))
1961 assert issue.watched_by?(User.find(3))
1962 # Watchers notified
1962 # Watchers notified
1963 mail = ActionMailer::Base.deliveries.last
1963 mail = ActionMailer::Base.deliveries.last
1964 assert_not_nil mail
1964 assert_not_nil mail
1965 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
1965 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
1966 end
1966 end
1967
1967
1968 def test_post_create_subissue
1968 def test_post_create_subissue
1969 @request.session[:user_id] = 2
1969 @request.session[:user_id] = 2
1970
1970
1971 assert_difference 'Issue.count' do
1971 assert_difference 'Issue.count' do
1972 post :create, :project_id => 1,
1972 post :create, :project_id => 1,
1973 :issue => {:tracker_id => 1,
1973 :issue => {:tracker_id => 1,
1974 :subject => 'This is a child issue',
1974 :subject => 'This is a child issue',
1975 :parent_issue_id => '2'}
1975 :parent_issue_id => '2'}
1976 assert_response 302
1976 assert_response 302
1977 end
1977 end
1978 issue = Issue.order('id DESC').first
1978 issue = Issue.order('id DESC').first
1979 assert_equal Issue.find(2), issue.parent
1979 assert_equal Issue.find(2), issue.parent
1980 end
1980 end
1981
1981
1982 def test_post_create_subissue_with_sharp_parent_id
1982 def test_post_create_subissue_with_sharp_parent_id
1983 @request.session[:user_id] = 2
1983 @request.session[:user_id] = 2
1984
1984
1985 assert_difference 'Issue.count' do
1985 assert_difference 'Issue.count' do
1986 post :create, :project_id => 1,
1986 post :create, :project_id => 1,
1987 :issue => {:tracker_id => 1,
1987 :issue => {:tracker_id => 1,
1988 :subject => 'This is a child issue',
1988 :subject => 'This is a child issue',
1989 :parent_issue_id => '#2'}
1989 :parent_issue_id => '#2'}
1990 assert_response 302
1990 assert_response 302
1991 end
1991 end
1992 issue = Issue.order('id DESC').first
1992 issue = Issue.order('id DESC').first
1993 assert_equal Issue.find(2), issue.parent
1993 assert_equal Issue.find(2), issue.parent
1994 end
1994 end
1995
1995
1996 def test_post_create_subissue_with_non_visible_parent_id_should_not_validate
1996 def test_post_create_subissue_with_non_visible_parent_id_should_not_validate
1997 @request.session[:user_id] = 2
1997 @request.session[:user_id] = 2
1998
1998
1999 assert_no_difference 'Issue.count' do
1999 assert_no_difference 'Issue.count' do
2000 post :create, :project_id => 1,
2000 post :create, :project_id => 1,
2001 :issue => {:tracker_id => 1,
2001 :issue => {:tracker_id => 1,
2002 :subject => 'This is a child issue',
2002 :subject => 'This is a child issue',
2003 :parent_issue_id => '4'}
2003 :parent_issue_id => '4'}
2004
2004
2005 assert_response :success
2005 assert_response :success
2006 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '4'
2006 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '4'
2007 assert_error_tag :content => /Parent task is invalid/i
2007 assert_error_tag :content => /Parent task is invalid/i
2008 end
2008 end
2009 end
2009 end
2010
2010
2011 def test_post_create_subissue_with_non_numeric_parent_id_should_not_validate
2011 def test_post_create_subissue_with_non_numeric_parent_id_should_not_validate
2012 @request.session[:user_id] = 2
2012 @request.session[:user_id] = 2
2013
2013
2014 assert_no_difference 'Issue.count' do
2014 assert_no_difference 'Issue.count' do
2015 post :create, :project_id => 1,
2015 post :create, :project_id => 1,
2016 :issue => {:tracker_id => 1,
2016 :issue => {:tracker_id => 1,
2017 :subject => 'This is a child issue',
2017 :subject => 'This is a child issue',
2018 :parent_issue_id => '01ABC'}
2018 :parent_issue_id => '01ABC'}
2019
2019
2020 assert_response :success
2020 assert_response :success
2021 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '01ABC'
2021 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '01ABC'
2022 assert_error_tag :content => /Parent task is invalid/i
2022 assert_error_tag :content => /Parent task is invalid/i
2023 end
2023 end
2024 end
2024 end
2025
2025
2026 def test_post_create_private
2026 def test_post_create_private
2027 @request.session[:user_id] = 2
2027 @request.session[:user_id] = 2
2028
2028
2029 assert_difference 'Issue.count' do
2029 assert_difference 'Issue.count' do
2030 post :create, :project_id => 1,
2030 post :create, :project_id => 1,
2031 :issue => {:tracker_id => 1,
2031 :issue => {:tracker_id => 1,
2032 :subject => 'This is a private issue',
2032 :subject => 'This is a private issue',
2033 :is_private => '1'}
2033 :is_private => '1'}
2034 end
2034 end
2035 issue = Issue.first(:order => 'id DESC')
2035 issue = Issue.first(:order => 'id DESC')
2036 assert issue.is_private?
2036 assert issue.is_private?
2037 end
2037 end
2038
2038
2039 def test_post_create_private_with_set_own_issues_private_permission
2039 def test_post_create_private_with_set_own_issues_private_permission
2040 role = Role.find(1)
2040 role = Role.find(1)
2041 role.remove_permission! :set_issues_private
2041 role.remove_permission! :set_issues_private
2042 role.add_permission! :set_own_issues_private
2042 role.add_permission! :set_own_issues_private
2043
2043
2044 @request.session[:user_id] = 2
2044 @request.session[:user_id] = 2
2045
2045
2046 assert_difference 'Issue.count' do
2046 assert_difference 'Issue.count' do
2047 post :create, :project_id => 1,
2047 post :create, :project_id => 1,
2048 :issue => {:tracker_id => 1,
2048 :issue => {:tracker_id => 1,
2049 :subject => 'This is a private issue',
2049 :subject => 'This is a private issue',
2050 :is_private => '1'}
2050 :is_private => '1'}
2051 end
2051 end
2052 issue = Issue.first(:order => 'id DESC')
2052 issue = Issue.first(:order => 'id DESC')
2053 assert issue.is_private?
2053 assert issue.is_private?
2054 end
2054 end
2055
2055
2056 def test_post_create_should_send_a_notification
2056 def test_post_create_should_send_a_notification
2057 ActionMailer::Base.deliveries.clear
2057 ActionMailer::Base.deliveries.clear
2058 @request.session[:user_id] = 2
2058 @request.session[:user_id] = 2
2059 assert_difference 'Issue.count' do
2059 assert_difference 'Issue.count' do
2060 post :create, :project_id => 1,
2060 post :create, :project_id => 1,
2061 :issue => {:tracker_id => 3,
2061 :issue => {:tracker_id => 3,
2062 :subject => 'This is the test_new issue',
2062 :subject => 'This is the test_new issue',
2063 :description => 'This is the description',
2063 :description => 'This is the description',
2064 :priority_id => 5,
2064 :priority_id => 5,
2065 :estimated_hours => '',
2065 :estimated_hours => '',
2066 :custom_field_values => {'2' => 'Value for field 2'}}
2066 :custom_field_values => {'2' => 'Value for field 2'}}
2067 end
2067 end
2068 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2068 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2069
2069
2070 assert_equal 1, ActionMailer::Base.deliveries.size
2070 assert_equal 1, ActionMailer::Base.deliveries.size
2071 end
2071 end
2072
2072
2073 def test_post_create_should_preserve_fields_values_on_validation_failure
2073 def test_post_create_should_preserve_fields_values_on_validation_failure
2074 @request.session[:user_id] = 2
2074 @request.session[:user_id] = 2
2075 post :create, :project_id => 1,
2075 post :create, :project_id => 1,
2076 :issue => {:tracker_id => 1,
2076 :issue => {:tracker_id => 1,
2077 # empty subject
2077 # empty subject
2078 :subject => '',
2078 :subject => '',
2079 :description => 'This is a description',
2079 :description => 'This is a description',
2080 :priority_id => 6,
2080 :priority_id => 6,
2081 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
2081 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
2082 assert_response :success
2082 assert_response :success
2083 assert_template 'new'
2083 assert_template 'new'
2084
2084
2085 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
2085 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
2086 :content => "\nThis is a description"
2086 :content => "\nThis is a description"
2087 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
2087 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
2088 :child => { :tag => 'option', :attributes => { :selected => 'selected',
2088 :child => { :tag => 'option', :attributes => { :selected => 'selected',
2089 :value => '6' },
2089 :value => '6' },
2090 :content => 'High' }
2090 :content => 'High' }
2091 # Custom fields
2091 # Custom fields
2092 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
2092 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
2093 :child => { :tag => 'option', :attributes => { :selected => 'selected',
2093 :child => { :tag => 'option', :attributes => { :selected => 'selected',
2094 :value => 'Oracle' },
2094 :value => 'Oracle' },
2095 :content => 'Oracle' }
2095 :content => 'Oracle' }
2096 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
2096 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
2097 :value => 'Value for field 2'}
2097 :value => 'Value for field 2'}
2098 end
2098 end
2099
2099
2100 def test_post_create_with_failure_should_preserve_watchers
2100 def test_post_create_with_failure_should_preserve_watchers
2101 assert !User.find(8).member_of?(Project.find(1))
2101 assert !User.find(8).member_of?(Project.find(1))
2102
2102
2103 @request.session[:user_id] = 2
2103 @request.session[:user_id] = 2
2104 post :create, :project_id => 1,
2104 post :create, :project_id => 1,
2105 :issue => {:tracker_id => 1,
2105 :issue => {:tracker_id => 1,
2106 :watcher_user_ids => ['3', '8']}
2106 :watcher_user_ids => ['3', '8']}
2107 assert_response :success
2107 assert_response :success
2108 assert_template 'new'
2108 assert_template 'new'
2109
2109
2110 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '2', :checked => nil}
2110 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '2', :checked => nil}
2111 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '3', :checked => 'checked'}
2111 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '3', :checked => 'checked'}
2112 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '8', :checked => 'checked'}
2112 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '8', :checked => 'checked'}
2113 end
2113 end
2114
2114
2115 def test_post_create_should_ignore_non_safe_attributes
2115 def test_post_create_should_ignore_non_safe_attributes
2116 @request.session[:user_id] = 2
2116 @request.session[:user_id] = 2
2117 assert_nothing_raised do
2117 assert_nothing_raised do
2118 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
2118 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
2119 end
2119 end
2120 end
2120 end
2121
2121
2122 def test_post_create_with_attachment
2122 def test_post_create_with_attachment
2123 set_tmp_attachments_directory
2123 set_tmp_attachments_directory
2124 @request.session[:user_id] = 2
2124 @request.session[:user_id] = 2
2125
2125
2126 assert_difference 'Issue.count' do
2126 assert_difference 'Issue.count' do
2127 assert_difference 'Attachment.count' do
2127 assert_difference 'Attachment.count' do
2128 post :create, :project_id => 1,
2128 post :create, :project_id => 1,
2129 :issue => { :tracker_id => '1', :subject => 'With attachment' },
2129 :issue => { :tracker_id => '1', :subject => 'With attachment' },
2130 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2130 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2131 end
2131 end
2132 end
2132 end
2133
2133
2134 issue = Issue.first(:order => 'id DESC')
2134 issue = Issue.first(:order => 'id DESC')
2135 attachment = Attachment.first(:order => 'id DESC')
2135 attachment = Attachment.first(:order => 'id DESC')
2136
2136
2137 assert_equal issue, attachment.container
2137 assert_equal issue, attachment.container
2138 assert_equal 2, attachment.author_id
2138 assert_equal 2, attachment.author_id
2139 assert_equal 'testfile.txt', attachment.filename
2139 assert_equal 'testfile.txt', attachment.filename
2140 assert_equal 'text/plain', attachment.content_type
2140 assert_equal 'text/plain', attachment.content_type
2141 assert_equal 'test file', attachment.description
2141 assert_equal 'test file', attachment.description
2142 assert_equal 59, attachment.filesize
2142 assert_equal 59, attachment.filesize
2143 assert File.exists?(attachment.diskfile)
2143 assert File.exists?(attachment.diskfile)
2144 assert_equal 59, File.size(attachment.diskfile)
2144 assert_equal 59, File.size(attachment.diskfile)
2145 end
2145 end
2146
2146
2147 def test_post_create_with_failure_should_save_attachments
2147 def test_post_create_with_failure_should_save_attachments
2148 set_tmp_attachments_directory
2148 set_tmp_attachments_directory
2149 @request.session[:user_id] = 2
2149 @request.session[:user_id] = 2
2150
2150
2151 assert_no_difference 'Issue.count' do
2151 assert_no_difference 'Issue.count' do
2152 assert_difference 'Attachment.count' do
2152 assert_difference 'Attachment.count' do
2153 post :create, :project_id => 1,
2153 post :create, :project_id => 1,
2154 :issue => { :tracker_id => '1', :subject => '' },
2154 :issue => { :tracker_id => '1', :subject => '' },
2155 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2155 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2156 assert_response :success
2156 assert_response :success
2157 assert_template 'new'
2157 assert_template 'new'
2158 end
2158 end
2159 end
2159 end
2160
2160
2161 attachment = Attachment.first(:order => 'id DESC')
2161 attachment = Attachment.first(:order => 'id DESC')
2162 assert_equal 'testfile.txt', attachment.filename
2162 assert_equal 'testfile.txt', attachment.filename
2163 assert File.exists?(attachment.diskfile)
2163 assert File.exists?(attachment.diskfile)
2164 assert_nil attachment.container
2164 assert_nil attachment.container
2165
2165
2166 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2166 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2167 assert_tag 'span', :content => /testfile.txt/
2167 assert_tag 'span', :content => /testfile.txt/
2168 end
2168 end
2169
2169
2170 def test_post_create_with_failure_should_keep_saved_attachments
2170 def test_post_create_with_failure_should_keep_saved_attachments
2171 set_tmp_attachments_directory
2171 set_tmp_attachments_directory
2172 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2172 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2173 @request.session[:user_id] = 2
2173 @request.session[:user_id] = 2
2174
2174
2175 assert_no_difference 'Issue.count' do
2175 assert_no_difference 'Issue.count' do
2176 assert_no_difference 'Attachment.count' do
2176 assert_no_difference 'Attachment.count' do
2177 post :create, :project_id => 1,
2177 post :create, :project_id => 1,
2178 :issue => { :tracker_id => '1', :subject => '' },
2178 :issue => { :tracker_id => '1', :subject => '' },
2179 :attachments => {'p0' => {'token' => attachment.token}}
2179 :attachments => {'p0' => {'token' => attachment.token}}
2180 assert_response :success
2180 assert_response :success
2181 assert_template 'new'
2181 assert_template 'new'
2182 end
2182 end
2183 end
2183 end
2184
2184
2185 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2185 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2186 assert_tag 'span', :content => /testfile.txt/
2186 assert_tag 'span', :content => /testfile.txt/
2187 end
2187 end
2188
2188
2189 def test_post_create_should_attach_saved_attachments
2189 def test_post_create_should_attach_saved_attachments
2190 set_tmp_attachments_directory
2190 set_tmp_attachments_directory
2191 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2191 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2192 @request.session[:user_id] = 2
2192 @request.session[:user_id] = 2
2193
2193
2194 assert_difference 'Issue.count' do
2194 assert_difference 'Issue.count' do
2195 assert_no_difference 'Attachment.count' do
2195 assert_no_difference 'Attachment.count' do
2196 post :create, :project_id => 1,
2196 post :create, :project_id => 1,
2197 :issue => { :tracker_id => '1', :subject => 'Saved attachments' },
2197 :issue => { :tracker_id => '1', :subject => 'Saved attachments' },
2198 :attachments => {'p0' => {'token' => attachment.token}}
2198 :attachments => {'p0' => {'token' => attachment.token}}
2199 assert_response 302
2199 assert_response 302
2200 end
2200 end
2201 end
2201 end
2202
2202
2203 issue = Issue.first(:order => 'id DESC')
2203 issue = Issue.first(:order => 'id DESC')
2204 assert_equal 1, issue.attachments.count
2204 assert_equal 1, issue.attachments.count
2205
2205
2206 attachment.reload
2206 attachment.reload
2207 assert_equal issue, attachment.container
2207 assert_equal issue, attachment.container
2208 end
2208 end
2209
2209
2210 context "without workflow privilege" do
2210 context "without workflow privilege" do
2211 setup do
2211 setup do
2212 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2212 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2213 Role.anonymous.add_permission! :add_issues, :add_issue_notes
2213 Role.anonymous.add_permission! :add_issues, :add_issue_notes
2214 end
2214 end
2215
2215
2216 context "#new" do
2216 context "#new" do
2217 should "propose default status only" do
2217 should "propose default status only" do
2218 get :new, :project_id => 1
2218 get :new, :project_id => 1
2219 assert_response :success
2219 assert_response :success
2220 assert_template 'new'
2220 assert_template 'new'
2221 assert_tag :tag => 'select',
2221 assert_tag :tag => 'select',
2222 :attributes => {:name => 'issue[status_id]'},
2222 :attributes => {:name => 'issue[status_id]'},
2223 :children => {:count => 1},
2223 :children => {:count => 1},
2224 :child => {:tag => 'option', :attributes => {:value => IssueStatus.default.id.to_s}}
2224 :child => {:tag => 'option', :attributes => {:value => IssueStatus.default.id.to_s}}
2225 end
2225 end
2226
2226
2227 should "accept default status" do
2227 should "accept default status" do
2228 assert_difference 'Issue.count' do
2228 assert_difference 'Issue.count' do
2229 post :create, :project_id => 1,
2229 post :create, :project_id => 1,
2230 :issue => {:tracker_id => 1,
2230 :issue => {:tracker_id => 1,
2231 :subject => 'This is an issue',
2231 :subject => 'This is an issue',
2232 :status_id => 1}
2232 :status_id => 1}
2233 end
2233 end
2234 issue = Issue.last(:order => 'id')
2234 issue = Issue.last(:order => 'id')
2235 assert_equal IssueStatus.default, issue.status
2235 assert_equal IssueStatus.default, issue.status
2236 end
2236 end
2237
2237
2238 should "ignore unauthorized status" do
2238 should "ignore unauthorized status" do
2239 assert_difference 'Issue.count' do
2239 assert_difference 'Issue.count' do
2240 post :create, :project_id => 1,
2240 post :create, :project_id => 1,
2241 :issue => {:tracker_id => 1,
2241 :issue => {:tracker_id => 1,
2242 :subject => 'This is an issue',
2242 :subject => 'This is an issue',
2243 :status_id => 3}
2243 :status_id => 3}
2244 end
2244 end
2245 issue = Issue.last(:order => 'id')
2245 issue = Issue.last(:order => 'id')
2246 assert_equal IssueStatus.default, issue.status
2246 assert_equal IssueStatus.default, issue.status
2247 end
2247 end
2248 end
2248 end
2249
2249
2250 context "#update" do
2250 context "#update" do
2251 should "ignore status change" do
2251 should "ignore status change" do
2252 assert_difference 'Journal.count' do
2252 assert_difference 'Journal.count' do
2253 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2253 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2254 end
2254 end
2255 assert_equal 1, Issue.find(1).status_id
2255 assert_equal 1, Issue.find(1).status_id
2256 end
2256 end
2257
2257
2258 should "ignore attributes changes" do
2258 should "ignore attributes changes" do
2259 assert_difference 'Journal.count' do
2259 assert_difference 'Journal.count' do
2260 put :update, :id => 1, :issue => {:subject => 'changed', :assigned_to_id => 2, :notes => 'just trying'}
2260 put :update, :id => 1, :issue => {:subject => 'changed', :assigned_to_id => 2, :notes => 'just trying'}
2261 end
2261 end
2262 issue = Issue.find(1)
2262 issue = Issue.find(1)
2263 assert_equal "Can't print recipes", issue.subject
2263 assert_equal "Can't print recipes", issue.subject
2264 assert_nil issue.assigned_to
2264 assert_nil issue.assigned_to
2265 end
2265 end
2266 end
2266 end
2267 end
2267 end
2268
2268
2269 context "with workflow privilege" do
2269 context "with workflow privilege" do
2270 setup do
2270 setup do
2271 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2271 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2272 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
2272 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
2273 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
2273 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
2274 Role.anonymous.add_permission! :add_issues, :add_issue_notes
2274 Role.anonymous.add_permission! :add_issues, :add_issue_notes
2275 end
2275 end
2276
2276
2277 context "#update" do
2277 context "#update" do
2278 should "accept authorized status" do
2278 should "accept authorized status" do
2279 assert_difference 'Journal.count' do
2279 assert_difference 'Journal.count' do
2280 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2280 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2281 end
2281 end
2282 assert_equal 3, Issue.find(1).status_id
2282 assert_equal 3, Issue.find(1).status_id
2283 end
2283 end
2284
2284
2285 should "ignore unauthorized status" do
2285 should "ignore unauthorized status" do
2286 assert_difference 'Journal.count' do
2286 assert_difference 'Journal.count' do
2287 put :update, :id => 1, :issue => {:status_id => 2, :notes => 'just trying'}
2287 put :update, :id => 1, :issue => {:status_id => 2, :notes => 'just trying'}
2288 end
2288 end
2289 assert_equal 1, Issue.find(1).status_id
2289 assert_equal 1, Issue.find(1).status_id
2290 end
2290 end
2291
2291
2292 should "accept authorized attributes changes" do
2292 should "accept authorized attributes changes" do
2293 assert_difference 'Journal.count' do
2293 assert_difference 'Journal.count' do
2294 put :update, :id => 1, :issue => {:assigned_to_id => 2, :notes => 'just trying'}
2294 put :update, :id => 1, :issue => {:assigned_to_id => 2, :notes => 'just trying'}
2295 end
2295 end
2296 issue = Issue.find(1)
2296 issue = Issue.find(1)
2297 assert_equal 2, issue.assigned_to_id
2297 assert_equal 2, issue.assigned_to_id
2298 end
2298 end
2299
2299
2300 should "ignore unauthorized attributes changes" do
2300 should "ignore unauthorized attributes changes" do
2301 assert_difference 'Journal.count' do
2301 assert_difference 'Journal.count' do
2302 put :update, :id => 1, :issue => {:subject => 'changed', :notes => 'just trying'}
2302 put :update, :id => 1, :issue => {:subject => 'changed', :notes => 'just trying'}
2303 end
2303 end
2304 issue = Issue.find(1)
2304 issue = Issue.find(1)
2305 assert_equal "Can't print recipes", issue.subject
2305 assert_equal "Can't print recipes", issue.subject
2306 end
2306 end
2307 end
2307 end
2308
2308
2309 context "and :edit_issues permission" do
2309 context "and :edit_issues permission" do
2310 setup do
2310 setup do
2311 Role.anonymous.add_permission! :add_issues, :edit_issues
2311 Role.anonymous.add_permission! :add_issues, :edit_issues
2312 end
2312 end
2313
2313
2314 should "accept authorized status" do
2314 should "accept authorized status" do
2315 assert_difference 'Journal.count' do
2315 assert_difference 'Journal.count' do
2316 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2316 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2317 end
2317 end
2318 assert_equal 3, Issue.find(1).status_id
2318 assert_equal 3, Issue.find(1).status_id
2319 end
2319 end
2320
2320
2321 should "ignore unauthorized status" do
2321 should "ignore unauthorized status" do
2322 assert_difference 'Journal.count' do
2322 assert_difference 'Journal.count' do
2323 put :update, :id => 1, :issue => {:status_id => 2, :notes => 'just trying'}
2323 put :update, :id => 1, :issue => {:status_id => 2, :notes => 'just trying'}
2324 end
2324 end
2325 assert_equal 1, Issue.find(1).status_id
2325 assert_equal 1, Issue.find(1).status_id
2326 end
2326 end
2327
2327
2328 should "accept authorized attributes changes" do
2328 should "accept authorized attributes changes" do
2329 assert_difference 'Journal.count' do
2329 assert_difference 'Journal.count' do
2330 put :update, :id => 1, :issue => {:subject => 'changed', :assigned_to_id => 2, :notes => 'just trying'}
2330 put :update, :id => 1, :issue => {:subject => 'changed', :assigned_to_id => 2, :notes => 'just trying'}
2331 end
2331 end
2332 issue = Issue.find(1)
2332 issue = Issue.find(1)
2333 assert_equal "changed", issue.subject
2333 assert_equal "changed", issue.subject
2334 assert_equal 2, issue.assigned_to_id
2334 assert_equal 2, issue.assigned_to_id
2335 end
2335 end
2336 end
2336 end
2337 end
2337 end
2338
2338
2339 def test_new_as_copy
2339 def test_new_as_copy
2340 @request.session[:user_id] = 2
2340 @request.session[:user_id] = 2
2341 get :new, :project_id => 1, :copy_from => 1
2341 get :new, :project_id => 1, :copy_from => 1
2342
2342
2343 assert_response :success
2343 assert_response :success
2344 assert_template 'new'
2344 assert_template 'new'
2345
2345
2346 assert_not_nil assigns(:issue)
2346 assert_not_nil assigns(:issue)
2347 orig = Issue.find(1)
2347 orig = Issue.find(1)
2348 assert_equal 1, assigns(:issue).project_id
2348 assert_equal 1, assigns(:issue).project_id
2349 assert_equal orig.subject, assigns(:issue).subject
2349 assert_equal orig.subject, assigns(:issue).subject
2350 assert assigns(:issue).copy?
2350 assert assigns(:issue).copy?
2351
2351
2352 assert_tag 'form', :attributes => {:id => 'issue-form', :action => '/projects/ecookbook/issues'}
2352 assert_tag 'form', :attributes => {:id => 'issue-form', :action => '/projects/ecookbook/issues'}
2353 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
2353 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
2354 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2354 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2355 :child => {:tag => 'option', :attributes => {:value => '1', :selected => 'selected'}, :content => 'eCookbook'}
2355 :child => {:tag => 'option', :attributes => {:value => '1', :selected => 'selected'}, :content => 'eCookbook'}
2356 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2356 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2357 :child => {:tag => 'option', :attributes => {:value => '2', :selected => nil}, :content => 'OnlineStore'}
2357 :child => {:tag => 'option', :attributes => {:value => '2', :selected => nil}, :content => 'OnlineStore'}
2358 assert_tag 'input', :attributes => {:name => 'copy_from', :value => '1'}
2358 assert_tag 'input', :attributes => {:name => 'copy_from', :value => '1'}
2359
2360 # "New issue" menu item should not link to copy
2361 assert_select '#main-menu a.new-issue[href=/projects/ecookbook/issues/new]'
2359 end
2362 end
2360
2363
2361 def test_new_as_copy_with_attachments_should_show_copy_attachments_checkbox
2364 def test_new_as_copy_with_attachments_should_show_copy_attachments_checkbox
2362 @request.session[:user_id] = 2
2365 @request.session[:user_id] = 2
2363 issue = Issue.find(3)
2366 issue = Issue.find(3)
2364 assert issue.attachments.count > 0
2367 assert issue.attachments.count > 0
2365 get :new, :project_id => 1, :copy_from => 3
2368 get :new, :project_id => 1, :copy_from => 3
2366
2369
2367 assert_tag 'input', :attributes => {:name => 'copy_attachments', :type => 'checkbox', :checked => 'checked', :value => '1'}
2370 assert_tag 'input', :attributes => {:name => 'copy_attachments', :type => 'checkbox', :checked => 'checked', :value => '1'}
2368 end
2371 end
2369
2372
2370 def test_new_as_copy_without_attachments_should_not_show_copy_attachments_checkbox
2373 def test_new_as_copy_without_attachments_should_not_show_copy_attachments_checkbox
2371 @request.session[:user_id] = 2
2374 @request.session[:user_id] = 2
2372 issue = Issue.find(3)
2375 issue = Issue.find(3)
2373 issue.attachments.delete_all
2376 issue.attachments.delete_all
2374 get :new, :project_id => 1, :copy_from => 3
2377 get :new, :project_id => 1, :copy_from => 3
2375
2378
2376 assert_no_tag 'input', :attributes => {:name => 'copy_attachments', :type => 'checkbox', :checked => 'checked', :value => '1'}
2379 assert_no_tag 'input', :attributes => {:name => 'copy_attachments', :type => 'checkbox', :checked => 'checked', :value => '1'}
2377 end
2380 end
2378
2381
2379 def test_new_as_copy_with_subtasks_should_show_copy_subtasks_checkbox
2382 def test_new_as_copy_with_subtasks_should_show_copy_subtasks_checkbox
2380 @request.session[:user_id] = 2
2383 @request.session[:user_id] = 2
2381 issue = Issue.generate_with_descendants!
2384 issue = Issue.generate_with_descendants!
2382 get :new, :project_id => 1, :copy_from => issue.id
2385 get :new, :project_id => 1, :copy_from => issue.id
2383
2386
2384 assert_select 'input[type=checkbox][name=copy_subtasks][checked=checked][value=1]'
2387 assert_select 'input[type=checkbox][name=copy_subtasks][checked=checked][value=1]'
2385 end
2388 end
2386
2389
2387 def test_new_as_copy_with_invalid_issue_should_respond_with_404
2390 def test_new_as_copy_with_invalid_issue_should_respond_with_404
2388 @request.session[:user_id] = 2
2391 @request.session[:user_id] = 2
2389 get :new, :project_id => 1, :copy_from => 99999
2392 get :new, :project_id => 1, :copy_from => 99999
2390 assert_response 404
2393 assert_response 404
2391 end
2394 end
2392
2395
2393 def test_create_as_copy_on_different_project
2396 def test_create_as_copy_on_different_project
2394 @request.session[:user_id] = 2
2397 @request.session[:user_id] = 2
2395 assert_difference 'Issue.count' do
2398 assert_difference 'Issue.count' do
2396 post :create, :project_id => 1, :copy_from => 1,
2399 post :create, :project_id => 1, :copy_from => 1,
2397 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2400 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2398
2401
2399 assert_not_nil assigns(:issue)
2402 assert_not_nil assigns(:issue)
2400 assert assigns(:issue).copy?
2403 assert assigns(:issue).copy?
2401 end
2404 end
2402 issue = Issue.first(:order => 'id DESC')
2405 issue = Issue.first(:order => 'id DESC')
2403 assert_redirected_to "/issues/#{issue.id}"
2406 assert_redirected_to "/issues/#{issue.id}"
2404
2407
2405 assert_equal 2, issue.project_id
2408 assert_equal 2, issue.project_id
2406 assert_equal 3, issue.tracker_id
2409 assert_equal 3, issue.tracker_id
2407 assert_equal 'Copy', issue.subject
2410 assert_equal 'Copy', issue.subject
2408 end
2411 end
2409
2412
2410 def test_create_as_copy_should_copy_attachments
2413 def test_create_as_copy_should_copy_attachments
2411 @request.session[:user_id] = 2
2414 @request.session[:user_id] = 2
2412 issue = Issue.find(3)
2415 issue = Issue.find(3)
2413 count = issue.attachments.count
2416 count = issue.attachments.count
2414 assert count > 0
2417 assert count > 0
2415
2418
2416 assert_difference 'Issue.count' do
2419 assert_difference 'Issue.count' do
2417 assert_difference 'Attachment.count', count do
2420 assert_difference 'Attachment.count', count do
2418 assert_no_difference 'Journal.count' do
2421 assert_no_difference 'Journal.count' do
2419 post :create, :project_id => 1, :copy_from => 3,
2422 post :create, :project_id => 1, :copy_from => 3,
2420 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'},
2423 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'},
2421 :copy_attachments => '1'
2424 :copy_attachments => '1'
2422 end
2425 end
2423 end
2426 end
2424 end
2427 end
2425 copy = Issue.first(:order => 'id DESC')
2428 copy = Issue.first(:order => 'id DESC')
2426 assert_equal count, copy.attachments.count
2429 assert_equal count, copy.attachments.count
2427 assert_equal issue.attachments.map(&:filename).sort, copy.attachments.map(&:filename).sort
2430 assert_equal issue.attachments.map(&:filename).sort, copy.attachments.map(&:filename).sort
2428 end
2431 end
2429
2432
2430 def test_create_as_copy_without_copy_attachments_option_should_not_copy_attachments
2433 def test_create_as_copy_without_copy_attachments_option_should_not_copy_attachments
2431 @request.session[:user_id] = 2
2434 @request.session[:user_id] = 2
2432 issue = Issue.find(3)
2435 issue = Issue.find(3)
2433 count = issue.attachments.count
2436 count = issue.attachments.count
2434 assert count > 0
2437 assert count > 0
2435
2438
2436 assert_difference 'Issue.count' do
2439 assert_difference 'Issue.count' do
2437 assert_no_difference 'Attachment.count' do
2440 assert_no_difference 'Attachment.count' do
2438 assert_no_difference 'Journal.count' do
2441 assert_no_difference 'Journal.count' do
2439 post :create, :project_id => 1, :copy_from => 3,
2442 post :create, :project_id => 1, :copy_from => 3,
2440 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'}
2443 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'}
2441 end
2444 end
2442 end
2445 end
2443 end
2446 end
2444 copy = Issue.first(:order => 'id DESC')
2447 copy = Issue.first(:order => 'id DESC')
2445 assert_equal 0, copy.attachments.count
2448 assert_equal 0, copy.attachments.count
2446 end
2449 end
2447
2450
2448 def test_create_as_copy_with_attachments_should_add_new_files
2451 def test_create_as_copy_with_attachments_should_add_new_files
2449 @request.session[:user_id] = 2
2452 @request.session[:user_id] = 2
2450 issue = Issue.find(3)
2453 issue = Issue.find(3)
2451 count = issue.attachments.count
2454 count = issue.attachments.count
2452 assert count > 0
2455 assert count > 0
2453
2456
2454 assert_difference 'Issue.count' do
2457 assert_difference 'Issue.count' do
2455 assert_difference 'Attachment.count', count + 1 do
2458 assert_difference 'Attachment.count', count + 1 do
2456 assert_no_difference 'Journal.count' do
2459 assert_no_difference 'Journal.count' do
2457 post :create, :project_id => 1, :copy_from => 3,
2460 post :create, :project_id => 1, :copy_from => 3,
2458 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'},
2461 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'},
2459 :copy_attachments => '1',
2462 :copy_attachments => '1',
2460 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2463 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2461 end
2464 end
2462 end
2465 end
2463 end
2466 end
2464 copy = Issue.first(:order => 'id DESC')
2467 copy = Issue.first(:order => 'id DESC')
2465 assert_equal count + 1, copy.attachments.count
2468 assert_equal count + 1, copy.attachments.count
2466 end
2469 end
2467
2470
2468 def test_create_as_copy_should_add_relation_with_copied_issue
2471 def test_create_as_copy_should_add_relation_with_copied_issue
2469 @request.session[:user_id] = 2
2472 @request.session[:user_id] = 2
2470
2473
2471 assert_difference 'Issue.count' do
2474 assert_difference 'Issue.count' do
2472 assert_difference 'IssueRelation.count' do
2475 assert_difference 'IssueRelation.count' do
2473 post :create, :project_id => 1, :copy_from => 1,
2476 post :create, :project_id => 1, :copy_from => 1,
2474 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2477 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2475 end
2478 end
2476 end
2479 end
2477 copy = Issue.first(:order => 'id DESC')
2480 copy = Issue.first(:order => 'id DESC')
2478 assert_equal 1, copy.relations.size
2481 assert_equal 1, copy.relations.size
2479 end
2482 end
2480
2483
2481 def test_create_as_copy_should_copy_subtasks
2484 def test_create_as_copy_should_copy_subtasks
2482 @request.session[:user_id] = 2
2485 @request.session[:user_id] = 2
2483 issue = Issue.generate_with_descendants!
2486 issue = Issue.generate_with_descendants!
2484 count = issue.descendants.count
2487 count = issue.descendants.count
2485
2488
2486 assert_difference 'Issue.count', count+1 do
2489 assert_difference 'Issue.count', count+1 do
2487 assert_no_difference 'Journal.count' do
2490 assert_no_difference 'Journal.count' do
2488 post :create, :project_id => 1, :copy_from => issue.id,
2491 post :create, :project_id => 1, :copy_from => issue.id,
2489 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with subtasks'},
2492 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with subtasks'},
2490 :copy_subtasks => '1'
2493 :copy_subtasks => '1'
2491 end
2494 end
2492 end
2495 end
2493 copy = Issue.where(:parent_id => nil).first(:order => 'id DESC')
2496 copy = Issue.where(:parent_id => nil).first(:order => 'id DESC')
2494 assert_equal count, copy.descendants.count
2497 assert_equal count, copy.descendants.count
2495 assert_equal issue.descendants.map(&:subject).sort, copy.descendants.map(&:subject).sort
2498 assert_equal issue.descendants.map(&:subject).sort, copy.descendants.map(&:subject).sort
2496 end
2499 end
2497
2500
2498 def test_create_as_copy_without_copy_subtasks_option_should_not_copy_subtasks
2501 def test_create_as_copy_without_copy_subtasks_option_should_not_copy_subtasks
2499 @request.session[:user_id] = 2
2502 @request.session[:user_id] = 2
2500 issue = Issue.generate_with_descendants!
2503 issue = Issue.generate_with_descendants!
2501
2504
2502 assert_difference 'Issue.count', 1 do
2505 assert_difference 'Issue.count', 1 do
2503 assert_no_difference 'Journal.count' do
2506 assert_no_difference 'Journal.count' do
2504 post :create, :project_id => 1, :copy_from => 3,
2507 post :create, :project_id => 1, :copy_from => 3,
2505 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with subtasks'}
2508 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with subtasks'}
2506 end
2509 end
2507 end
2510 end
2508 copy = Issue.where(:parent_id => nil).first(:order => 'id DESC')
2511 copy = Issue.where(:parent_id => nil).first(:order => 'id DESC')
2509 assert_equal 0, copy.descendants.count
2512 assert_equal 0, copy.descendants.count
2510 end
2513 end
2511
2514
2512 def test_create_as_copy_with_failure
2515 def test_create_as_copy_with_failure
2513 @request.session[:user_id] = 2
2516 @request.session[:user_id] = 2
2514 post :create, :project_id => 1, :copy_from => 1,
2517 post :create, :project_id => 1, :copy_from => 1,
2515 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => ''}
2518 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => ''}
2516
2519
2517 assert_response :success
2520 assert_response :success
2518 assert_template 'new'
2521 assert_template 'new'
2519
2522
2520 assert_not_nil assigns(:issue)
2523 assert_not_nil assigns(:issue)
2521 assert assigns(:issue).copy?
2524 assert assigns(:issue).copy?
2522
2525
2523 assert_tag 'form', :attributes => {:id => 'issue-form', :action => '/projects/ecookbook/issues'}
2526 assert_tag 'form', :attributes => {:id => 'issue-form', :action => '/projects/ecookbook/issues'}
2524 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
2527 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
2525 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2528 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2526 :child => {:tag => 'option', :attributes => {:value => '1', :selected => nil}, :content => 'eCookbook'}
2529 :child => {:tag => 'option', :attributes => {:value => '1', :selected => nil}, :content => 'eCookbook'}
2527 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2530 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2528 :child => {:tag => 'option', :attributes => {:value => '2', :selected => 'selected'}, :content => 'OnlineStore'}
2531 :child => {:tag => 'option', :attributes => {:value => '2', :selected => 'selected'}, :content => 'OnlineStore'}
2529 assert_tag 'input', :attributes => {:name => 'copy_from', :value => '1'}
2532 assert_tag 'input', :attributes => {:name => 'copy_from', :value => '1'}
2530 end
2533 end
2531
2534
2532 def test_create_as_copy_on_project_without_permission_should_ignore_target_project
2535 def test_create_as_copy_on_project_without_permission_should_ignore_target_project
2533 @request.session[:user_id] = 2
2536 @request.session[:user_id] = 2
2534 assert !User.find(2).member_of?(Project.find(4))
2537 assert !User.find(2).member_of?(Project.find(4))
2535
2538
2536 assert_difference 'Issue.count' do
2539 assert_difference 'Issue.count' do
2537 post :create, :project_id => 1, :copy_from => 1,
2540 post :create, :project_id => 1, :copy_from => 1,
2538 :issue => {:project_id => '4', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2541 :issue => {:project_id => '4', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2539 end
2542 end
2540 issue = Issue.first(:order => 'id DESC')
2543 issue = Issue.first(:order => 'id DESC')
2541 assert_equal 1, issue.project_id
2544 assert_equal 1, issue.project_id
2542 end
2545 end
2543
2546
2544 def test_get_edit
2547 def test_get_edit
2545 @request.session[:user_id] = 2
2548 @request.session[:user_id] = 2
2546 get :edit, :id => 1
2549 get :edit, :id => 1
2547 assert_response :success
2550 assert_response :success
2548 assert_template 'edit'
2551 assert_template 'edit'
2549 assert_not_nil assigns(:issue)
2552 assert_not_nil assigns(:issue)
2550 assert_equal Issue.find(1), assigns(:issue)
2553 assert_equal Issue.find(1), assigns(:issue)
2551
2554
2552 # Be sure we don't display inactive IssuePriorities
2555 # Be sure we don't display inactive IssuePriorities
2553 assert ! IssuePriority.find(15).active?
2556 assert ! IssuePriority.find(15).active?
2554 assert_no_tag :option, :attributes => {:value => '15'},
2557 assert_no_tag :option, :attributes => {:value => '15'},
2555 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
2558 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
2556 end
2559 end
2557
2560
2558 def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
2561 def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
2559 @request.session[:user_id] = 2
2562 @request.session[:user_id] = 2
2560 Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
2563 Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
2561
2564
2562 get :edit, :id => 1
2565 get :edit, :id => 1
2563 assert_tag 'input', :attributes => {:name => 'time_entry[hours]'}
2566 assert_tag 'input', :attributes => {:name => 'time_entry[hours]'}
2564 end
2567 end
2565
2568
2566 def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
2569 def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
2567 @request.session[:user_id] = 2
2570 @request.session[:user_id] = 2
2568 Role.find_by_name('Manager').remove_permission! :log_time
2571 Role.find_by_name('Manager').remove_permission! :log_time
2569
2572
2570 get :edit, :id => 1
2573 get :edit, :id => 1
2571 assert_no_tag 'input', :attributes => {:name => 'time_entry[hours]'}
2574 assert_no_tag 'input', :attributes => {:name => 'time_entry[hours]'}
2572 end
2575 end
2573
2576
2574 def test_get_edit_with_params
2577 def test_get_edit_with_params
2575 @request.session[:user_id] = 2
2578 @request.session[:user_id] = 2
2576 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
2579 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
2577 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => TimeEntryActivity.first.id }
2580 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => TimeEntryActivity.first.id }
2578 assert_response :success
2581 assert_response :success
2579 assert_template 'edit'
2582 assert_template 'edit'
2580
2583
2581 issue = assigns(:issue)
2584 issue = assigns(:issue)
2582 assert_not_nil issue
2585 assert_not_nil issue
2583
2586
2584 assert_equal 5, issue.status_id
2587 assert_equal 5, issue.status_id
2585 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
2588 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
2586 :child => { :tag => 'option',
2589 :child => { :tag => 'option',
2587 :content => 'Closed',
2590 :content => 'Closed',
2588 :attributes => { :selected => 'selected' } }
2591 :attributes => { :selected => 'selected' } }
2589
2592
2590 assert_equal 7, issue.priority_id
2593 assert_equal 7, issue.priority_id
2591 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
2594 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
2592 :child => { :tag => 'option',
2595 :child => { :tag => 'option',
2593 :content => 'Urgent',
2596 :content => 'Urgent',
2594 :attributes => { :selected => 'selected' } }
2597 :attributes => { :selected => 'selected' } }
2595
2598
2596 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => '2.5' }
2599 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => '2.5' }
2597 assert_tag :select, :attributes => { :name => 'time_entry[activity_id]' },
2600 assert_tag :select, :attributes => { :name => 'time_entry[activity_id]' },
2598 :child => { :tag => 'option',
2601 :child => { :tag => 'option',
2599 :attributes => { :selected => 'selected', :value => TimeEntryActivity.first.id } }
2602 :attributes => { :selected => 'selected', :value => TimeEntryActivity.first.id } }
2600 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => 'test_get_edit_with_params' }
2603 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => 'test_get_edit_with_params' }
2601 end
2604 end
2602
2605
2603 def test_get_edit_with_multi_custom_field
2606 def test_get_edit_with_multi_custom_field
2604 field = CustomField.find(1)
2607 field = CustomField.find(1)
2605 field.update_attribute :multiple, true
2608 field.update_attribute :multiple, true
2606 issue = Issue.find(1)
2609 issue = Issue.find(1)
2607 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
2610 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
2608 issue.save!
2611 issue.save!
2609
2612
2610 @request.session[:user_id] = 2
2613 @request.session[:user_id] = 2
2611 get :edit, :id => 1
2614 get :edit, :id => 1
2612 assert_response :success
2615 assert_response :success
2613 assert_template 'edit'
2616 assert_template 'edit'
2614
2617
2615 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]', :multiple => 'multiple'}
2618 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]', :multiple => 'multiple'}
2616 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2619 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2617 :child => {:tag => 'option', :attributes => {:value => 'MySQL', :selected => 'selected'}}
2620 :child => {:tag => 'option', :attributes => {:value => 'MySQL', :selected => 'selected'}}
2618 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2621 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2619 :child => {:tag => 'option', :attributes => {:value => 'PostgreSQL', :selected => nil}}
2622 :child => {:tag => 'option', :attributes => {:value => 'PostgreSQL', :selected => nil}}
2620 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2623 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2621 :child => {:tag => 'option', :attributes => {:value => 'Oracle', :selected => 'selected'}}
2624 :child => {:tag => 'option', :attributes => {:value => 'Oracle', :selected => 'selected'}}
2622 end
2625 end
2623
2626
2624 def test_update_edit_form
2627 def test_update_edit_form
2625 @request.session[:user_id] = 2
2628 @request.session[:user_id] = 2
2626 xhr :put, :new, :project_id => 1,
2629 xhr :put, :new, :project_id => 1,
2627 :id => 1,
2630 :id => 1,
2628 :issue => {:tracker_id => 2,
2631 :issue => {:tracker_id => 2,
2629 :subject => 'This is the test_new issue',
2632 :subject => 'This is the test_new issue',
2630 :description => 'This is the description',
2633 :description => 'This is the description',
2631 :priority_id => 5}
2634 :priority_id => 5}
2632 assert_response :success
2635 assert_response :success
2633 assert_equal 'text/javascript', response.content_type
2636 assert_equal 'text/javascript', response.content_type
2634 assert_template 'update_form'
2637 assert_template 'update_form'
2635 assert_template 'form'
2638 assert_template 'form'
2636
2639
2637 issue = assigns(:issue)
2640 issue = assigns(:issue)
2638 assert_kind_of Issue, issue
2641 assert_kind_of Issue, issue
2639 assert_equal 1, issue.id
2642 assert_equal 1, issue.id
2640 assert_equal 1, issue.project_id
2643 assert_equal 1, issue.project_id
2641 assert_equal 2, issue.tracker_id
2644 assert_equal 2, issue.tracker_id
2642 assert_equal 'This is the test_new issue', issue.subject
2645 assert_equal 'This is the test_new issue', issue.subject
2643 end
2646 end
2644
2647
2645 def test_update_edit_form_should_keep_issue_author
2648 def test_update_edit_form_should_keep_issue_author
2646 @request.session[:user_id] = 3
2649 @request.session[:user_id] = 3
2647 xhr :put, :new, :project_id => 1, :id => 1, :issue => {:subject => 'Changed'}
2650 xhr :put, :new, :project_id => 1, :id => 1, :issue => {:subject => 'Changed'}
2648 assert_response :success
2651 assert_response :success
2649 assert_equal 'text/javascript', response.content_type
2652 assert_equal 'text/javascript', response.content_type
2650
2653
2651 issue = assigns(:issue)
2654 issue = assigns(:issue)
2652 assert_equal User.find(2), issue.author
2655 assert_equal User.find(2), issue.author
2653 assert_equal 2, issue.author_id
2656 assert_equal 2, issue.author_id
2654 assert_not_equal User.current, issue.author
2657 assert_not_equal User.current, issue.author
2655 end
2658 end
2656
2659
2657 def test_update_edit_form_should_propose_transitions_based_on_initial_status
2660 def test_update_edit_form_should_propose_transitions_based_on_initial_status
2658 @request.session[:user_id] = 2
2661 @request.session[:user_id] = 2
2659 WorkflowTransition.delete_all
2662 WorkflowTransition.delete_all
2660 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
2663 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
2661 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
2664 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
2662 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
2665 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
2663
2666
2664 xhr :put, :new, :project_id => 1,
2667 xhr :put, :new, :project_id => 1,
2665 :id => 2,
2668 :id => 2,
2666 :issue => {:tracker_id => 2,
2669 :issue => {:tracker_id => 2,
2667 :status_id => 5,
2670 :status_id => 5,
2668 :subject => 'This is an issue'}
2671 :subject => 'This is an issue'}
2669
2672
2670 assert_equal 5, assigns(:issue).status_id
2673 assert_equal 5, assigns(:issue).status_id
2671 assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
2674 assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
2672 end
2675 end
2673
2676
2674 def test_update_edit_form_with_project_change
2677 def test_update_edit_form_with_project_change
2675 @request.session[:user_id] = 2
2678 @request.session[:user_id] = 2
2676 xhr :put, :new, :project_id => 1,
2679 xhr :put, :new, :project_id => 1,
2677 :id => 1,
2680 :id => 1,
2678 :issue => {:project_id => 2,
2681 :issue => {:project_id => 2,
2679 :tracker_id => 2,
2682 :tracker_id => 2,
2680 :subject => 'This is the test_new issue',
2683 :subject => 'This is the test_new issue',
2681 :description => 'This is the description',
2684 :description => 'This is the description',
2682 :priority_id => 5}
2685 :priority_id => 5}
2683 assert_response :success
2686 assert_response :success
2684 assert_template 'form'
2687 assert_template 'form'
2685
2688
2686 issue = assigns(:issue)
2689 issue = assigns(:issue)
2687 assert_kind_of Issue, issue
2690 assert_kind_of Issue, issue
2688 assert_equal 1, issue.id
2691 assert_equal 1, issue.id
2689 assert_equal 2, issue.project_id
2692 assert_equal 2, issue.project_id
2690 assert_equal 2, issue.tracker_id
2693 assert_equal 2, issue.tracker_id
2691 assert_equal 'This is the test_new issue', issue.subject
2694 assert_equal 'This is the test_new issue', issue.subject
2692 end
2695 end
2693
2696
2694 def test_put_update_without_custom_fields_param
2697 def test_put_update_without_custom_fields_param
2695 @request.session[:user_id] = 2
2698 @request.session[:user_id] = 2
2696 ActionMailer::Base.deliveries.clear
2699 ActionMailer::Base.deliveries.clear
2697
2700
2698 issue = Issue.find(1)
2701 issue = Issue.find(1)
2699 assert_equal '125', issue.custom_value_for(2).value
2702 assert_equal '125', issue.custom_value_for(2).value
2700 old_subject = issue.subject
2703 old_subject = issue.subject
2701 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
2704 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
2702
2705
2703 assert_difference('Journal.count') do
2706 assert_difference('Journal.count') do
2704 assert_difference('JournalDetail.count', 2) do
2707 assert_difference('JournalDetail.count', 2) do
2705 put :update, :id => 1, :issue => {:subject => new_subject,
2708 put :update, :id => 1, :issue => {:subject => new_subject,
2706 :priority_id => '6',
2709 :priority_id => '6',
2707 :category_id => '1' # no change
2710 :category_id => '1' # no change
2708 }
2711 }
2709 end
2712 end
2710 end
2713 end
2711 assert_redirected_to :action => 'show', :id => '1'
2714 assert_redirected_to :action => 'show', :id => '1'
2712 issue.reload
2715 issue.reload
2713 assert_equal new_subject, issue.subject
2716 assert_equal new_subject, issue.subject
2714 # Make sure custom fields were not cleared
2717 # Make sure custom fields were not cleared
2715 assert_equal '125', issue.custom_value_for(2).value
2718 assert_equal '125', issue.custom_value_for(2).value
2716
2719
2717 mail = ActionMailer::Base.deliveries.last
2720 mail = ActionMailer::Base.deliveries.last
2718 assert_not_nil mail
2721 assert_not_nil mail
2719 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2722 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2720 assert_mail_body_match "Subject changed from #{old_subject} to #{new_subject}", mail
2723 assert_mail_body_match "Subject changed from #{old_subject} to #{new_subject}", mail
2721 end
2724 end
2722
2725
2723 def test_put_update_with_project_change
2726 def test_put_update_with_project_change
2724 @request.session[:user_id] = 2
2727 @request.session[:user_id] = 2
2725 ActionMailer::Base.deliveries.clear
2728 ActionMailer::Base.deliveries.clear
2726
2729
2727 assert_difference('Journal.count') do
2730 assert_difference('Journal.count') do
2728 assert_difference('JournalDetail.count', 3) do
2731 assert_difference('JournalDetail.count', 3) do
2729 put :update, :id => 1, :issue => {:project_id => '2',
2732 put :update, :id => 1, :issue => {:project_id => '2',
2730 :tracker_id => '1', # no change
2733 :tracker_id => '1', # no change
2731 :priority_id => '6',
2734 :priority_id => '6',
2732 :category_id => '3'
2735 :category_id => '3'
2733 }
2736 }
2734 end
2737 end
2735 end
2738 end
2736 assert_redirected_to :action => 'show', :id => '1'
2739 assert_redirected_to :action => 'show', :id => '1'
2737 issue = Issue.find(1)
2740 issue = Issue.find(1)
2738 assert_equal 2, issue.project_id
2741 assert_equal 2, issue.project_id
2739 assert_equal 1, issue.tracker_id
2742 assert_equal 1, issue.tracker_id
2740 assert_equal 6, issue.priority_id
2743 assert_equal 6, issue.priority_id
2741 assert_equal 3, issue.category_id
2744 assert_equal 3, issue.category_id
2742
2745
2743 mail = ActionMailer::Base.deliveries.last
2746 mail = ActionMailer::Base.deliveries.last
2744 assert_not_nil mail
2747 assert_not_nil mail
2745 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2748 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2746 assert_mail_body_match "Project changed from eCookbook to OnlineStore", mail
2749 assert_mail_body_match "Project changed from eCookbook to OnlineStore", mail
2747 end
2750 end
2748
2751
2749 def test_put_update_with_tracker_change
2752 def test_put_update_with_tracker_change
2750 @request.session[:user_id] = 2
2753 @request.session[:user_id] = 2
2751 ActionMailer::Base.deliveries.clear
2754 ActionMailer::Base.deliveries.clear
2752
2755
2753 assert_difference('Journal.count') do
2756 assert_difference('Journal.count') do
2754 assert_difference('JournalDetail.count', 2) do
2757 assert_difference('JournalDetail.count', 2) do
2755 put :update, :id => 1, :issue => {:project_id => '1',
2758 put :update, :id => 1, :issue => {:project_id => '1',
2756 :tracker_id => '2',
2759 :tracker_id => '2',
2757 :priority_id => '6'
2760 :priority_id => '6'
2758 }
2761 }
2759 end
2762 end
2760 end
2763 end
2761 assert_redirected_to :action => 'show', :id => '1'
2764 assert_redirected_to :action => 'show', :id => '1'
2762 issue = Issue.find(1)
2765 issue = Issue.find(1)
2763 assert_equal 1, issue.project_id
2766 assert_equal 1, issue.project_id
2764 assert_equal 2, issue.tracker_id
2767 assert_equal 2, issue.tracker_id
2765 assert_equal 6, issue.priority_id
2768 assert_equal 6, issue.priority_id
2766 assert_equal 1, issue.category_id
2769 assert_equal 1, issue.category_id
2767
2770
2768 mail = ActionMailer::Base.deliveries.last
2771 mail = ActionMailer::Base.deliveries.last
2769 assert_not_nil mail
2772 assert_not_nil mail
2770 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2773 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2771 assert_mail_body_match "Tracker changed from Bug to Feature request", mail
2774 assert_mail_body_match "Tracker changed from Bug to Feature request", mail
2772 end
2775 end
2773
2776
2774 def test_put_update_with_custom_field_change
2777 def test_put_update_with_custom_field_change
2775 @request.session[:user_id] = 2
2778 @request.session[:user_id] = 2
2776 issue = Issue.find(1)
2779 issue = Issue.find(1)
2777 assert_equal '125', issue.custom_value_for(2).value
2780 assert_equal '125', issue.custom_value_for(2).value
2778
2781
2779 assert_difference('Journal.count') do
2782 assert_difference('Journal.count') do
2780 assert_difference('JournalDetail.count', 3) do
2783 assert_difference('JournalDetail.count', 3) do
2781 put :update, :id => 1, :issue => {:subject => 'Custom field change',
2784 put :update, :id => 1, :issue => {:subject => 'Custom field change',
2782 :priority_id => '6',
2785 :priority_id => '6',
2783 :category_id => '1', # no change
2786 :category_id => '1', # no change
2784 :custom_field_values => { '2' => 'New custom value' }
2787 :custom_field_values => { '2' => 'New custom value' }
2785 }
2788 }
2786 end
2789 end
2787 end
2790 end
2788 assert_redirected_to :action => 'show', :id => '1'
2791 assert_redirected_to :action => 'show', :id => '1'
2789 issue.reload
2792 issue.reload
2790 assert_equal 'New custom value', issue.custom_value_for(2).value
2793 assert_equal 'New custom value', issue.custom_value_for(2).value
2791
2794
2792 mail = ActionMailer::Base.deliveries.last
2795 mail = ActionMailer::Base.deliveries.last
2793 assert_not_nil mail
2796 assert_not_nil mail
2794 assert_mail_body_match "Searchable field changed from 125 to New custom value", mail
2797 assert_mail_body_match "Searchable field changed from 125 to New custom value", mail
2795 end
2798 end
2796
2799
2797 def test_put_update_with_multi_custom_field_change
2800 def test_put_update_with_multi_custom_field_change
2798 field = CustomField.find(1)
2801 field = CustomField.find(1)
2799 field.update_attribute :multiple, true
2802 field.update_attribute :multiple, true
2800 issue = Issue.find(1)
2803 issue = Issue.find(1)
2801 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
2804 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
2802 issue.save!
2805 issue.save!
2803
2806
2804 @request.session[:user_id] = 2
2807 @request.session[:user_id] = 2
2805 assert_difference('Journal.count') do
2808 assert_difference('Journal.count') do
2806 assert_difference('JournalDetail.count', 3) do
2809 assert_difference('JournalDetail.count', 3) do
2807 put :update, :id => 1,
2810 put :update, :id => 1,
2808 :issue => {
2811 :issue => {
2809 :subject => 'Custom field change',
2812 :subject => 'Custom field change',
2810 :custom_field_values => { '1' => ['', 'Oracle', 'PostgreSQL'] }
2813 :custom_field_values => { '1' => ['', 'Oracle', 'PostgreSQL'] }
2811 }
2814 }
2812 end
2815 end
2813 end
2816 end
2814 assert_redirected_to :action => 'show', :id => '1'
2817 assert_redirected_to :action => 'show', :id => '1'
2815 assert_equal ['Oracle', 'PostgreSQL'], Issue.find(1).custom_field_value(1).sort
2818 assert_equal ['Oracle', 'PostgreSQL'], Issue.find(1).custom_field_value(1).sort
2816 end
2819 end
2817
2820
2818 def test_put_update_with_status_and_assignee_change
2821 def test_put_update_with_status_and_assignee_change
2819 issue = Issue.find(1)
2822 issue = Issue.find(1)
2820 assert_equal 1, issue.status_id
2823 assert_equal 1, issue.status_id
2821 @request.session[:user_id] = 2
2824 @request.session[:user_id] = 2
2822 assert_difference('TimeEntry.count', 0) do
2825 assert_difference('TimeEntry.count', 0) do
2823 put :update,
2826 put :update,
2824 :id => 1,
2827 :id => 1,
2825 :issue => { :status_id => 2, :assigned_to_id => 3, :notes => 'Assigned to dlopper' },
2828 :issue => { :status_id => 2, :assigned_to_id => 3, :notes => 'Assigned to dlopper' },
2826 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
2829 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
2827 end
2830 end
2828 assert_redirected_to :action => 'show', :id => '1'
2831 assert_redirected_to :action => 'show', :id => '1'
2829 issue.reload
2832 issue.reload
2830 assert_equal 2, issue.status_id
2833 assert_equal 2, issue.status_id
2831 j = Journal.find(:first, :order => 'id DESC')
2834 j = Journal.find(:first, :order => 'id DESC')
2832 assert_equal 'Assigned to dlopper', j.notes
2835 assert_equal 'Assigned to dlopper', j.notes
2833 assert_equal 2, j.details.size
2836 assert_equal 2, j.details.size
2834
2837
2835 mail = ActionMailer::Base.deliveries.last
2838 mail = ActionMailer::Base.deliveries.last
2836 assert_mail_body_match "Status changed from New to Assigned", mail
2839 assert_mail_body_match "Status changed from New to Assigned", mail
2837 # subject should contain the new status
2840 # subject should contain the new status
2838 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
2841 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
2839 end
2842 end
2840
2843
2841 def test_put_update_with_note_only
2844 def test_put_update_with_note_only
2842 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
2845 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
2843 # anonymous user
2846 # anonymous user
2844 put :update,
2847 put :update,
2845 :id => 1,
2848 :id => 1,
2846 :issue => { :notes => notes }
2849 :issue => { :notes => notes }
2847 assert_redirected_to :action => 'show', :id => '1'
2850 assert_redirected_to :action => 'show', :id => '1'
2848 j = Journal.find(:first, :order => 'id DESC')
2851 j = Journal.find(:first, :order => 'id DESC')
2849 assert_equal notes, j.notes
2852 assert_equal notes, j.notes
2850 assert_equal 0, j.details.size
2853 assert_equal 0, j.details.size
2851 assert_equal User.anonymous, j.user
2854 assert_equal User.anonymous, j.user
2852
2855
2853 mail = ActionMailer::Base.deliveries.last
2856 mail = ActionMailer::Base.deliveries.last
2854 assert_mail_body_match notes, mail
2857 assert_mail_body_match notes, mail
2855 end
2858 end
2856
2859
2857 def test_put_update_with_private_note_only
2860 def test_put_update_with_private_note_only
2858 notes = 'Private note'
2861 notes = 'Private note'
2859 @request.session[:user_id] = 2
2862 @request.session[:user_id] = 2
2860
2863
2861 assert_difference 'Journal.count' do
2864 assert_difference 'Journal.count' do
2862 put :update, :id => 1, :issue => {:notes => notes, :private_notes => '1'}
2865 put :update, :id => 1, :issue => {:notes => notes, :private_notes => '1'}
2863 assert_redirected_to :action => 'show', :id => '1'
2866 assert_redirected_to :action => 'show', :id => '1'
2864 end
2867 end
2865
2868
2866 j = Journal.order('id DESC').first
2869 j = Journal.order('id DESC').first
2867 assert_equal notes, j.notes
2870 assert_equal notes, j.notes
2868 assert_equal true, j.private_notes
2871 assert_equal true, j.private_notes
2869 end
2872 end
2870
2873
2871 def test_put_update_with_private_note_and_changes
2874 def test_put_update_with_private_note_and_changes
2872 notes = 'Private note'
2875 notes = 'Private note'
2873 @request.session[:user_id] = 2
2876 @request.session[:user_id] = 2
2874
2877
2875 assert_difference 'Journal.count', 2 do
2878 assert_difference 'Journal.count', 2 do
2876 put :update, :id => 1, :issue => {:subject => 'New subject', :notes => notes, :private_notes => '1'}
2879 put :update, :id => 1, :issue => {:subject => 'New subject', :notes => notes, :private_notes => '1'}
2877 assert_redirected_to :action => 'show', :id => '1'
2880 assert_redirected_to :action => 'show', :id => '1'
2878 end
2881 end
2879
2882
2880 j = Journal.order('id DESC').first
2883 j = Journal.order('id DESC').first
2881 assert_equal notes, j.notes
2884 assert_equal notes, j.notes
2882 assert_equal true, j.private_notes
2885 assert_equal true, j.private_notes
2883 assert_equal 0, j.details.count
2886 assert_equal 0, j.details.count
2884
2887
2885 j = Journal.order('id DESC').offset(1).first
2888 j = Journal.order('id DESC').offset(1).first
2886 assert_nil j.notes
2889 assert_nil j.notes
2887 assert_equal false, j.private_notes
2890 assert_equal false, j.private_notes
2888 assert_equal 1, j.details.count
2891 assert_equal 1, j.details.count
2889 end
2892 end
2890
2893
2891 def test_put_update_with_note_and_spent_time
2894 def test_put_update_with_note_and_spent_time
2892 @request.session[:user_id] = 2
2895 @request.session[:user_id] = 2
2893 spent_hours_before = Issue.find(1).spent_hours
2896 spent_hours_before = Issue.find(1).spent_hours
2894 assert_difference('TimeEntry.count') do
2897 assert_difference('TimeEntry.count') do
2895 put :update,
2898 put :update,
2896 :id => 1,
2899 :id => 1,
2897 :issue => { :notes => '2.5 hours added' },
2900 :issue => { :notes => '2.5 hours added' },
2898 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
2901 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
2899 end
2902 end
2900 assert_redirected_to :action => 'show', :id => '1'
2903 assert_redirected_to :action => 'show', :id => '1'
2901
2904
2902 issue = Issue.find(1)
2905 issue = Issue.find(1)
2903
2906
2904 j = Journal.find(:first, :order => 'id DESC')
2907 j = Journal.find(:first, :order => 'id DESC')
2905 assert_equal '2.5 hours added', j.notes
2908 assert_equal '2.5 hours added', j.notes
2906 assert_equal 0, j.details.size
2909 assert_equal 0, j.details.size
2907
2910
2908 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
2911 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
2909 assert_not_nil t
2912 assert_not_nil t
2910 assert_equal 2.5, t.hours
2913 assert_equal 2.5, t.hours
2911 assert_equal spent_hours_before + 2.5, issue.spent_hours
2914 assert_equal spent_hours_before + 2.5, issue.spent_hours
2912 end
2915 end
2913
2916
2914 def test_put_update_with_attachment_only
2917 def test_put_update_with_attachment_only
2915 set_tmp_attachments_directory
2918 set_tmp_attachments_directory
2916
2919
2917 # Delete all fixtured journals, a race condition can occur causing the wrong
2920 # Delete all fixtured journals, a race condition can occur causing the wrong
2918 # journal to get fetched in the next find.
2921 # journal to get fetched in the next find.
2919 Journal.delete_all
2922 Journal.delete_all
2920
2923
2921 # anonymous user
2924 # anonymous user
2922 assert_difference 'Attachment.count' do
2925 assert_difference 'Attachment.count' do
2923 put :update, :id => 1,
2926 put :update, :id => 1,
2924 :issue => {:notes => ''},
2927 :issue => {:notes => ''},
2925 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2928 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2926 end
2929 end
2927
2930
2928 assert_redirected_to :action => 'show', :id => '1'
2931 assert_redirected_to :action => 'show', :id => '1'
2929 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
2932 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
2930 assert j.notes.blank?
2933 assert j.notes.blank?
2931 assert_equal 1, j.details.size
2934 assert_equal 1, j.details.size
2932 assert_equal 'testfile.txt', j.details.first.value
2935 assert_equal 'testfile.txt', j.details.first.value
2933 assert_equal User.anonymous, j.user
2936 assert_equal User.anonymous, j.user
2934
2937
2935 attachment = Attachment.first(:order => 'id DESC')
2938 attachment = Attachment.first(:order => 'id DESC')
2936 assert_equal Issue.find(1), attachment.container
2939 assert_equal Issue.find(1), attachment.container
2937 assert_equal User.anonymous, attachment.author
2940 assert_equal User.anonymous, attachment.author
2938 assert_equal 'testfile.txt', attachment.filename
2941 assert_equal 'testfile.txt', attachment.filename
2939 assert_equal 'text/plain', attachment.content_type
2942 assert_equal 'text/plain', attachment.content_type
2940 assert_equal 'test file', attachment.description
2943 assert_equal 'test file', attachment.description
2941 assert_equal 59, attachment.filesize
2944 assert_equal 59, attachment.filesize
2942 assert File.exists?(attachment.diskfile)
2945 assert File.exists?(attachment.diskfile)
2943 assert_equal 59, File.size(attachment.diskfile)
2946 assert_equal 59, File.size(attachment.diskfile)
2944
2947
2945 mail = ActionMailer::Base.deliveries.last
2948 mail = ActionMailer::Base.deliveries.last
2946 assert_mail_body_match 'testfile.txt', mail
2949 assert_mail_body_match 'testfile.txt', mail
2947 end
2950 end
2948
2951
2949 def test_put_update_with_failure_should_save_attachments
2952 def test_put_update_with_failure_should_save_attachments
2950 set_tmp_attachments_directory
2953 set_tmp_attachments_directory
2951 @request.session[:user_id] = 2
2954 @request.session[:user_id] = 2
2952
2955
2953 assert_no_difference 'Journal.count' do
2956 assert_no_difference 'Journal.count' do
2954 assert_difference 'Attachment.count' do
2957 assert_difference 'Attachment.count' do
2955 put :update, :id => 1,
2958 put :update, :id => 1,
2956 :issue => { :subject => '' },
2959 :issue => { :subject => '' },
2957 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2960 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2958 assert_response :success
2961 assert_response :success
2959 assert_template 'edit'
2962 assert_template 'edit'
2960 end
2963 end
2961 end
2964 end
2962
2965
2963 attachment = Attachment.first(:order => 'id DESC')
2966 attachment = Attachment.first(:order => 'id DESC')
2964 assert_equal 'testfile.txt', attachment.filename
2967 assert_equal 'testfile.txt', attachment.filename
2965 assert File.exists?(attachment.diskfile)
2968 assert File.exists?(attachment.diskfile)
2966 assert_nil attachment.container
2969 assert_nil attachment.container
2967
2970
2968 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2971 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2969 assert_tag 'span', :content => /testfile.txt/
2972 assert_tag 'span', :content => /testfile.txt/
2970 end
2973 end
2971
2974
2972 def test_put_update_with_failure_should_keep_saved_attachments
2975 def test_put_update_with_failure_should_keep_saved_attachments
2973 set_tmp_attachments_directory
2976 set_tmp_attachments_directory
2974 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2977 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2975 @request.session[:user_id] = 2
2978 @request.session[:user_id] = 2
2976
2979
2977 assert_no_difference 'Journal.count' do
2980 assert_no_difference 'Journal.count' do
2978 assert_no_difference 'Attachment.count' do
2981 assert_no_difference 'Attachment.count' do
2979 put :update, :id => 1,
2982 put :update, :id => 1,
2980 :issue => { :subject => '' },
2983 :issue => { :subject => '' },
2981 :attachments => {'p0' => {'token' => attachment.token}}
2984 :attachments => {'p0' => {'token' => attachment.token}}
2982 assert_response :success
2985 assert_response :success
2983 assert_template 'edit'
2986 assert_template 'edit'
2984 end
2987 end
2985 end
2988 end
2986
2989
2987 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2990 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2988 assert_tag 'span', :content => /testfile.txt/
2991 assert_tag 'span', :content => /testfile.txt/
2989 end
2992 end
2990
2993
2991 def test_put_update_should_attach_saved_attachments
2994 def test_put_update_should_attach_saved_attachments
2992 set_tmp_attachments_directory
2995 set_tmp_attachments_directory
2993 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2996 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2994 @request.session[:user_id] = 2
2997 @request.session[:user_id] = 2
2995
2998
2996 assert_difference 'Journal.count' do
2999 assert_difference 'Journal.count' do
2997 assert_difference 'JournalDetail.count' do
3000 assert_difference 'JournalDetail.count' do
2998 assert_no_difference 'Attachment.count' do
3001 assert_no_difference 'Attachment.count' do
2999 put :update, :id => 1,
3002 put :update, :id => 1,
3000 :issue => {:notes => 'Attachment added'},
3003 :issue => {:notes => 'Attachment added'},
3001 :attachments => {'p0' => {'token' => attachment.token}}
3004 :attachments => {'p0' => {'token' => attachment.token}}
3002 assert_redirected_to '/issues/1'
3005 assert_redirected_to '/issues/1'
3003 end
3006 end
3004 end
3007 end
3005 end
3008 end
3006
3009
3007 attachment.reload
3010 attachment.reload
3008 assert_equal Issue.find(1), attachment.container
3011 assert_equal Issue.find(1), attachment.container
3009
3012
3010 journal = Journal.first(:order => 'id DESC')
3013 journal = Journal.first(:order => 'id DESC')
3011 assert_equal 1, journal.details.size
3014 assert_equal 1, journal.details.size
3012 assert_equal 'testfile.txt', journal.details.first.value
3015 assert_equal 'testfile.txt', journal.details.first.value
3013 end
3016 end
3014
3017
3015 def test_put_update_with_attachment_that_fails_to_save
3018 def test_put_update_with_attachment_that_fails_to_save
3016 set_tmp_attachments_directory
3019 set_tmp_attachments_directory
3017
3020
3018 # Delete all fixtured journals, a race condition can occur causing the wrong
3021 # Delete all fixtured journals, a race condition can occur causing the wrong
3019 # journal to get fetched in the next find.
3022 # journal to get fetched in the next find.
3020 Journal.delete_all
3023 Journal.delete_all
3021
3024
3022 # Mock out the unsaved attachment
3025 # Mock out the unsaved attachment
3023 Attachment.any_instance.stubs(:create).returns(Attachment.new)
3026 Attachment.any_instance.stubs(:create).returns(Attachment.new)
3024
3027
3025 # anonymous user
3028 # anonymous user
3026 put :update,
3029 put :update,
3027 :id => 1,
3030 :id => 1,
3028 :issue => {:notes => ''},
3031 :issue => {:notes => ''},
3029 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
3032 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
3030 assert_redirected_to :action => 'show', :id => '1'
3033 assert_redirected_to :action => 'show', :id => '1'
3031 assert_equal '1 file(s) could not be saved.', flash[:warning]
3034 assert_equal '1 file(s) could not be saved.', flash[:warning]
3032 end
3035 end
3033
3036
3034 def test_put_update_with_no_change
3037 def test_put_update_with_no_change
3035 issue = Issue.find(1)
3038 issue = Issue.find(1)
3036 issue.journals.clear
3039 issue.journals.clear
3037 ActionMailer::Base.deliveries.clear
3040 ActionMailer::Base.deliveries.clear
3038
3041
3039 put :update,
3042 put :update,
3040 :id => 1,
3043 :id => 1,
3041 :issue => {:notes => ''}
3044 :issue => {:notes => ''}
3042 assert_redirected_to :action => 'show', :id => '1'
3045 assert_redirected_to :action => 'show', :id => '1'
3043
3046
3044 issue.reload
3047 issue.reload
3045 assert issue.journals.empty?
3048 assert issue.journals.empty?
3046 # No email should be sent
3049 # No email should be sent
3047 assert ActionMailer::Base.deliveries.empty?
3050 assert ActionMailer::Base.deliveries.empty?
3048 end
3051 end
3049
3052
3050 def test_put_update_should_send_a_notification
3053 def test_put_update_should_send_a_notification
3051 @request.session[:user_id] = 2
3054 @request.session[:user_id] = 2
3052 ActionMailer::Base.deliveries.clear
3055 ActionMailer::Base.deliveries.clear
3053 issue = Issue.find(1)
3056 issue = Issue.find(1)
3054 old_subject = issue.subject
3057 old_subject = issue.subject
3055 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
3058 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
3056
3059
3057 put :update, :id => 1, :issue => {:subject => new_subject,
3060 put :update, :id => 1, :issue => {:subject => new_subject,
3058 :priority_id => '6',
3061 :priority_id => '6',
3059 :category_id => '1' # no change
3062 :category_id => '1' # no change
3060 }
3063 }
3061 assert_equal 1, ActionMailer::Base.deliveries.size
3064 assert_equal 1, ActionMailer::Base.deliveries.size
3062 end
3065 end
3063
3066
3064 def test_put_update_with_invalid_spent_time_hours_only
3067 def test_put_update_with_invalid_spent_time_hours_only
3065 @request.session[:user_id] = 2
3068 @request.session[:user_id] = 2
3066 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
3069 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
3067
3070
3068 assert_no_difference('Journal.count') do
3071 assert_no_difference('Journal.count') do
3069 put :update,
3072 put :update,
3070 :id => 1,
3073 :id => 1,
3071 :issue => {:notes => notes},
3074 :issue => {:notes => notes},
3072 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
3075 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
3073 end
3076 end
3074 assert_response :success
3077 assert_response :success
3075 assert_template 'edit'
3078 assert_template 'edit'
3076
3079
3077 assert_error_tag :descendant => {:content => /Activity can&#x27;t be blank/}
3080 assert_error_tag :descendant => {:content => /Activity can&#x27;t be blank/}
3078 assert_tag :textarea, :attributes => { :name => 'issue[notes]' }, :content => "\n"+notes
3081 assert_tag :textarea, :attributes => { :name => 'issue[notes]' }, :content => "\n"+notes
3079 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
3082 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
3080 end
3083 end
3081
3084
3082 def test_put_update_with_invalid_spent_time_comments_only
3085 def test_put_update_with_invalid_spent_time_comments_only
3083 @request.session[:user_id] = 2
3086 @request.session[:user_id] = 2
3084 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
3087 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
3085
3088
3086 assert_no_difference('Journal.count') do
3089 assert_no_difference('Journal.count') do
3087 put :update,
3090 put :update,
3088 :id => 1,
3091 :id => 1,
3089 :issue => {:notes => notes},
3092 :issue => {:notes => notes},
3090 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
3093 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
3091 end
3094 end
3092 assert_response :success
3095 assert_response :success
3093 assert_template 'edit'
3096 assert_template 'edit'
3094
3097
3095 assert_error_tag :descendant => {:content => /Activity can&#x27;t be blank/}
3098 assert_error_tag :descendant => {:content => /Activity can&#x27;t be blank/}
3096 assert_error_tag :descendant => {:content => /Hours can&#x27;t be blank/}
3099 assert_error_tag :descendant => {:content => /Hours can&#x27;t be blank/}
3097 assert_tag :textarea, :attributes => { :name => 'issue[notes]' }, :content => "\n"+notes
3100 assert_tag :textarea, :attributes => { :name => 'issue[notes]' }, :content => "\n"+notes
3098 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => "this is my comment" }
3101 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => "this is my comment" }
3099 end
3102 end
3100
3103
3101 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
3104 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
3102 issue = Issue.find(2)
3105 issue = Issue.find(2)
3103 @request.session[:user_id] = 2
3106 @request.session[:user_id] = 2
3104
3107
3105 put :update,
3108 put :update,
3106 :id => issue.id,
3109 :id => issue.id,
3107 :issue => {
3110 :issue => {
3108 :fixed_version_id => 4
3111 :fixed_version_id => 4
3109 }
3112 }
3110
3113
3111 assert_response :redirect
3114 assert_response :redirect
3112 issue.reload
3115 issue.reload
3113 assert_equal 4, issue.fixed_version_id
3116 assert_equal 4, issue.fixed_version_id
3114 assert_not_equal issue.project_id, issue.fixed_version.project_id
3117 assert_not_equal issue.project_id, issue.fixed_version.project_id
3115 end
3118 end
3116
3119
3117 def test_put_update_should_redirect_back_using_the_back_url_parameter
3120 def test_put_update_should_redirect_back_using_the_back_url_parameter
3118 issue = Issue.find(2)
3121 issue = Issue.find(2)
3119 @request.session[:user_id] = 2
3122 @request.session[:user_id] = 2
3120
3123
3121 put :update,
3124 put :update,
3122 :id => issue.id,
3125 :id => issue.id,
3123 :issue => {
3126 :issue => {
3124 :fixed_version_id => 4
3127 :fixed_version_id => 4
3125 },
3128 },
3126 :back_url => '/issues'
3129 :back_url => '/issues'
3127
3130
3128 assert_response :redirect
3131 assert_response :redirect
3129 assert_redirected_to '/issues'
3132 assert_redirected_to '/issues'
3130 end
3133 end
3131
3134
3132 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
3135 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
3133 issue = Issue.find(2)
3136 issue = Issue.find(2)
3134 @request.session[:user_id] = 2
3137 @request.session[:user_id] = 2
3135
3138
3136 put :update,
3139 put :update,
3137 :id => issue.id,
3140 :id => issue.id,
3138 :issue => {
3141 :issue => {
3139 :fixed_version_id => 4
3142 :fixed_version_id => 4
3140 },
3143 },
3141 :back_url => 'http://google.com'
3144 :back_url => 'http://google.com'
3142
3145
3143 assert_response :redirect
3146 assert_response :redirect
3144 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
3147 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
3145 end
3148 end
3146
3149
3147 def test_get_bulk_edit
3150 def test_get_bulk_edit
3148 @request.session[:user_id] = 2
3151 @request.session[:user_id] = 2
3149 get :bulk_edit, :ids => [1, 2]
3152 get :bulk_edit, :ids => [1, 2]
3150 assert_response :success
3153 assert_response :success
3151 assert_template 'bulk_edit'
3154 assert_template 'bulk_edit'
3152
3155
3153 assert_tag :select, :attributes => {:name => 'issue[project_id]'}
3156 assert_tag :select, :attributes => {:name => 'issue[project_id]'}
3154 assert_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
3157 assert_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
3155
3158
3156 # Project specific custom field, date type
3159 # Project specific custom field, date type
3157 field = CustomField.find(9)
3160 field = CustomField.find(9)
3158 assert !field.is_for_all?
3161 assert !field.is_for_all?
3159 assert_equal 'date', field.field_format
3162 assert_equal 'date', field.field_format
3160 assert_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
3163 assert_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
3161
3164
3162 # System wide custom field
3165 # System wide custom field
3163 assert CustomField.find(1).is_for_all?
3166 assert CustomField.find(1).is_for_all?
3164 assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'}
3167 assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'}
3165
3168
3166 # Be sure we don't display inactive IssuePriorities
3169 # Be sure we don't display inactive IssuePriorities
3167 assert ! IssuePriority.find(15).active?
3170 assert ! IssuePriority.find(15).active?
3168 assert_no_tag :option, :attributes => {:value => '15'},
3171 assert_no_tag :option, :attributes => {:value => '15'},
3169 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
3172 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
3170 end
3173 end
3171
3174
3172 def test_get_bulk_edit_on_different_projects
3175 def test_get_bulk_edit_on_different_projects
3173 @request.session[:user_id] = 2
3176 @request.session[:user_id] = 2
3174 get :bulk_edit, :ids => [1, 2, 6]
3177 get :bulk_edit, :ids => [1, 2, 6]
3175 assert_response :success
3178 assert_response :success
3176 assert_template 'bulk_edit'
3179 assert_template 'bulk_edit'
3177
3180
3178 # Can not set issues from different projects as children of an issue
3181 # Can not set issues from different projects as children of an issue
3179 assert_no_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
3182 assert_no_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
3180
3183
3181 # Project specific custom field, date type
3184 # Project specific custom field, date type
3182 field = CustomField.find(9)
3185 field = CustomField.find(9)
3183 assert !field.is_for_all?
3186 assert !field.is_for_all?
3184 assert !field.project_ids.include?(Issue.find(6).project_id)
3187 assert !field.project_ids.include?(Issue.find(6).project_id)
3185 assert_no_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
3188 assert_no_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
3186 end
3189 end
3187
3190
3188 def test_get_bulk_edit_with_user_custom_field
3191 def test_get_bulk_edit_with_user_custom_field
3189 field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true)
3192 field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true)
3190
3193
3191 @request.session[:user_id] = 2
3194 @request.session[:user_id] = 2
3192 get :bulk_edit, :ids => [1, 2]
3195 get :bulk_edit, :ids => [1, 2]
3193 assert_response :success
3196 assert_response :success
3194 assert_template 'bulk_edit'
3197 assert_template 'bulk_edit'
3195
3198
3196 assert_tag :select,
3199 assert_tag :select,
3197 :attributes => {:name => "issue[custom_field_values][#{field.id}]", :class => 'user_cf'},
3200 :attributes => {:name => "issue[custom_field_values][#{field.id}]", :class => 'user_cf'},
3198 :children => {
3201 :children => {
3199 :only => {:tag => 'option'},
3202 :only => {:tag => 'option'},
3200 :count => Project.find(1).users.count + 2 # "no change" + "none" options
3203 :count => Project.find(1).users.count + 2 # "no change" + "none" options
3201 }
3204 }
3202 end
3205 end
3203
3206
3204 def test_get_bulk_edit_with_version_custom_field
3207 def test_get_bulk_edit_with_version_custom_field
3205 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true)
3208 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true)
3206
3209
3207 @request.session[:user_id] = 2
3210 @request.session[:user_id] = 2
3208 get :bulk_edit, :ids => [1, 2]
3211 get :bulk_edit, :ids => [1, 2]
3209 assert_response :success
3212 assert_response :success
3210 assert_template 'bulk_edit'
3213 assert_template 'bulk_edit'
3211
3214
3212 assert_tag :select,
3215 assert_tag :select,
3213 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
3216 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
3214 :children => {
3217 :children => {
3215 :only => {:tag => 'option'},
3218 :only => {:tag => 'option'},
3216 :count => Project.find(1).shared_versions.count + 2 # "no change" + "none" options
3219 :count => Project.find(1).shared_versions.count + 2 # "no change" + "none" options
3217 }
3220 }
3218 end
3221 end
3219
3222
3220 def test_get_bulk_edit_with_multi_custom_field
3223 def test_get_bulk_edit_with_multi_custom_field
3221 field = CustomField.find(1)
3224 field = CustomField.find(1)
3222 field.update_attribute :multiple, true
3225 field.update_attribute :multiple, true
3223
3226
3224 @request.session[:user_id] = 2
3227 @request.session[:user_id] = 2
3225 get :bulk_edit, :ids => [1, 2]
3228 get :bulk_edit, :ids => [1, 2]
3226 assert_response :success
3229 assert_response :success
3227 assert_template 'bulk_edit'
3230 assert_template 'bulk_edit'
3228
3231
3229 assert_tag :select,
3232 assert_tag :select,
3230 :attributes => {:name => "issue[custom_field_values][1][]"},
3233 :attributes => {:name => "issue[custom_field_values][1][]"},
3231 :children => {
3234 :children => {
3232 :only => {:tag => 'option'},
3235 :only => {:tag => 'option'},
3233 :count => field.possible_values.size + 1 # "none" options
3236 :count => field.possible_values.size + 1 # "none" options
3234 }
3237 }
3235 end
3238 end
3236
3239
3237 def test_bulk_edit_should_only_propose_statuses_allowed_for_all_issues
3240 def test_bulk_edit_should_only_propose_statuses_allowed_for_all_issues
3238 WorkflowTransition.delete_all
3241 WorkflowTransition.delete_all
3239 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 1)
3242 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 1)
3240 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
3243 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
3241 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
3244 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
3242 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
3245 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
3243 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3)
3246 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3)
3244 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
3247 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
3245 @request.session[:user_id] = 2
3248 @request.session[:user_id] = 2
3246 get :bulk_edit, :ids => [1, 2]
3249 get :bulk_edit, :ids => [1, 2]
3247
3250
3248 assert_response :success
3251 assert_response :success
3249 statuses = assigns(:available_statuses)
3252 statuses = assigns(:available_statuses)
3250 assert_not_nil statuses
3253 assert_not_nil statuses
3251 assert_equal [1, 3], statuses.map(&:id).sort
3254 assert_equal [1, 3], statuses.map(&:id).sort
3252
3255
3253 assert_tag 'select', :attributes => {:name => 'issue[status_id]'},
3256 assert_tag 'select', :attributes => {:name => 'issue[status_id]'},
3254 :children => {:count => 3} # 2 statuses + "no change" option
3257 :children => {:count => 3} # 2 statuses + "no change" option
3255 end
3258 end
3256
3259
3257 def test_bulk_edit_should_propose_target_project_open_shared_versions
3260 def test_bulk_edit_should_propose_target_project_open_shared_versions
3258 @request.session[:user_id] = 2
3261 @request.session[:user_id] = 2
3259 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3262 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3260 assert_response :success
3263 assert_response :success
3261 assert_template 'bulk_edit'
3264 assert_template 'bulk_edit'
3262 assert_equal Project.find(1).shared_versions.open.all.sort, assigns(:versions).sort
3265 assert_equal Project.find(1).shared_versions.open.all.sort, assigns(:versions).sort
3263 assert_tag 'select',
3266 assert_tag 'select',
3264 :attributes => {:name => 'issue[fixed_version_id]'},
3267 :attributes => {:name => 'issue[fixed_version_id]'},
3265 :descendant => {:tag => 'option', :content => '2.0'}
3268 :descendant => {:tag => 'option', :content => '2.0'}
3266 end
3269 end
3267
3270
3268 def test_bulk_edit_should_propose_target_project_categories
3271 def test_bulk_edit_should_propose_target_project_categories
3269 @request.session[:user_id] = 2
3272 @request.session[:user_id] = 2
3270 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3273 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3271 assert_response :success
3274 assert_response :success
3272 assert_template 'bulk_edit'
3275 assert_template 'bulk_edit'
3273 assert_equal Project.find(1).issue_categories.sort, assigns(:categories).sort
3276 assert_equal Project.find(1).issue_categories.sort, assigns(:categories).sort
3274 assert_tag 'select',
3277 assert_tag 'select',
3275 :attributes => {:name => 'issue[category_id]'},
3278 :attributes => {:name => 'issue[category_id]'},
3276 :descendant => {:tag => 'option', :content => 'Recipes'}
3279 :descendant => {:tag => 'option', :content => 'Recipes'}
3277 end
3280 end
3278
3281
3279 def test_bulk_update
3282 def test_bulk_update
3280 @request.session[:user_id] = 2
3283 @request.session[:user_id] = 2
3281 # update issues priority
3284 # update issues priority
3282 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
3285 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
3283 :issue => {:priority_id => 7,
3286 :issue => {:priority_id => 7,
3284 :assigned_to_id => '',
3287 :assigned_to_id => '',
3285 :custom_field_values => {'2' => ''}}
3288 :custom_field_values => {'2' => ''}}
3286
3289
3287 assert_response 302
3290 assert_response 302
3288 # check that the issues were updated
3291 # check that the issues were updated
3289 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
3292 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
3290
3293
3291 issue = Issue.find(1)
3294 issue = Issue.find(1)
3292 journal = issue.journals.find(:first, :order => 'created_on DESC')
3295 journal = issue.journals.find(:first, :order => 'created_on DESC')
3293 assert_equal '125', issue.custom_value_for(2).value
3296 assert_equal '125', issue.custom_value_for(2).value
3294 assert_equal 'Bulk editing', journal.notes
3297 assert_equal 'Bulk editing', journal.notes
3295 assert_equal 1, journal.details.size
3298 assert_equal 1, journal.details.size
3296 end
3299 end
3297
3300
3298 def test_bulk_update_with_group_assignee
3301 def test_bulk_update_with_group_assignee
3299 group = Group.find(11)
3302 group = Group.find(11)
3300 project = Project.find(1)
3303 project = Project.find(1)
3301 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
3304 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
3302
3305
3303 @request.session[:user_id] = 2
3306 @request.session[:user_id] = 2
3304 # update issues assignee
3307 # update issues assignee
3305 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
3308 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
3306 :issue => {:priority_id => '',
3309 :issue => {:priority_id => '',
3307 :assigned_to_id => group.id,
3310 :assigned_to_id => group.id,
3308 :custom_field_values => {'2' => ''}}
3311 :custom_field_values => {'2' => ''}}
3309
3312
3310 assert_response 302
3313 assert_response 302
3311 assert_equal [group, group], Issue.find_all_by_id([1, 2]).collect {|i| i.assigned_to}
3314 assert_equal [group, group], Issue.find_all_by_id([1, 2]).collect {|i| i.assigned_to}
3312 end
3315 end
3313
3316
3314 def test_bulk_update_on_different_projects
3317 def test_bulk_update_on_different_projects
3315 @request.session[:user_id] = 2
3318 @request.session[:user_id] = 2
3316 # update issues priority
3319 # update issues priority
3317 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
3320 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
3318 :issue => {:priority_id => 7,
3321 :issue => {:priority_id => 7,
3319 :assigned_to_id => '',
3322 :assigned_to_id => '',
3320 :custom_field_values => {'2' => ''}}
3323 :custom_field_values => {'2' => ''}}
3321
3324
3322 assert_response 302
3325 assert_response 302
3323 # check that the issues were updated
3326 # check that the issues were updated
3324 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
3327 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
3325
3328
3326 issue = Issue.find(1)
3329 issue = Issue.find(1)
3327 journal = issue.journals.find(:first, :order => 'created_on DESC')
3330 journal = issue.journals.find(:first, :order => 'created_on DESC')
3328 assert_equal '125', issue.custom_value_for(2).value
3331 assert_equal '125', issue.custom_value_for(2).value
3329 assert_equal 'Bulk editing', journal.notes
3332 assert_equal 'Bulk editing', journal.notes
3330 assert_equal 1, journal.details.size
3333 assert_equal 1, journal.details.size
3331 end
3334 end
3332
3335
3333 def test_bulk_update_on_different_projects_without_rights
3336 def test_bulk_update_on_different_projects_without_rights
3334 @request.session[:user_id] = 3
3337 @request.session[:user_id] = 3
3335 user = User.find(3)
3338 user = User.find(3)
3336 action = { :controller => "issues", :action => "bulk_update" }
3339 action = { :controller => "issues", :action => "bulk_update" }
3337 assert user.allowed_to?(action, Issue.find(1).project)
3340 assert user.allowed_to?(action, Issue.find(1).project)
3338 assert ! user.allowed_to?(action, Issue.find(6).project)
3341 assert ! user.allowed_to?(action, Issue.find(6).project)
3339 post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
3342 post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
3340 :issue => {:priority_id => 7,
3343 :issue => {:priority_id => 7,
3341 :assigned_to_id => '',
3344 :assigned_to_id => '',
3342 :custom_field_values => {'2' => ''}}
3345 :custom_field_values => {'2' => ''}}
3343 assert_response 403
3346 assert_response 403
3344 assert_not_equal "Bulk should fail", Journal.last.notes
3347 assert_not_equal "Bulk should fail", Journal.last.notes
3345 end
3348 end
3346
3349
3347 def test_bullk_update_should_send_a_notification
3350 def test_bullk_update_should_send_a_notification
3348 @request.session[:user_id] = 2
3351 @request.session[:user_id] = 2
3349 ActionMailer::Base.deliveries.clear
3352 ActionMailer::Base.deliveries.clear
3350 post(:bulk_update,
3353 post(:bulk_update,
3351 {
3354 {
3352 :ids => [1, 2],
3355 :ids => [1, 2],
3353 :notes => 'Bulk editing',
3356 :notes => 'Bulk editing',
3354 :issue => {
3357 :issue => {
3355 :priority_id => 7,
3358 :priority_id => 7,
3356 :assigned_to_id => '',
3359 :assigned_to_id => '',
3357 :custom_field_values => {'2' => ''}
3360 :custom_field_values => {'2' => ''}
3358 }
3361 }
3359 })
3362 })
3360
3363
3361 assert_response 302
3364 assert_response 302
3362 assert_equal 2, ActionMailer::Base.deliveries.size
3365 assert_equal 2, ActionMailer::Base.deliveries.size
3363 end
3366 end
3364
3367
3365 def test_bulk_update_project
3368 def test_bulk_update_project
3366 @request.session[:user_id] = 2
3369 @request.session[:user_id] = 2
3367 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}
3370 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}
3368 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3371 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3369 # Issues moved to project 2
3372 # Issues moved to project 2
3370 assert_equal 2, Issue.find(1).project_id
3373 assert_equal 2, Issue.find(1).project_id
3371 assert_equal 2, Issue.find(2).project_id
3374 assert_equal 2, Issue.find(2).project_id
3372 # No tracker change
3375 # No tracker change
3373 assert_equal 1, Issue.find(1).tracker_id
3376 assert_equal 1, Issue.find(1).tracker_id
3374 assert_equal 2, Issue.find(2).tracker_id
3377 assert_equal 2, Issue.find(2).tracker_id
3375 end
3378 end
3376
3379
3377 def test_bulk_update_project_on_single_issue_should_follow_when_needed
3380 def test_bulk_update_project_on_single_issue_should_follow_when_needed
3378 @request.session[:user_id] = 2
3381 @request.session[:user_id] = 2
3379 post :bulk_update, :id => 1, :issue => {:project_id => '2'}, :follow => '1'
3382 post :bulk_update, :id => 1, :issue => {:project_id => '2'}, :follow => '1'
3380 assert_redirected_to '/issues/1'
3383 assert_redirected_to '/issues/1'
3381 end
3384 end
3382
3385
3383 def test_bulk_update_project_on_multiple_issues_should_follow_when_needed
3386 def test_bulk_update_project_on_multiple_issues_should_follow_when_needed
3384 @request.session[:user_id] = 2
3387 @request.session[:user_id] = 2
3385 post :bulk_update, :id => [1, 2], :issue => {:project_id => '2'}, :follow => '1'
3388 post :bulk_update, :id => [1, 2], :issue => {:project_id => '2'}, :follow => '1'
3386 assert_redirected_to '/projects/onlinestore/issues'
3389 assert_redirected_to '/projects/onlinestore/issues'
3387 end
3390 end
3388
3391
3389 def test_bulk_update_tracker
3392 def test_bulk_update_tracker
3390 @request.session[:user_id] = 2
3393 @request.session[:user_id] = 2
3391 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2'}
3394 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2'}
3392 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3395 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3393 assert_equal 2, Issue.find(1).tracker_id
3396 assert_equal 2, Issue.find(1).tracker_id
3394 assert_equal 2, Issue.find(2).tracker_id
3397 assert_equal 2, Issue.find(2).tracker_id
3395 end
3398 end
3396
3399
3397 def test_bulk_update_status
3400 def test_bulk_update_status
3398 @request.session[:user_id] = 2
3401 @request.session[:user_id] = 2
3399 # update issues priority
3402 # update issues priority
3400 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
3403 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
3401 :issue => {:priority_id => '',
3404 :issue => {:priority_id => '',
3402 :assigned_to_id => '',
3405 :assigned_to_id => '',
3403 :status_id => '5'}
3406 :status_id => '5'}
3404
3407
3405 assert_response 302
3408 assert_response 302
3406 issue = Issue.find(1)
3409 issue = Issue.find(1)
3407 assert issue.closed?
3410 assert issue.closed?
3408 end
3411 end
3409
3412
3410 def test_bulk_update_priority
3413 def test_bulk_update_priority
3411 @request.session[:user_id] = 2
3414 @request.session[:user_id] = 2
3412 post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
3415 post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
3413
3416
3414 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3417 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3415 assert_equal 6, Issue.find(1).priority_id
3418 assert_equal 6, Issue.find(1).priority_id
3416 assert_equal 6, Issue.find(2).priority_id
3419 assert_equal 6, Issue.find(2).priority_id
3417 end
3420 end
3418
3421
3419 def test_bulk_update_with_notes
3422 def test_bulk_update_with_notes
3420 @request.session[:user_id] = 2
3423 @request.session[:user_id] = 2
3421 post :bulk_update, :ids => [1, 2], :notes => 'Moving two issues'
3424 post :bulk_update, :ids => [1, 2], :notes => 'Moving two issues'
3422
3425
3423 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3426 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3424 assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
3427 assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
3425 assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
3428 assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
3426 end
3429 end
3427
3430
3428 def test_bulk_update_parent_id
3431 def test_bulk_update_parent_id
3429 @request.session[:user_id] = 2
3432 @request.session[:user_id] = 2
3430 post :bulk_update, :ids => [1, 3],
3433 post :bulk_update, :ids => [1, 3],
3431 :notes => 'Bulk editing parent',
3434 :notes => 'Bulk editing parent',
3432 :issue => {:priority_id => '', :assigned_to_id => '', :status_id => '', :parent_issue_id => '2'}
3435 :issue => {:priority_id => '', :assigned_to_id => '', :status_id => '', :parent_issue_id => '2'}
3433
3436
3434 assert_response 302
3437 assert_response 302
3435 parent = Issue.find(2)
3438 parent = Issue.find(2)
3436 assert_equal parent.id, Issue.find(1).parent_id
3439 assert_equal parent.id, Issue.find(1).parent_id
3437 assert_equal parent.id, Issue.find(3).parent_id
3440 assert_equal parent.id, Issue.find(3).parent_id
3438 assert_equal [1, 3], parent.children.collect(&:id).sort
3441 assert_equal [1, 3], parent.children.collect(&:id).sort
3439 end
3442 end
3440
3443
3441 def test_bulk_update_custom_field
3444 def test_bulk_update_custom_field
3442 @request.session[:user_id] = 2
3445 @request.session[:user_id] = 2
3443 # update issues priority
3446 # update issues priority
3444 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
3447 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
3445 :issue => {:priority_id => '',
3448 :issue => {:priority_id => '',
3446 :assigned_to_id => '',
3449 :assigned_to_id => '',
3447 :custom_field_values => {'2' => '777'}}
3450 :custom_field_values => {'2' => '777'}}
3448
3451
3449 assert_response 302
3452 assert_response 302
3450
3453
3451 issue = Issue.find(1)
3454 issue = Issue.find(1)
3452 journal = issue.journals.find(:first, :order => 'created_on DESC')
3455 journal = issue.journals.find(:first, :order => 'created_on DESC')
3453 assert_equal '777', issue.custom_value_for(2).value
3456 assert_equal '777', issue.custom_value_for(2).value
3454 assert_equal 1, journal.details.size
3457 assert_equal 1, journal.details.size
3455 assert_equal '125', journal.details.first.old_value
3458 assert_equal '125', journal.details.first.old_value
3456 assert_equal '777', journal.details.first.value
3459 assert_equal '777', journal.details.first.value
3457 end
3460 end
3458
3461
3459 def test_bulk_update_custom_field_to_blank
3462 def test_bulk_update_custom_field_to_blank
3460 @request.session[:user_id] = 2
3463 @request.session[:user_id] = 2
3461 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing custom field',
3464 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing custom field',
3462 :issue => {:priority_id => '',
3465 :issue => {:priority_id => '',
3463 :assigned_to_id => '',
3466 :assigned_to_id => '',
3464 :custom_field_values => {'1' => '__none__'}}
3467 :custom_field_values => {'1' => '__none__'}}
3465 assert_response 302
3468 assert_response 302
3466 assert_equal '', Issue.find(1).custom_field_value(1)
3469 assert_equal '', Issue.find(1).custom_field_value(1)
3467 assert_equal '', Issue.find(3).custom_field_value(1)
3470 assert_equal '', Issue.find(3).custom_field_value(1)
3468 end
3471 end
3469
3472
3470 def test_bulk_update_multi_custom_field
3473 def test_bulk_update_multi_custom_field
3471 field = CustomField.find(1)
3474 field = CustomField.find(1)
3472 field.update_attribute :multiple, true
3475 field.update_attribute :multiple, true
3473
3476
3474 @request.session[:user_id] = 2
3477 @request.session[:user_id] = 2
3475 post :bulk_update, :ids => [1, 2, 3], :notes => 'Bulk editing multi custom field',
3478 post :bulk_update, :ids => [1, 2, 3], :notes => 'Bulk editing multi custom field',
3476 :issue => {:priority_id => '',
3479 :issue => {:priority_id => '',
3477 :assigned_to_id => '',
3480 :assigned_to_id => '',
3478 :custom_field_values => {'1' => ['MySQL', 'Oracle']}}
3481 :custom_field_values => {'1' => ['MySQL', 'Oracle']}}
3479
3482
3480 assert_response 302
3483 assert_response 302
3481
3484
3482 assert_equal ['MySQL', 'Oracle'], Issue.find(1).custom_field_value(1).sort
3485 assert_equal ['MySQL', 'Oracle'], Issue.find(1).custom_field_value(1).sort
3483 assert_equal ['MySQL', 'Oracle'], Issue.find(3).custom_field_value(1).sort
3486 assert_equal ['MySQL', 'Oracle'], Issue.find(3).custom_field_value(1).sort
3484 # the custom field is not associated with the issue tracker
3487 # the custom field is not associated with the issue tracker
3485 assert_nil Issue.find(2).custom_field_value(1)
3488 assert_nil Issue.find(2).custom_field_value(1)
3486 end
3489 end
3487
3490
3488 def test_bulk_update_multi_custom_field_to_blank
3491 def test_bulk_update_multi_custom_field_to_blank
3489 field = CustomField.find(1)
3492 field = CustomField.find(1)
3490 field.update_attribute :multiple, true
3493 field.update_attribute :multiple, true
3491
3494
3492 @request.session[:user_id] = 2
3495 @request.session[:user_id] = 2
3493 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing multi custom field',
3496 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing multi custom field',
3494 :issue => {:priority_id => '',
3497 :issue => {:priority_id => '',
3495 :assigned_to_id => '',
3498 :assigned_to_id => '',
3496 :custom_field_values => {'1' => ['__none__']}}
3499 :custom_field_values => {'1' => ['__none__']}}
3497 assert_response 302
3500 assert_response 302
3498 assert_equal [''], Issue.find(1).custom_field_value(1)
3501 assert_equal [''], Issue.find(1).custom_field_value(1)
3499 assert_equal [''], Issue.find(3).custom_field_value(1)
3502 assert_equal [''], Issue.find(3).custom_field_value(1)
3500 end
3503 end
3501
3504
3502 def test_bulk_update_unassign
3505 def test_bulk_update_unassign
3503 assert_not_nil Issue.find(2).assigned_to
3506 assert_not_nil Issue.find(2).assigned_to
3504 @request.session[:user_id] = 2
3507 @request.session[:user_id] = 2
3505 # unassign issues
3508 # unassign issues
3506 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
3509 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
3507 assert_response 302
3510 assert_response 302
3508 # check that the issues were updated
3511 # check that the issues were updated
3509 assert_nil Issue.find(2).assigned_to
3512 assert_nil Issue.find(2).assigned_to
3510 end
3513 end
3511
3514
3512 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
3515 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
3513 @request.session[:user_id] = 2
3516 @request.session[:user_id] = 2
3514
3517
3515 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
3518 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
3516
3519
3517 assert_response :redirect
3520 assert_response :redirect
3518 issues = Issue.find([1,2])
3521 issues = Issue.find([1,2])
3519 issues.each do |issue|
3522 issues.each do |issue|
3520 assert_equal 4, issue.fixed_version_id
3523 assert_equal 4, issue.fixed_version_id
3521 assert_not_equal issue.project_id, issue.fixed_version.project_id
3524 assert_not_equal issue.project_id, issue.fixed_version.project_id
3522 end
3525 end
3523 end
3526 end
3524
3527
3525 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
3528 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
3526 @request.session[:user_id] = 2
3529 @request.session[:user_id] = 2
3527 post :bulk_update, :ids => [1,2], :back_url => '/issues'
3530 post :bulk_update, :ids => [1,2], :back_url => '/issues'
3528
3531
3529 assert_response :redirect
3532 assert_response :redirect
3530 assert_redirected_to '/issues'
3533 assert_redirected_to '/issues'
3531 end
3534 end
3532
3535
3533 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
3536 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
3534 @request.session[:user_id] = 2
3537 @request.session[:user_id] = 2
3535 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
3538 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
3536
3539
3537 assert_response :redirect
3540 assert_response :redirect
3538 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
3541 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
3539 end
3542 end
3540
3543
3541 def test_bulk_update_with_failure_should_set_flash
3544 def test_bulk_update_with_failure_should_set_flash
3542 @request.session[:user_id] = 2
3545 @request.session[:user_id] = 2
3543 Issue.update_all("subject = ''", "id = 2") # Make it invalid
3546 Issue.update_all("subject = ''", "id = 2") # Make it invalid
3544 post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
3547 post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
3545
3548
3546 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3549 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3547 assert_equal 'Failed to save 1 issue(s) on 2 selected: #2.', flash[:error]
3550 assert_equal 'Failed to save 1 issue(s) on 2 selected: #2.', flash[:error]
3548 end
3551 end
3549
3552
3550 def test_get_bulk_copy
3553 def test_get_bulk_copy
3551 @request.session[:user_id] = 2
3554 @request.session[:user_id] = 2
3552 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
3555 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
3553 assert_response :success
3556 assert_response :success
3554 assert_template 'bulk_edit'
3557 assert_template 'bulk_edit'
3555
3558
3556 issues = assigns(:issues)
3559 issues = assigns(:issues)
3557 assert_not_nil issues
3560 assert_not_nil issues
3558 assert_equal [1, 2, 3], issues.map(&:id).sort
3561 assert_equal [1, 2, 3], issues.map(&:id).sort
3559
3562
3560 assert_select 'input[name=copy_attachments]'
3563 assert_select 'input[name=copy_attachments]'
3561 end
3564 end
3562
3565
3563 def test_bulk_copy_to_another_project
3566 def test_bulk_copy_to_another_project
3564 @request.session[:user_id] = 2
3567 @request.session[:user_id] = 2
3565 assert_difference 'Issue.count', 2 do
3568 assert_difference 'Issue.count', 2 do
3566 assert_no_difference 'Project.find(1).issues.count' do
3569 assert_no_difference 'Project.find(1).issues.count' do
3567 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}, :copy => '1'
3570 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}, :copy => '1'
3568 end
3571 end
3569 end
3572 end
3570 assert_redirected_to '/projects/ecookbook/issues'
3573 assert_redirected_to '/projects/ecookbook/issues'
3571
3574
3572 copies = Issue.all(:order => 'id DESC', :limit => issues.size)
3575 copies = Issue.all(:order => 'id DESC', :limit => issues.size)
3573 copies.each do |copy|
3576 copies.each do |copy|
3574 assert_equal 2, copy.project_id
3577 assert_equal 2, copy.project_id
3575 end
3578 end
3576 end
3579 end
3577
3580
3578 def test_bulk_copy_should_allow_not_changing_the_issue_attributes
3581 def test_bulk_copy_should_allow_not_changing_the_issue_attributes
3579 @request.session[:user_id] = 2
3582 @request.session[:user_id] = 2
3580 issues = [
3583 issues = [
3581 Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1, :priority_id => 2, :subject => 'issue 1', :author_id => 1, :assigned_to_id => nil),
3584 Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1, :priority_id => 2, :subject => 'issue 1', :author_id => 1, :assigned_to_id => nil),
3582 Issue.create!(:project_id => 2, :tracker_id => 3, :status_id => 2, :priority_id => 1, :subject => 'issue 2', :author_id => 2, :assigned_to_id => 3)
3585 Issue.create!(:project_id => 2, :tracker_id => 3, :status_id => 2, :priority_id => 1, :subject => 'issue 2', :author_id => 2, :assigned_to_id => 3)
3583 ]
3586 ]
3584
3587
3585 assert_difference 'Issue.count', issues.size do
3588 assert_difference 'Issue.count', issues.size do
3586 post :bulk_update, :ids => issues.map(&:id), :copy => '1',
3589 post :bulk_update, :ids => issues.map(&:id), :copy => '1',
3587 :issue => {
3590 :issue => {
3588 :project_id => '', :tracker_id => '', :assigned_to_id => '',
3591 :project_id => '', :tracker_id => '', :assigned_to_id => '',
3589 :status_id => '', :start_date => '', :due_date => ''
3592 :status_id => '', :start_date => '', :due_date => ''
3590 }
3593 }
3591 end
3594 end
3592
3595
3593 copies = Issue.all(:order => 'id DESC', :limit => issues.size)
3596 copies = Issue.all(:order => 'id DESC', :limit => issues.size)
3594 issues.each do |orig|
3597 issues.each do |orig|
3595 copy = copies.detect {|c| c.subject == orig.subject}
3598 copy = copies.detect {|c| c.subject == orig.subject}
3596 assert_not_nil copy
3599 assert_not_nil copy
3597 assert_equal orig.project_id, copy.project_id
3600 assert_equal orig.project_id, copy.project_id
3598 assert_equal orig.tracker_id, copy.tracker_id
3601 assert_equal orig.tracker_id, copy.tracker_id
3599 assert_equal orig.status_id, copy.status_id
3602 assert_equal orig.status_id, copy.status_id
3600 assert_equal orig.assigned_to_id, copy.assigned_to_id
3603 assert_equal orig.assigned_to_id, copy.assigned_to_id
3601 assert_equal orig.priority_id, copy.priority_id
3604 assert_equal orig.priority_id, copy.priority_id
3602 end
3605 end
3603 end
3606 end
3604
3607
3605 def test_bulk_copy_should_allow_changing_the_issue_attributes
3608 def test_bulk_copy_should_allow_changing_the_issue_attributes
3606 # Fixes random test failure with Mysql
3609 # Fixes random test failure with Mysql
3607 # where Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
3610 # where Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
3608 # doesn't return the expected results
3611 # doesn't return the expected results
3609 Issue.delete_all("project_id=2")
3612 Issue.delete_all("project_id=2")
3610
3613
3611 @request.session[:user_id] = 2
3614 @request.session[:user_id] = 2
3612 assert_difference 'Issue.count', 2 do
3615 assert_difference 'Issue.count', 2 do
3613 assert_no_difference 'Project.find(1).issues.count' do
3616 assert_no_difference 'Project.find(1).issues.count' do
3614 post :bulk_update, :ids => [1, 2], :copy => '1',
3617 post :bulk_update, :ids => [1, 2], :copy => '1',
3615 :issue => {
3618 :issue => {
3616 :project_id => '2', :tracker_id => '', :assigned_to_id => '4',
3619 :project_id => '2', :tracker_id => '', :assigned_to_id => '4',
3617 :status_id => '1', :start_date => '2009-12-01', :due_date => '2009-12-31'
3620 :status_id => '1', :start_date => '2009-12-01', :due_date => '2009-12-31'
3618 }
3621 }
3619 end
3622 end
3620 end
3623 end
3621
3624
3622 copied_issues = Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
3625 copied_issues = Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
3623 assert_equal 2, copied_issues.size
3626 assert_equal 2, copied_issues.size
3624 copied_issues.each do |issue|
3627 copied_issues.each do |issue|
3625 assert_equal 2, issue.project_id, "Project is incorrect"
3628 assert_equal 2, issue.project_id, "Project is incorrect"
3626 assert_equal 4, issue.assigned_to_id, "Assigned to is incorrect"
3629 assert_equal 4, issue.assigned_to_id, "Assigned to is incorrect"
3627 assert_equal 1, issue.status_id, "Status is incorrect"
3630 assert_equal 1, issue.status_id, "Status is incorrect"
3628 assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
3631 assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
3629 assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
3632 assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
3630 end
3633 end
3631 end
3634 end
3632
3635
3633 def test_bulk_copy_should_allow_adding_a_note
3636 def test_bulk_copy_should_allow_adding_a_note
3634 @request.session[:user_id] = 2
3637 @request.session[:user_id] = 2
3635 assert_difference 'Issue.count', 1 do
3638 assert_difference 'Issue.count', 1 do
3636 post :bulk_update, :ids => [1], :copy => '1',
3639 post :bulk_update, :ids => [1], :copy => '1',
3637 :notes => 'Copying one issue',
3640 :notes => 'Copying one issue',
3638 :issue => {
3641 :issue => {
3639 :project_id => '', :tracker_id => '', :assigned_to_id => '4',
3642 :project_id => '', :tracker_id => '', :assigned_to_id => '4',
3640 :status_id => '3', :start_date => '2009-12-01', :due_date => '2009-12-31'
3643 :status_id => '3', :start_date => '2009-12-01', :due_date => '2009-12-31'
3641 }
3644 }
3642 end
3645 end
3643
3646
3644 issue = Issue.first(:order => 'id DESC')
3647 issue = Issue.first(:order => 'id DESC')
3645 assert_equal 1, issue.journals.size
3648 assert_equal 1, issue.journals.size
3646 journal = issue.journals.first
3649 journal = issue.journals.first
3647 assert_equal 0, journal.details.size
3650 assert_equal 0, journal.details.size
3648 assert_equal 'Copying one issue', journal.notes
3651 assert_equal 'Copying one issue', journal.notes
3649 end
3652 end
3650
3653
3651 def test_bulk_copy_should_allow_not_copying_the_attachments
3654 def test_bulk_copy_should_allow_not_copying_the_attachments
3652 attachment_count = Issue.find(3).attachments.size
3655 attachment_count = Issue.find(3).attachments.size
3653 assert attachment_count > 0
3656 assert attachment_count > 0
3654 @request.session[:user_id] = 2
3657 @request.session[:user_id] = 2
3655
3658
3656 assert_difference 'Issue.count', 1 do
3659 assert_difference 'Issue.count', 1 do
3657 assert_no_difference 'Attachment.count' do
3660 assert_no_difference 'Attachment.count' do
3658 post :bulk_update, :ids => [3], :copy => '1',
3661 post :bulk_update, :ids => [3], :copy => '1',
3659 :issue => {
3662 :issue => {
3660 :project_id => ''
3663 :project_id => ''
3661 }
3664 }
3662 end
3665 end
3663 end
3666 end
3664 end
3667 end
3665
3668
3666 def test_bulk_copy_should_allow_copying_the_attachments
3669 def test_bulk_copy_should_allow_copying_the_attachments
3667 attachment_count = Issue.find(3).attachments.size
3670 attachment_count = Issue.find(3).attachments.size
3668 assert attachment_count > 0
3671 assert attachment_count > 0
3669 @request.session[:user_id] = 2
3672 @request.session[:user_id] = 2
3670
3673
3671 assert_difference 'Issue.count', 1 do
3674 assert_difference 'Issue.count', 1 do
3672 assert_difference 'Attachment.count', attachment_count do
3675 assert_difference 'Attachment.count', attachment_count do
3673 post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '1',
3676 post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '1',
3674 :issue => {
3677 :issue => {
3675 :project_id => ''
3678 :project_id => ''
3676 }
3679 }
3677 end
3680 end
3678 end
3681 end
3679 end
3682 end
3680
3683
3681 def test_bulk_copy_should_add_relations_with_copied_issues
3684 def test_bulk_copy_should_add_relations_with_copied_issues
3682 @request.session[:user_id] = 2
3685 @request.session[:user_id] = 2
3683
3686
3684 assert_difference 'Issue.count', 2 do
3687 assert_difference 'Issue.count', 2 do
3685 assert_difference 'IssueRelation.count', 2 do
3688 assert_difference 'IssueRelation.count', 2 do
3686 post :bulk_update, :ids => [1, 3], :copy => '1',
3689 post :bulk_update, :ids => [1, 3], :copy => '1',
3687 :issue => {
3690 :issue => {
3688 :project_id => '1'
3691 :project_id => '1'
3689 }
3692 }
3690 end
3693 end
3691 end
3694 end
3692 end
3695 end
3693
3696
3694 def test_bulk_copy_should_allow_not_copying_the_subtasks
3697 def test_bulk_copy_should_allow_not_copying_the_subtasks
3695 issue = Issue.generate_with_descendants!
3698 issue = Issue.generate_with_descendants!
3696 @request.session[:user_id] = 2
3699 @request.session[:user_id] = 2
3697
3700
3698 assert_difference 'Issue.count', 1 do
3701 assert_difference 'Issue.count', 1 do
3699 post :bulk_update, :ids => [issue.id], :copy => '1',
3702 post :bulk_update, :ids => [issue.id], :copy => '1',
3700 :issue => {
3703 :issue => {
3701 :project_id => ''
3704 :project_id => ''
3702 }
3705 }
3703 end
3706 end
3704 end
3707 end
3705
3708
3706 def test_bulk_copy_should_allow_copying_the_subtasks
3709 def test_bulk_copy_should_allow_copying_the_subtasks
3707 issue = Issue.generate_with_descendants!
3710 issue = Issue.generate_with_descendants!
3708 count = issue.descendants.count
3711 count = issue.descendants.count
3709 @request.session[:user_id] = 2
3712 @request.session[:user_id] = 2
3710
3713
3711 assert_difference 'Issue.count', count+1 do
3714 assert_difference 'Issue.count', count+1 do
3712 post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '1',
3715 post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '1',
3713 :issue => {
3716 :issue => {
3714 :project_id => ''
3717 :project_id => ''
3715 }
3718 }
3716 end
3719 end
3717 copy = Issue.where(:parent_id => nil).order("id DESC").first
3720 copy = Issue.where(:parent_id => nil).order("id DESC").first
3718 assert_equal count, copy.descendants.count
3721 assert_equal count, copy.descendants.count
3719 end
3722 end
3720
3723
3721 def test_bulk_copy_should_not_copy_selected_subtasks_twice
3724 def test_bulk_copy_should_not_copy_selected_subtasks_twice
3722 issue = Issue.generate_with_descendants!
3725 issue = Issue.generate_with_descendants!
3723 count = issue.descendants.count
3726 count = issue.descendants.count
3724 @request.session[:user_id] = 2
3727 @request.session[:user_id] = 2
3725
3728
3726 assert_difference 'Issue.count', count+1 do
3729 assert_difference 'Issue.count', count+1 do
3727 post :bulk_update, :ids => issue.self_and_descendants.map(&:id), :copy => '1', :copy_subtasks => '1',
3730 post :bulk_update, :ids => issue.self_and_descendants.map(&:id), :copy => '1', :copy_subtasks => '1',
3728 :issue => {
3731 :issue => {
3729 :project_id => ''
3732 :project_id => ''
3730 }
3733 }
3731 end
3734 end
3732 copy = Issue.where(:parent_id => nil).order("id DESC").first
3735 copy = Issue.where(:parent_id => nil).order("id DESC").first
3733 assert_equal count, copy.descendants.count
3736 assert_equal count, copy.descendants.count
3734 end
3737 end
3735
3738
3736 def test_bulk_copy_to_another_project_should_follow_when_needed
3739 def test_bulk_copy_to_another_project_should_follow_when_needed
3737 @request.session[:user_id] = 2
3740 @request.session[:user_id] = 2
3738 post :bulk_update, :ids => [1], :copy => '1', :issue => {:project_id => 2}, :follow => '1'
3741 post :bulk_update, :ids => [1], :copy => '1', :issue => {:project_id => 2}, :follow => '1'
3739 issue = Issue.first(:order => 'id DESC')
3742 issue = Issue.first(:order => 'id DESC')
3740 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
3743 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
3741 end
3744 end
3742
3745
3743 def test_destroy_issue_with_no_time_entries
3746 def test_destroy_issue_with_no_time_entries
3744 assert_nil TimeEntry.find_by_issue_id(2)
3747 assert_nil TimeEntry.find_by_issue_id(2)
3745 @request.session[:user_id] = 2
3748 @request.session[:user_id] = 2
3746
3749
3747 assert_difference 'Issue.count', -1 do
3750 assert_difference 'Issue.count', -1 do
3748 delete :destroy, :id => 2
3751 delete :destroy, :id => 2
3749 end
3752 end
3750 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3753 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3751 assert_nil Issue.find_by_id(2)
3754 assert_nil Issue.find_by_id(2)
3752 end
3755 end
3753
3756
3754 def test_destroy_issues_with_time_entries
3757 def test_destroy_issues_with_time_entries
3755 @request.session[:user_id] = 2
3758 @request.session[:user_id] = 2
3756
3759
3757 assert_no_difference 'Issue.count' do
3760 assert_no_difference 'Issue.count' do
3758 delete :destroy, :ids => [1, 3]
3761 delete :destroy, :ids => [1, 3]
3759 end
3762 end
3760 assert_response :success
3763 assert_response :success
3761 assert_template 'destroy'
3764 assert_template 'destroy'
3762 assert_not_nil assigns(:hours)
3765 assert_not_nil assigns(:hours)
3763 assert Issue.find_by_id(1) && Issue.find_by_id(3)
3766 assert Issue.find_by_id(1) && Issue.find_by_id(3)
3764 assert_tag 'form',
3767 assert_tag 'form',
3765 :descendant => {:tag => 'input', :attributes => {:name => '_method', :value => 'delete'}}
3768 :descendant => {:tag => 'input', :attributes => {:name => '_method', :value => 'delete'}}
3766 end
3769 end
3767
3770
3768 def test_destroy_issues_and_destroy_time_entries
3771 def test_destroy_issues_and_destroy_time_entries
3769 @request.session[:user_id] = 2
3772 @request.session[:user_id] = 2
3770
3773
3771 assert_difference 'Issue.count', -2 do
3774 assert_difference 'Issue.count', -2 do
3772 assert_difference 'TimeEntry.count', -3 do
3775 assert_difference 'TimeEntry.count', -3 do
3773 delete :destroy, :ids => [1, 3], :todo => 'destroy'
3776 delete :destroy, :ids => [1, 3], :todo => 'destroy'
3774 end
3777 end
3775 end
3778 end
3776 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3779 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3777 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
3780 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
3778 assert_nil TimeEntry.find_by_id([1, 2])
3781 assert_nil TimeEntry.find_by_id([1, 2])
3779 end
3782 end
3780
3783
3781 def test_destroy_issues_and_assign_time_entries_to_project
3784 def test_destroy_issues_and_assign_time_entries_to_project
3782 @request.session[:user_id] = 2
3785 @request.session[:user_id] = 2
3783
3786
3784 assert_difference 'Issue.count', -2 do
3787 assert_difference 'Issue.count', -2 do
3785 assert_no_difference 'TimeEntry.count' do
3788 assert_no_difference 'TimeEntry.count' do
3786 delete :destroy, :ids => [1, 3], :todo => 'nullify'
3789 delete :destroy, :ids => [1, 3], :todo => 'nullify'
3787 end
3790 end
3788 end
3791 end
3789 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3792 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3790 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
3793 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
3791 assert_nil TimeEntry.find(1).issue_id
3794 assert_nil TimeEntry.find(1).issue_id
3792 assert_nil TimeEntry.find(2).issue_id
3795 assert_nil TimeEntry.find(2).issue_id
3793 end
3796 end
3794
3797
3795 def test_destroy_issues_and_reassign_time_entries_to_another_issue
3798 def test_destroy_issues_and_reassign_time_entries_to_another_issue
3796 @request.session[:user_id] = 2
3799 @request.session[:user_id] = 2
3797
3800
3798 assert_difference 'Issue.count', -2 do
3801 assert_difference 'Issue.count', -2 do
3799 assert_no_difference 'TimeEntry.count' do
3802 assert_no_difference 'TimeEntry.count' do
3800 delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
3803 delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
3801 end
3804 end
3802 end
3805 end
3803 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3806 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3804 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
3807 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
3805 assert_equal 2, TimeEntry.find(1).issue_id
3808 assert_equal 2, TimeEntry.find(1).issue_id
3806 assert_equal 2, TimeEntry.find(2).issue_id
3809 assert_equal 2, TimeEntry.find(2).issue_id
3807 end
3810 end
3808
3811
3809 def test_destroy_issues_from_different_projects
3812 def test_destroy_issues_from_different_projects
3810 @request.session[:user_id] = 2
3813 @request.session[:user_id] = 2
3811
3814
3812 assert_difference 'Issue.count', -3 do
3815 assert_difference 'Issue.count', -3 do
3813 delete :destroy, :ids => [1, 2, 6], :todo => 'destroy'
3816 delete :destroy, :ids => [1, 2, 6], :todo => 'destroy'
3814 end
3817 end
3815 assert_redirected_to :controller => 'issues', :action => 'index'
3818 assert_redirected_to :controller => 'issues', :action => 'index'
3816 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
3819 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
3817 end
3820 end
3818
3821
3819 def test_destroy_parent_and_child_issues
3822 def test_destroy_parent_and_child_issues
3820 parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
3823 parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
3821 child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
3824 child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
3822 assert child.is_descendant_of?(parent.reload)
3825 assert child.is_descendant_of?(parent.reload)
3823
3826
3824 @request.session[:user_id] = 2
3827 @request.session[:user_id] = 2
3825 assert_difference 'Issue.count', -2 do
3828 assert_difference 'Issue.count', -2 do
3826 delete :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
3829 delete :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
3827 end
3830 end
3828 assert_response 302
3831 assert_response 302
3829 end
3832 end
3830
3833
3831 def test_default_search_scope
3834 def test_default_search_scope
3832 get :index
3835 get :index
3833 assert_tag :div, :attributes => {:id => 'quick-search'},
3836 assert_tag :div, :attributes => {:id => 'quick-search'},
3834 :child => {:tag => 'form',
3837 :child => {:tag => 'form',
3835 :child => {:tag => 'input', :attributes => {:name => 'issues', :type => 'hidden', :value => '1'}}}
3838 :child => {:tag => 'input', :attributes => {:name => 'issues', :type => 'hidden', :value => '1'}}}
3836 end
3839 end
3837 end
3840 end
General Comments 0
You need to be logged in to leave comments. Login now