##// END OF EJS Templates
Creating a wiki page named "Sidebar" without proper permission raises an exception (#23700)....
Jean-Philippe Lang -
r15367:650a64cb0020
parent child
Show More
@@ -1,387 +1,389
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 # The WikiController follows the Rails REST controller pattern but with
19 19 # a few differences
20 20 #
21 21 # * index - shows a list of WikiPages grouped by page or date
22 22 # * new - not used
23 23 # * create - not used
24 24 # * show - will also show the form for creating a new wiki page
25 25 # * edit - used to edit an existing or new page
26 26 # * update - used to save a wiki page update to the database, including new pages
27 27 # * destroy - normal
28 28 #
29 29 # Other member and collection methods are also used
30 30 #
31 31 # TODO: still being worked on
32 32 class WikiController < ApplicationController
33 33 default_search_scope :wiki_pages
34 34 before_action :find_wiki, :authorize
35 35 before_action :find_existing_or_new_page, :only => [:show, :edit, :update]
36 36 before_action :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy, :destroy_version]
37 37 before_action :find_attachments, :only => [:preview]
38 38 accept_api_auth :index, :show, :update, :destroy
39 39
40 40 helper :attachments
41 41 include AttachmentsHelper
42 42 helper :watchers
43 43 include Redmine::Export::PDF
44 44
45 45 # List of pages, sorted alphabetically and by parent (hierarchy)
46 46 def index
47 47 load_pages_for_index
48 48
49 49 respond_to do |format|
50 50 format.html {
51 51 @pages_by_parent_id = @pages.group_by(&:parent_id)
52 52 }
53 53 format.api
54 54 end
55 55 end
56 56
57 57 # List of page, by last update
58 58 def date_index
59 59 load_pages_for_index
60 60 @pages_by_date = @pages.group_by {|p| p.updated_on.to_date}
61 61 end
62 62
63 63 def new
64 64 @page = WikiPage.new(:wiki => @wiki, :title => params[:title])
65 unless User.current.allowed_to?(:edit_wiki_pages, @project) && editable?
65 unless User.current.allowed_to?(:edit_wiki_pages, @project)
66 66 render_403
67 return
67 68 end
68 69 if request.post?
70 @page.title = '' unless editable?
69 71 @page.validate
70 72 if @page.errors[:title].blank?
71 73 path = project_wiki_page_path(@project, @page.title)
72 74 respond_to do |format|
73 75 format.html { redirect_to path }
74 76 format.js { render :js => "window.location = #{path.to_json}" }
75 77 end
76 78 end
77 79 end
78 80 end
79 81
80 82 # display a page (in editing mode if it doesn't exist)
81 83 def show
82 84 if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project)
83 85 deny_access
84 86 return
85 87 end
86 88 @content = @page.content_for_version(params[:version])
87 89 if @content.nil?
88 90 if User.current.allowed_to?(:edit_wiki_pages, @project) && editable? && !api_request?
89 91 edit
90 92 render :action => 'edit'
91 93 else
92 94 render_404
93 95 end
94 96 return
95 97 end
96 98 if User.current.allowed_to?(:export_wiki_pages, @project)
97 99 if params[:format] == 'pdf'
98 100 send_file_headers! :type => 'application/pdf', :filename => "#{@page.title}.pdf"
99 101 return
100 102 elsif params[:format] == 'html'
101 103 export = render_to_string :action => 'export', :layout => false
102 104 send_data(export, :type => 'text/html', :filename => "#{@page.title}.html")
103 105 return
104 106 elsif params[:format] == 'txt'
105 107 send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt")
106 108 return
107 109 end
108 110 end
109 111 @editable = editable?
110 112 @sections_editable = @editable && User.current.allowed_to?(:edit_wiki_pages, @page.project) &&
111 113 @content.current_version? &&
112 114 Redmine::WikiFormatting.supports_section_edit?
113 115
114 116 respond_to do |format|
115 117 format.html
116 118 format.api
117 119 end
118 120 end
119 121
120 122 # edit an existing page or a new one
121 123 def edit
122 124 return render_403 unless editable?
123 125 if @page.new_record?
124 126 if params[:parent].present?
125 127 @page.parent = @page.wiki.find_page(params[:parent].to_s)
126 128 end
127 129 end
128 130
129 131 @content = @page.content_for_version(params[:version])
130 132 @content ||= WikiContent.new(:page => @page)
131 133 @content.text = initial_page_content(@page) if @content.text.blank?
132 134 # don't keep previous comment
133 135 @content.comments = nil
134 136
135 137 # To prevent StaleObjectError exception when reverting to a previous version
136 138 @content.version = @page.content.version if @page.content
137 139
138 140 @text = @content.text
139 141 if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
140 142 @section = params[:section].to_i
141 143 @text, @section_hash = Redmine::WikiFormatting.formatter.new(@text).get_section(@section)
142 144 render_404 if @text.blank?
143 145 end
144 146 end
145 147
146 148 # Creates a new page or updates an existing one
147 149 def update
148 150 return render_403 unless editable?
149 151 was_new_page = @page.new_record?
150 152 @page.safe_attributes = params[:wiki_page]
151 153
152 154 @content = @page.content || WikiContent.new(:page => @page)
153 155 content_params = params[:content]
154 156 if content_params.nil? && params[:wiki_page].is_a?(Hash)
155 157 content_params = params[:wiki_page].slice(:text, :comments, :version)
156 158 end
157 159 content_params ||= {}
158 160
159 161 @content.comments = content_params[:comments]
160 162 @text = content_params[:text]
161 163 if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
162 164 @section = params[:section].to_i
163 165 @section_hash = params[:section_hash]
164 166 @content.text = Redmine::WikiFormatting.formatter.new(@content.text).update_section(@section, @text, @section_hash)
165 167 else
166 168 @content.version = content_params[:version] if content_params[:version]
167 169 @content.text = @text
168 170 end
169 171 @content.author = User.current
170 172
171 173 if @page.save_with_content(@content)
172 174 attachments = Attachment.attach_files(@page, params[:attachments] || (params[:wiki_page] && params[:wiki_page][:uploads]))
173 175 render_attachment_warning_if_needed(@page)
174 176 call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page})
175 177
176 178 respond_to do |format|
177 179 format.html {
178 180 anchor = @section ? "section-#{@section}" : nil
179 181 redirect_to project_wiki_page_path(@project, @page.title, :anchor => anchor)
180 182 }
181 183 format.api {
182 184 if was_new_page
183 185 render :action => 'show', :status => :created, :location => project_wiki_page_path(@project, @page.title)
184 186 else
185 187 render_api_ok
186 188 end
187 189 }
188 190 end
189 191 else
190 192 respond_to do |format|
191 193 format.html { render :action => 'edit' }
192 194 format.api { render_validation_errors(@content) }
193 195 end
194 196 end
195 197
196 198 rescue ActiveRecord::StaleObjectError, Redmine::WikiFormatting::StaleSectionError
197 199 # Optimistic locking exception
198 200 respond_to do |format|
199 201 format.html {
200 202 flash.now[:error] = l(:notice_locking_conflict)
201 203 render :action => 'edit'
202 204 }
203 205 format.api { render_api_head :conflict }
204 206 end
205 207 end
206 208
207 209 # rename a page
208 210 def rename
209 211 return render_403 unless editable?
210 212 @page.redirect_existing_links = true
211 213 # used to display the *original* title if some AR validation errors occur
212 214 @original_title = @page.pretty_title
213 215 @page.safe_attributes = params[:wiki_page]
214 216 if request.post? && @page.save
215 217 flash[:notice] = l(:notice_successful_update)
216 218 redirect_to project_wiki_page_path(@page.project, @page.title)
217 219 end
218 220 end
219 221
220 222 def protect
221 223 @page.update_attribute :protected, params[:protected]
222 224 redirect_to project_wiki_page_path(@project, @page.title)
223 225 end
224 226
225 227 # show page history
226 228 def history
227 229 @version_count = @page.content.versions.count
228 230 @version_pages = Paginator.new @version_count, per_page_option, params['page']
229 231 # don't load text
230 232 @versions = @page.content.versions.
231 233 select("id, author_id, comments, updated_on, version").
232 234 reorder('version DESC').
233 235 limit(@version_pages.per_page + 1).
234 236 offset(@version_pages.offset).
235 237 to_a
236 238
237 239 render :layout => false if request.xhr?
238 240 end
239 241
240 242 def diff
241 243 @diff = @page.diff(params[:version], params[:version_from])
242 244 render_404 unless @diff
243 245 end
244 246
245 247 def annotate
246 248 @annotate = @page.annotate(params[:version])
247 249 render_404 unless @annotate
248 250 end
249 251
250 252 # Removes a wiki page and its history
251 253 # Children can be either set as root pages, removed or reassigned to another parent page
252 254 def destroy
253 255 return render_403 unless editable?
254 256
255 257 @descendants_count = @page.descendants.size
256 258 if @descendants_count > 0
257 259 case params[:todo]
258 260 when 'nullify'
259 261 # Nothing to do
260 262 when 'destroy'
261 263 # Removes all its descendants
262 264 @page.descendants.each(&:destroy)
263 265 when 'reassign'
264 266 # Reassign children to another parent page
265 267 reassign_to = @wiki.pages.find_by_id(params[:reassign_to_id].to_i)
266 268 return unless reassign_to
267 269 @page.children.each do |child|
268 270 child.update_attribute(:parent, reassign_to)
269 271 end
270 272 else
271 273 @reassignable_to = @wiki.pages - @page.self_and_descendants
272 274 # display the destroy form if it's a user request
273 275 return unless api_request?
274 276 end
275 277 end
276 278 @page.destroy
277 279 respond_to do |format|
278 280 format.html { redirect_to project_wiki_index_path(@project) }
279 281 format.api { render_api_ok }
280 282 end
281 283 end
282 284
283 285 def destroy_version
284 286 return render_403 unless editable?
285 287
286 288 if content = @page.content.versions.find_by_version(params[:version])
287 289 content.destroy
288 290 redirect_to_referer_or history_project_wiki_page_path(@project, @page.title)
289 291 else
290 292 render_404
291 293 end
292 294 end
293 295
294 296 # Export wiki to a single pdf or html file
295 297 def export
296 298 @pages = @wiki.pages.
297 299 order('title').
298 300 includes([:content, {:attachments => :author}]).
299 301 to_a
300 302 respond_to do |format|
301 303 format.html {
302 304 export = render_to_string :action => 'export_multiple', :layout => false
303 305 send_data(export, :type => 'text/html', :filename => "wiki.html")
304 306 }
305 307 format.pdf {
306 308 send_file_headers! :type => 'application/pdf', :filename => "#{@project.identifier}.pdf"
307 309 }
308 310 end
309 311 end
310 312
311 313 def preview
312 314 page = @wiki.find_page(params[:id])
313 315 # page is nil when previewing a new page
314 316 return render_403 unless page.nil? || editable?(page)
315 317 if page
316 318 @attachments += page.attachments
317 319 @previewed = page.content
318 320 end
319 321 @text = params[:content][:text]
320 322 render :partial => 'common/preview'
321 323 end
322 324
323 325 def add_attachment
324 326 return render_403 unless editable?
325 327 attachments = Attachment.attach_files(@page, params[:attachments])
326 328 render_attachment_warning_if_needed(@page)
327 329 redirect_to :action => 'show', :id => @page.title, :project_id => @project
328 330 end
329 331
330 332 private
331 333
332 334 def find_wiki
333 335 @project = Project.find(params[:project_id])
334 336 @wiki = @project.wiki
335 337 render_404 unless @wiki
336 338 rescue ActiveRecord::RecordNotFound
337 339 render_404
338 340 end
339 341
340 342 # Finds the requested page or a new page if it doesn't exist
341 343 def find_existing_or_new_page
342 344 @page = @wiki.find_or_new_page(params[:id])
343 345 if @wiki.page_found_with_redirect?
344 346 redirect_to_page @page
345 347 end
346 348 end
347 349
348 350 # Finds the requested page and returns a 404 error if it doesn't exist
349 351 def find_existing_page
350 352 @page = @wiki.find_page(params[:id])
351 353 if @page.nil?
352 354 render_404
353 355 return
354 356 end
355 357 if @wiki.page_found_with_redirect?
356 358 redirect_to_page @page
357 359 end
358 360 end
359 361
360 362 def redirect_to_page(page)
361 363 if page.project && page.project.visible?
362 364 redirect_to :action => action_name, :project_id => page.project, :id => page.title
363 365 else
364 366 render_404
365 367 end
366 368 end
367 369
368 370 # Returns true if the current user is allowed to edit the page, otherwise false
369 371 def editable?(page = @page)
370 372 page.editable_by?(User.current)
371 373 end
372 374
373 375 # Returns the default content of a new wiki page
374 376 def initial_page_content(page)
375 377 helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
376 378 extend helper unless self.instance_of?(helper)
377 379 helper.instance_method(:initial_page_content).bind(self).call(page)
378 380 end
379 381
380 382 def load_pages_for_index
381 383 @pages = @wiki.pages.with_updated_on.
382 384 reorder("#{WikiPage.table_name}.title").
383 385 includes(:wiki => :project).
384 386 includes(:parent).
385 387 to_a
386 388 end
387 389 end
@@ -1,1094 +1,1103
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class WikiControllerTest < Redmine::ControllerTest
21 21 fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles,
22 22 :enabled_modules, :wikis, :wiki_pages, :wiki_contents,
23 23 :wiki_content_versions, :attachments,
24 24 :issues, :issue_statuses, :trackers
25 25
26 26 def setup
27 27 User.current = nil
28 28 end
29 29
30 30 def test_show_start_page
31 31 get :show, :params => {:project_id => 'ecookbook'}
32 32 assert_response :success
33 33
34 34 assert_select 'h1', :text => /CookBook documentation/
35 35 # child_pages macro
36 36 assert_select 'ul.pages-hierarchy>li>a[href=?]', '/projects/ecookbook/wiki/Page_with_an_inline_image',
37 37 :text => 'Page with an inline image'
38 38 end
39 39
40 40 def test_export_link
41 41 Role.anonymous.add_permission! :export_wiki_pages
42 42 get :show, :params => {:project_id => 'ecookbook'}
43 43 assert_response :success
44 44 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation.txt'
45 45 end
46 46
47 47 def test_show_page_with_name
48 48 get :show, :params => {:project_id => 1, :id => 'Another_page'}
49 49 assert_response :success
50 50
51 51 assert_select 'h1', :text => /Another page/
52 52 # Included page with an inline image
53 53 assert_select 'p', :text => /This is an inline image/
54 54 assert_select 'img[src=?][alt=?]', '/attachments/download/3/logo.gif', 'This is a logo'
55 55 end
56 56
57 57 def test_show_old_version
58 58 with_settings :default_language => 'en' do
59 59 get :show, :params => {:project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '2'}
60 60 end
61 61 assert_response :success
62 62
63 63 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/1', :text => /Previous/
64 64 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2/diff', :text => /diff/
65 65 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/3', :text => /Next/
66 66 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation', :text => /Current version/
67 67 end
68 68
69 69 def test_show_old_version_with_attachments
70 70 page = WikiPage.find(4)
71 71 assert page.attachments.any?
72 72 content = page.content
73 73 content.text = "update"
74 74 content.save!
75 75
76 76 get :show, :params => {:project_id => 'ecookbook', :id => page.title, :version => '1'}
77 77 assert_response :success
78 78 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_an_inline_image', :text => /Current version/
79 79 end
80 80
81 81 def test_show_old_version_without_permission_should_be_denied
82 82 Role.anonymous.remove_permission! :view_wiki_edits
83 83
84 84 get :show, :params => {:project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '2'}
85 85 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fprojects%2Fecookbook%2Fwiki%2FCookBook_documentation%2F2'
86 86 end
87 87
88 88 def test_show_first_version
89 89 with_settings :default_language => 'en' do
90 90 get :show, :params => {:project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '1'}
91 91 end
92 92 assert_response :success
93 93
94 94 assert_select 'a', :text => /Previous/, :count => 0
95 95 assert_select 'a', :text => /diff/, :count => 0
96 96 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => /Next/
97 97 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation', :text => /Current version/
98 98 end
99 99
100 100 def test_show_redirected_page
101 101 WikiRedirect.create!(:wiki_id => 1, :title => 'Old_title', :redirects_to => 'Another_page')
102 102
103 103 get :show, :params => {:project_id => 'ecookbook', :id => 'Old_title'}
104 104 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
105 105 end
106 106
107 107 def test_show_with_sidebar
108 108 page = Project.find(1).wiki.pages.new(:title => 'Sidebar')
109 109 page.content = WikiContent.new(:text => 'Side bar content for test_show_with_sidebar')
110 110 page.save!
111 111
112 112 get :show, :params => {:project_id => 1, :id => 'Another_page'}
113 113 assert_response :success
114 114 assert_select 'div#sidebar', :text => /Side bar content for test_show_with_sidebar/
115 115 end
116 116
117 117 def test_show_should_display_section_edit_links
118 118 @request.session[:user_id] = 2
119 119 get :show, :params => {:project_id => 1, :id => 'Page with sections'}
120 120
121 121 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=1', 0
122 122 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
123 123 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=3'
124 124 end
125 125
126 126 def test_show_current_version_should_display_section_edit_links
127 127 @request.session[:user_id] = 2
128 128 get :show, :params => {:project_id => 1, :id => 'Page with sections', :version => 3}
129 129
130 130 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
131 131 end
132 132
133 133 def test_show_old_version_should_not_display_section_edit_links
134 134 @request.session[:user_id] = 2
135 135 get :show, :params => {:project_id => 1, :id => 'Page with sections', :version => 2}
136 136
137 137 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=2', 0
138 138 end
139 139
140 140 def test_show_unexistent_page_without_edit_right
141 141 get :show, :params => {:project_id => 1, :id => 'Unexistent page'}
142 142 assert_response 404
143 143 end
144 144
145 145 def test_show_unexistent_page_with_edit_right
146 146 @request.session[:user_id] = 2
147 147 get :show, :params => {:project_id => 1, :id => 'Unexistent page'}
148 148 assert_response :success
149 149 assert_select 'textarea[name=?]', 'content[text]'
150 150 end
151 151
152 152 def test_show_specific_version_of_an_unexistent_page_without_edit_right
153 153 get :show, :params => {:project_id => 1, :id => 'Unexistent page', :version => 1}
154 154 assert_response 404
155 155 end
156 156
157 157 def test_show_unexistent_page_with_parent_should_preselect_parent
158 158 @request.session[:user_id] = 2
159 159 get :show, :params => {:project_id => 1, :id => 'Unexistent page', :parent => 'Another_page'}
160 160 assert_response :success
161 161 assert_select 'select[name=?] option[value="2"][selected=selected]', 'wiki_page[parent_id]'
162 162 end
163 163
164 164 def test_show_should_not_show_history_without_permission
165 165 Role.anonymous.remove_permission! :view_wiki_edits
166 166 get :show, :params => {:project_id => 1, :id => 'Page with sections', :version => 2}
167 167
168 168 assert_response 302
169 169 end
170 170
171 171 def test_show_page_without_content_should_display_the_edit_form
172 172 @request.session[:user_id] = 2
173 173 WikiPage.create!(:title => 'NoContent', :wiki => Project.find(1).wiki)
174 174
175 175 get :show, :params => {:project_id => 1, :id => 'NoContent'}
176 176 assert_response :success
177 177 assert_select 'textarea[name=?]', 'content[text]'
178 178 end
179 179
180 180 def test_get_new
181 181 @request.session[:user_id] = 2
182 182
183 183 get :new, :params => {:project_id => 'ecookbook'}
184 184 assert_response :success
185 185 assert_select 'input[name=?]', 'title'
186 186 end
187 187
188 188 def test_get_new_xhr
189 189 @request.session[:user_id] = 2
190 190
191 191 xhr :get, :new, :params => {:project_id => 'ecookbook'}
192 192 assert_response :success
193 193 assert_include 'Unallowed characters', response.body
194 194 end
195 195
196 196 def test_post_new_with_valid_title_should_redirect_to_edit
197 197 @request.session[:user_id] = 2
198 198
199 199 post :new, :params => {:project_id => 'ecookbook', :title => 'New Page'}
200 200 assert_redirected_to '/projects/ecookbook/wiki/New_Page'
201 201 end
202 202
203 203 def test_post_new_xhr_with_valid_title_should_redirect_to_edit
204 204 @request.session[:user_id] = 2
205 205
206 206 xhr :post, :new, :params => {:project_id => 'ecookbook', :title => 'New Page'}
207 207 assert_response :success
208 208 assert_equal 'window.location = "/projects/ecookbook/wiki/New_Page"', response.body
209 209 end
210 210
211 211 def test_post_new_with_invalid_title_should_display_errors
212 212 @request.session[:user_id] = 2
213 213
214 214 post :new, :params => {:project_id => 'ecookbook', :title => 'Another page'}
215 215 assert_response :success
216 216 assert_select_error 'Title has already been taken'
217 217 end
218 218
219 def test_post_new_with_protected_title_should_display_errors
220 Role.find(1).remove_permission!(:protect_wiki_pages)
221 @request.session[:user_id] = 2
222
223 post :new, :params => {:project_id => 'ecookbook', :title => 'Sidebar'}
224 assert_response :success
225 assert_select_error /Title/
226 end
227
219 228 def test_post_new_xhr_with_invalid_title_should_display_errors
220 229 @request.session[:user_id] = 2
221 230
222 231 xhr :post, :new, :params => {:project_id => 'ecookbook', :title => 'Another page'}
223 232 assert_response :success
224 233 assert_include 'Title has already been taken', response.body
225 234 end
226 235
227 236 def test_create_page
228 237 @request.session[:user_id] = 2
229 238 assert_difference 'WikiPage.count' do
230 239 assert_difference 'WikiContent.count' do
231 240 put :update, :params => {
232 241 :project_id => 1,
233 242 :id => 'New page',
234 243 :content => {
235 244 :comments => 'Created the page',
236 245 :text => "h1. New page\n\nThis is a new page",
237 246 :version => 0
238 247 }
239 248 }
240 249 end
241 250 end
242 251 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'New_page'
243 252 page = Project.find(1).wiki.find_page('New page')
244 253 assert !page.new_record?
245 254 assert_not_nil page.content
246 255 assert_nil page.parent
247 256 assert_equal 'Created the page', page.content.comments
248 257 end
249 258
250 259 def test_create_page_with_attachments
251 260 @request.session[:user_id] = 2
252 261 assert_difference 'WikiPage.count' do
253 262 assert_difference 'Attachment.count' do
254 263 put :update, :params => {
255 264 :project_id => 1,
256 265 :id => 'New page',
257 266 :content => {
258 267 :comments => 'Created the page',
259 268 :text => "h1. New page\n\nThis is a new page",
260 269 :version => 0
261 270 },
262 271 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
263 272 }
264 273 end
265 274 end
266 275 page = Project.find(1).wiki.find_page('New page')
267 276 assert_equal 1, page.attachments.count
268 277 assert_equal 'testfile.txt', page.attachments.first.filename
269 278 end
270 279
271 280 def test_create_page_with_parent
272 281 @request.session[:user_id] = 2
273 282 assert_difference 'WikiPage.count' do
274 283 put :update, :params => {
275 284 :project_id => 1,
276 285 :id => 'New page',
277 286 :content => {
278 287 :text => "h1. New page\n\nThis is a new page",
279 288 :version => 0
280 289 },
281 290 :wiki_page => {:parent_id => 2}
282 291 }
283 292 end
284 293 page = Project.find(1).wiki.find_page('New page')
285 294 assert_equal WikiPage.find(2), page.parent
286 295 end
287 296
288 297 def test_edit_page
289 298 @request.session[:user_id] = 2
290 299 get :edit, :params => {:project_id => 'ecookbook', :id => 'Another_page'}
291 300
292 301 assert_response :success
293 302
294 303 assert_select 'textarea[name=?]', 'content[text]',
295 304 :text => WikiPage.find_by_title('Another_page').content.text
296 305 end
297 306
298 307 def test_edit_section
299 308 @request.session[:user_id] = 2
300 309 get :edit, :params => {:project_id => 'ecookbook', :id => 'Page_with_sections', :section => 2}
301 310
302 311 assert_response :success
303 312
304 313 page = WikiPage.find_by_title('Page_with_sections')
305 314 section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
306 315
307 316 assert_select 'textarea[name=?]', 'content[text]', :text => section
308 317 assert_select 'input[name=section][type=hidden][value="2"]'
309 318 assert_select 'input[name=section_hash][type=hidden][value=?]', hash
310 319 end
311 320
312 321 def test_edit_invalid_section_should_respond_with_404
313 322 @request.session[:user_id] = 2
314 323 get :edit, :params => {:project_id => 'ecookbook', :id => 'Page_with_sections', :section => 10}
315 324
316 325 assert_response 404
317 326 end
318 327
319 328 def test_update_page
320 329 @request.session[:user_id] = 2
321 330 assert_no_difference 'WikiPage.count' do
322 331 assert_no_difference 'WikiContent.count' do
323 332 assert_difference 'WikiContent::Version.count' do
324 333 put :update, :params => {
325 334 :project_id => 1,
326 335 :id => 'Another_page',
327 336 :content => {
328 337 :comments => "my comments",
329 338 :text => "edited",
330 339 :version => 1
331 340 }
332 341 }
333 342 end
334 343 end
335 344 end
336 345 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
337 346
338 347 page = Wiki.find(1).pages.find_by_title('Another_page')
339 348 assert_equal "edited", page.content.text
340 349 assert_equal 2, page.content.version
341 350 assert_equal "my comments", page.content.comments
342 351 end
343 352
344 353 def test_update_page_with_parent
345 354 @request.session[:user_id] = 2
346 355 assert_no_difference 'WikiPage.count' do
347 356 assert_no_difference 'WikiContent.count' do
348 357 assert_difference 'WikiContent::Version.count' do
349 358 put :update, :params => {
350 359 :project_id => 1,
351 360 :id => 'Another_page',
352 361 :content => {
353 362 :comments => "my comments",
354 363 :text => "edited",
355 364 :version => 1
356 365 },
357 366 :wiki_page => {:parent_id => '1'}
358 367 }
359 368 end
360 369 end
361 370 end
362 371 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
363 372
364 373 page = Wiki.find(1).pages.find_by_title('Another_page')
365 374 assert_equal "edited", page.content.text
366 375 assert_equal 2, page.content.version
367 376 assert_equal "my comments", page.content.comments
368 377 assert_equal WikiPage.find(1), page.parent
369 378 end
370 379
371 380 def test_update_page_with_failure
372 381 @request.session[:user_id] = 2
373 382 assert_no_difference 'WikiPage.count' do
374 383 assert_no_difference 'WikiContent.count' do
375 384 assert_no_difference 'WikiContent::Version.count' do
376 385 put :update, :params => {
377 386 :project_id => 1,
378 387 :id => 'Another_page',
379 388 :content => {
380 389 :comments => 'a' * 1300, # failure here, comment is too long
381 390 :text => 'edited'
382 391 },
383 392 :wiki_page => {
384 393 :parent_id => ""
385 394 }
386 395 }
387 396 end
388 397 end
389 398 end
390 399 assert_response :success
391 400
392 401 assert_select_error /Comment is too long/
393 402 assert_select 'textarea#content_text', :text => "edited"
394 403 assert_select 'input#content_version[value="1"]'
395 404 end
396 405
397 406 def test_update_page_with_parent_change_only_should_not_create_content_version
398 407 @request.session[:user_id] = 2
399 408 assert_no_difference 'WikiPage.count' do
400 409 assert_no_difference 'WikiContent.count' do
401 410 assert_no_difference 'WikiContent::Version.count' do
402 411 put :update, :params => {
403 412 :project_id => 1,
404 413 :id => 'Another_page',
405 414 :content => {
406 415 :comments => '',
407 416 :text => Wiki.find(1).find_page('Another_page').content.text,
408 417 :version => 1
409 418 },
410 419 :wiki_page => {:parent_id => '1'}
411 420 }
412 421 end
413 422 end
414 423 end
415 424 page = Wiki.find(1).pages.find_by_title('Another_page')
416 425 assert_equal 1, page.content.version
417 426 assert_equal WikiPage.find(1), page.parent
418 427 end
419 428
420 429 def test_update_page_with_attachments_only_should_not_create_content_version
421 430 @request.session[:user_id] = 2
422 431 assert_no_difference 'WikiPage.count' do
423 432 assert_no_difference 'WikiContent.count' do
424 433 assert_no_difference 'WikiContent::Version.count' do
425 434 assert_difference 'Attachment.count' do
426 435 put :update, :params => {
427 436 :project_id => 1,
428 437 :id => 'Another_page',
429 438 :content => {
430 439 :comments => '',
431 440 :text => Wiki.find(1).find_page('Another_page').content.text,
432 441 :version => 1
433 442 },
434 443 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
435 444 }
436 445 end
437 446 end
438 447 end
439 448 end
440 449 page = Wiki.find(1).pages.find_by_title('Another_page')
441 450 assert_equal 1, page.content.version
442 451 end
443 452
444 453 def test_update_stale_page_should_not_raise_an_error
445 454 @request.session[:user_id] = 2
446 455 c = Wiki.find(1).find_page('Another_page').content
447 456 c.text = 'Previous text'
448 457 c.save!
449 458 assert_equal 2, c.version
450 459
451 460 assert_no_difference 'WikiPage.count' do
452 461 assert_no_difference 'WikiContent.count' do
453 462 assert_no_difference 'WikiContent::Version.count' do
454 463 put :update, :params => {
455 464 :project_id => 1,
456 465 :id => 'Another_page',
457 466 :content => {
458 467 :comments => 'My comments',
459 468 :text => 'Text should not be lost',
460 469 :version => 1
461 470 }
462 471 }
463 472 end
464 473 end
465 474 end
466 475 assert_response :success
467 476 assert_select 'div.error', :text => /Data has been updated by another user/
468 477 assert_select 'textarea[name=?]', 'content[text]', :text => /Text should not be lost/
469 478 assert_select 'input[name=?][value=?]', 'content[comments]', 'My comments'
470 479
471 480 c.reload
472 481 assert_equal 'Previous text', c.text
473 482 assert_equal 2, c.version
474 483 end
475 484
476 485 def test_update_page_without_content_should_create_content
477 486 @request.session[:user_id] = 2
478 487 page = WikiPage.create!(:title => 'NoContent', :wiki => Project.find(1).wiki)
479 488
480 489 assert_no_difference 'WikiPage.count' do
481 490 assert_difference 'WikiContent.count' do
482 491 put :update, :params => {
483 492 :project_id => 1,
484 493 :id => 'NoContent',
485 494 :content => {:text => 'Some content'}
486 495 }
487 496 assert_response 302
488 497 end
489 498 end
490 499 assert_equal 'Some content', page.reload.content.text
491 500 end
492 501
493 502 def test_update_section
494 503 @request.session[:user_id] = 2
495 504 page = WikiPage.find_by_title('Page_with_sections')
496 505 section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
497 506 text = page.content.text
498 507
499 508 assert_no_difference 'WikiPage.count' do
500 509 assert_no_difference 'WikiContent.count' do
501 510 assert_difference 'WikiContent::Version.count' do
502 511 put :update, :params => {
503 512 :project_id => 1,
504 513 :id => 'Page_with_sections',
505 514 :content => {
506 515 :text => "New section content",
507 516 :version => 3
508 517 },
509 518 :section => 2,
510 519 :section_hash => hash
511 520 }
512 521 end
513 522 end
514 523 end
515 524 assert_redirected_to '/projects/ecookbook/wiki/Page_with_sections#section-2'
516 525 assert_equal Redmine::WikiFormatting::Textile::Formatter.new(text).update_section(2, "New section content"), page.reload.content.text
517 526 end
518 527
519 528 def test_update_section_should_allow_stale_page_update
520 529 @request.session[:user_id] = 2
521 530 page = WikiPage.find_by_title('Page_with_sections')
522 531 section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
523 532 text = page.content.text
524 533
525 534 assert_no_difference 'WikiPage.count' do
526 535 assert_no_difference 'WikiContent.count' do
527 536 assert_difference 'WikiContent::Version.count' do
528 537 put :update, :params => {
529 538 :project_id => 1,
530 539 :id => 'Page_with_sections',
531 540 :content => {
532 541 :text => "New section content",
533 542 :version => 2 # Current version is 3
534 543 },
535 544 :section => 2,
536 545 :section_hash => hash
537 546 }
538 547 end
539 548 end
540 549 end
541 550 assert_redirected_to '/projects/ecookbook/wiki/Page_with_sections#section-2'
542 551 page.reload
543 552 assert_equal Redmine::WikiFormatting::Textile::Formatter.new(text).update_section(2, "New section content"), page.content.text
544 553 assert_equal 4, page.content.version
545 554 end
546 555
547 556 def test_update_section_should_not_allow_stale_section_update
548 557 @request.session[:user_id] = 2
549 558
550 559 assert_no_difference 'WikiPage.count' do
551 560 assert_no_difference 'WikiContent.count' do
552 561 assert_no_difference 'WikiContent::Version.count' do
553 562 put :update, :params => {
554 563 :project_id => 1,
555 564 :id => 'Page_with_sections',
556 565 :content => {
557 566 :comments => 'My comments',
558 567 :text => "Text should not be lost",
559 568 :version => 3
560 569 },
561 570 :section => 2,
562 571 :section_hash => Digest::MD5.hexdigest("wrong hash")
563 572 }
564 573 end
565 574 end
566 575 end
567 576 assert_response :success
568 577 assert_select 'div.error', :text => /Data has been updated by another user/
569 578 assert_select 'textarea[name=?]', 'content[text]', :text => /Text should not be lost/
570 579 assert_select 'input[name=?][value=?]', 'content[comments]', 'My comments'
571 580 end
572 581
573 582 def test_preview
574 583 @request.session[:user_id] = 2
575 584 xhr :post, :preview, :params => {
576 585 :project_id => 1,
577 586 :id => 'CookBook_documentation',
578 587 :content => {
579 588 :comments => '',
580 589 :text => 'this is a *previewed text*',
581 590 :version => 3
582 591 }
583 592 }
584 593 assert_response :success
585 594 assert_select 'strong', :text => /previewed text/
586 595 end
587 596
588 597 def test_preview_new_page
589 598 @request.session[:user_id] = 2
590 599 xhr :post, :preview, :params => {
591 600 :project_id => 1,
592 601 :id => 'New page',
593 602 :content => {
594 603 :text => 'h1. New page',
595 604 :comments => '',
596 605 :version => 0
597 606 }
598 607 }
599 608 assert_response :success
600 609 assert_select 'h1', :text => /New page/
601 610 end
602 611
603 612 def test_history
604 613 @request.session[:user_id] = 2
605 614 get :history, :params => {:project_id => 'ecookbook', :id => 'CookBook_documentation'}
606 615 assert_response :success
607 616
608 617 assert_select 'table.wiki-page-versions tbody' do
609 618 assert_select 'tr', 3
610 619 end
611 620
612 621 assert_select "input[type=submit][name=commit]"
613 622 assert_select 'td' do
614 623 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => '2'
615 624 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2/annotate', :text => 'Annotate'
616 625 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => 'Delete'
617 626 end
618 627 end
619 628
620 629 def test_history_with_one_version
621 630 @request.session[:user_id] = 2
622 631 get :history, :params => {:project_id => 'ecookbook', :id => 'Another_page'}
623 632 assert_response :success
624 633
625 634 assert_select 'table.wiki-page-versions tbody' do
626 635 assert_select 'tr', 1
627 636 end
628 637
629 638 assert_select "input[type=submit][name=commit]", false
630 639 assert_select 'td' do
631 640 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1', :text => '1'
632 641 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1/annotate', :text => 'Annotate'
633 642 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1', :text => 'Delete', :count => 0
634 643 end
635 644 end
636 645
637 646 def test_diff
638 647 content = WikiPage.find(1).content
639 648 assert_difference 'WikiContent::Version.count', 2 do
640 649 content.text = "Line removed\nThis is a sample text for testing diffs"
641 650 content.save!
642 651 content.text = "This is a sample text for testing diffs\nLine added"
643 652 content.save!
644 653 end
645 654
646 655 get :diff, :params => {
647 656 :project_id => 1, :id => 'CookBook_documentation',
648 657 :version => content.version,
649 658 :version_from => (content.version - 1)
650 659 }
651 660 assert_response :success
652 661 assert_select 'span.diff_out', :text => 'Line removed'
653 662 assert_select 'span.diff_in', :text => 'Line added'
654 663 end
655 664
656 665 def test_diff_with_invalid_version_should_respond_with_404
657 666 get :diff, :params => {
658 667 :project_id => 1, :id => 'CookBook_documentation',
659 668 :version => '99'
660 669 }
661 670 assert_response 404
662 671 end
663 672
664 673 def test_diff_with_invalid_version_from_should_respond_with_404
665 674 get :diff, :params => {
666 675 :project_id => 1, :id => 'CookBook_documentation',
667 676 :version => '99',
668 677 :version_from => '98'
669 678 }
670 679 assert_response 404
671 680 end
672 681
673 682 def test_annotate
674 683 get :annotate, :params => {
675 684 :project_id => 1, :id => 'CookBook_documentation',
676 685 :version => 2
677 686 }
678 687 assert_response :success
679 688
680 689 # Line 1
681 690 assert_select 'table.annotate tr:nth-child(1)' do
682 691 assert_select 'th.line-num', :text => '1'
683 692 assert_select 'td.author', :text => /Redmine Admin/
684 693 assert_select 'td', :text => /h1\. CookBook documentation v2/
685 694 end
686 695
687 696 # Line 4
688 697 assert_select 'table.annotate tr:nth-child(4)' do
689 698 assert_select 'th.line-num', :text => '4'
690 699 assert_select 'td.author', :text => /John Smith/
691 700 assert_select 'td', :text => /Line from v1/
692 701 end
693 702
694 703 # Line 5
695 704 assert_select 'table.annotate tr:nth-child(5)' do
696 705 assert_select 'th.line-num', :text => '5'
697 706 assert_select 'td.author', :text => /Redmine Admin/
698 707 assert_select 'td', :text => /Some updated \[\[documentation\]\] here/
699 708 end
700 709 end
701 710
702 711 def test_annotate_with_invalid_version_should_respond_with_404
703 712 get :annotate, :params => {
704 713 :project_id => 1, :id => 'CookBook_documentation',
705 714 :version => '99'
706 715 }
707 716 assert_response 404
708 717 end
709 718
710 719 def test_get_rename
711 720 @request.session[:user_id] = 2
712 721 get :rename, :params => {:project_id => 1, :id => 'Another_page'}
713 722 assert_response :success
714 723
715 724 assert_select 'select[name=?]', 'wiki_page[parent_id]' do
716 725 assert_select 'option[value=""]', :text => ''
717 726 assert_select 'option[selected=selected]', 0
718 727 end
719 728 end
720 729
721 730 def test_get_rename_child_page
722 731 @request.session[:user_id] = 2
723 732 get :rename, :params => {:project_id => 1, :id => 'Child_1'}
724 733 assert_response :success
725 734
726 735 assert_select 'select[name=?]', 'wiki_page[parent_id]' do
727 736 assert_select 'option[value=""]', :text => ''
728 737 assert_select 'option[value="2"][selected=selected]', :text => /Another page/
729 738 end
730 739 end
731 740
732 741 def test_rename_with_redirect
733 742 @request.session[:user_id] = 2
734 743 post :rename, :params => {
735 744 :project_id => 1,
736 745 :id => 'Another_page',
737 746 :wiki_page => {
738 747 :title => 'Another renamed page',
739 748 :redirect_existing_links => 1
740 749 }
741 750 }
742 751 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
743 752 wiki = Project.find(1).wiki
744 753 # Check redirects
745 754 assert_not_nil wiki.find_page('Another page')
746 755 assert_nil wiki.find_page('Another page', :with_redirect => false)
747 756 end
748 757
749 758 def test_rename_without_redirect
750 759 @request.session[:user_id] = 2
751 760 post :rename, :params => {
752 761 :project_id => 1,
753 762 :id => 'Another_page',
754 763 :wiki_page => {
755 764 :title => 'Another renamed page',
756 765 :redirect_existing_links => "0"
757 766 }
758 767 }
759 768 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
760 769 wiki = Project.find(1).wiki
761 770 # Check that there's no redirects
762 771 assert_nil wiki.find_page('Another page')
763 772 end
764 773
765 774 def test_rename_with_parent_assignment
766 775 @request.session[:user_id] = 2
767 776 post :rename, :params => {
768 777 :project_id => 1,
769 778 :id => 'Another_page',
770 779 :wiki_page => {
771 780 :title => 'Another page',
772 781 :redirect_existing_links => "0",
773 782 :parent_id => '4'
774 783 }
775 784 }
776 785 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
777 786 assert_equal WikiPage.find(4), WikiPage.find_by_title('Another_page').parent
778 787 end
779 788
780 789 def test_rename_with_parent_unassignment
781 790 @request.session[:user_id] = 2
782 791 post :rename, :params => {
783 792 :project_id => 1,
784 793 :id => 'Child_1',
785 794 :wiki_page => {
786 795 :title => 'Child 1',
787 796 :redirect_existing_links => "0",
788 797 :parent_id => ''
789 798 }
790 799 }
791 800 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Child_1'
792 801 assert_nil WikiPage.find_by_title('Child_1').parent
793 802 end
794 803
795 804 def test_get_rename_should_show_target_projects_list
796 805 @request.session[:user_id] = 2
797 806 project = Project.find(5)
798 807 project.enable_module! :wiki
799 808
800 809 get :rename, :params => {:project_id => 1, :id => 'Another_page'}
801 810 assert_response :success
802 811
803 812 assert_select 'select[name=?]', 'wiki_page[wiki_id]' do
804 813 assert_select 'option', 2
805 814 assert_select 'option[value=?][selected=selected]', '1', :text => /eCookbook/
806 815 assert_select 'option[value=?]', project.wiki.id.to_s, :text => /#{project.name}/
807 816 end
808 817 end
809 818
810 819 def test_rename_with_move
811 820 @request.session[:user_id] = 2
812 821 project = Project.find(5)
813 822 project.enable_module! :wiki
814 823
815 824 post :rename, :params => {
816 825 :project_id => 1,
817 826 :id => 'Another_page',
818 827 :wiki_page => {
819 828 :wiki_id => project.wiki.id.to_s,
820 829 :title => 'Another renamed page',
821 830 :redirect_existing_links => 1
822 831 }
823 832 }
824 833 assert_redirected_to '/projects/private-child/wiki/Another_renamed_page'
825 834
826 835 page = WikiPage.find(2)
827 836 assert_equal project.wiki.id, page.wiki_id
828 837 end
829 838
830 839 def test_destroy_a_page_without_children_should_not_ask_confirmation
831 840 @request.session[:user_id] = 2
832 841 delete :destroy, :params => {:project_id => 1, :id => 'Child_2'}
833 842 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
834 843 end
835 844
836 845 def test_destroy_parent_should_ask_confirmation
837 846 @request.session[:user_id] = 2
838 847 assert_no_difference('WikiPage.count') do
839 848 delete :destroy, :params => {:project_id => 1, :id => 'Another_page'}
840 849 end
841 850 assert_response :success
842 851 assert_select 'form' do
843 852 assert_select 'input[name=todo][value=nullify]'
844 853 assert_select 'input[name=todo][value=destroy]'
845 854 assert_select 'input[name=todo][value=reassign]'
846 855 end
847 856 end
848 857
849 858 def test_destroy_parent_with_nullify_should_delete_parent_only
850 859 @request.session[:user_id] = 2
851 860 assert_difference('WikiPage.count', -1) do
852 861 delete :destroy, :params => {:project_id => 1, :id => 'Another_page', :todo => 'nullify'}
853 862 end
854 863 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
855 864 assert_nil WikiPage.find_by_id(2)
856 865 end
857 866
858 867 def test_destroy_parent_with_cascade_should_delete_descendants
859 868 @request.session[:user_id] = 2
860 869 assert_difference('WikiPage.count', -4) do
861 870 delete :destroy, :params => {:project_id => 1, :id => 'Another_page', :todo => 'destroy'}
862 871 end
863 872 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
864 873 assert_nil WikiPage.find_by_id(2)
865 874 assert_nil WikiPage.find_by_id(5)
866 875 end
867 876
868 877 def test_destroy_parent_with_reassign
869 878 @request.session[:user_id] = 2
870 879 assert_difference('WikiPage.count', -1) do
871 880 delete :destroy, :params => {:project_id => 1, :id => 'Another_page', :todo => 'reassign', :reassign_to_id => 1}
872 881 end
873 882 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
874 883 assert_nil WikiPage.find_by_id(2)
875 884 assert_equal WikiPage.find(1), WikiPage.find_by_id(5).parent
876 885 end
877 886
878 887 def test_destroy_version
879 888 @request.session[:user_id] = 2
880 889 assert_difference 'WikiContent::Version.count', -1 do
881 890 assert_no_difference 'WikiContent.count' do
882 891 assert_no_difference 'WikiPage.count' do
883 892 delete :destroy_version, :params => {:project_id => 'ecookbook', :id => 'CookBook_documentation', :version => 2}
884 893 assert_redirected_to '/projects/ecookbook/wiki/CookBook_documentation/history'
885 894 end
886 895 end
887 896 end
888 897 end
889 898
890 899 def test_destroy_invalid_version_should_respond_with_404
891 900 @request.session[:user_id] = 2
892 901 assert_no_difference 'WikiContent::Version.count' do
893 902 assert_no_difference 'WikiContent.count' do
894 903 assert_no_difference 'WikiPage.count' do
895 904 delete :destroy_version, :params => {:project_id => 'ecookbook', :id => 'CookBook_documentation', :version => 99}
896 905 end
897 906 end
898 907 end
899 908 assert_response 404
900 909 end
901 910
902 911 def test_index
903 912 get :index, :params => {:project_id => 'ecookbook'}
904 913 assert_response :success
905 914
906 915 assert_select 'ul.pages-hierarchy' do
907 916 assert_select 'li', Project.find(1).wiki.pages.count
908 917 end
909 918
910 919 assert_select 'ul.pages-hierarchy' do
911 920 assert_select 'li' do
912 921 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation', :text => 'CookBook documentation'
913 922 assert_select 'ul li a[href=?]', '/projects/ecookbook/wiki/Page_with_an_inline_image', :text => 'Page with an inline image'
914 923 end
915 924 assert_select 'li a[href=?]', '/projects/ecookbook/wiki/Another_page', :text => 'Another page'
916 925 end
917 926 end
918 927
919 928 def test_index_should_include_atom_link
920 929 get :index, :params => {:project_id => 'ecookbook'}
921 930 assert_select 'a[href=?]', '/projects/ecookbook/activity.atom?show_wiki_edits=1'
922 931 end
923 932
924 933 def test_export_to_html
925 934 @request.session[:user_id] = 2
926 935 get :export, :params => {:project_id => 'ecookbook'}
927 936
928 937 assert_response :success
929 938 assert_equal "text/html", @response.content_type
930 939
931 940 assert_select "a[name=?]", "CookBook_documentation"
932 941 assert_select "a[name=?]", "Another_page"
933 942 assert_select "a[name=?]", "Page_with_an_inline_image"
934 943 end
935 944
936 945 def test_export_to_pdf
937 946 @request.session[:user_id] = 2
938 947 get :export, :params => {:project_id => 'ecookbook', :format => 'pdf'}
939 948
940 949 assert_response :success
941 950 assert_equal 'application/pdf', @response.content_type
942 951 assert_equal 'attachment; filename="ecookbook.pdf"', @response.headers['Content-Disposition']
943 952 assert @response.body.starts_with?('%PDF')
944 953 end
945 954
946 955 def test_export_without_permission_should_be_denied
947 956 @request.session[:user_id] = 2
948 957 Role.find_by_name('Manager').remove_permission! :export_wiki_pages
949 958 get :export, :params => {:project_id => 'ecookbook'}
950 959
951 960 assert_response 403
952 961 end
953 962
954 963 def test_date_index
955 964 get :date_index, :params => {:project_id => 'ecookbook'}
956 965
957 966 assert_response :success
958 967
959 968 assert_select 'a[href=?]', '/projects/ecookbook/activity.atom?show_wiki_edits=1'
960 969 end
961 970
962 971 def test_not_found
963 972 get :show, :params => {:project_id => 999}
964 973 assert_response 404
965 974 end
966 975
967 976 def test_protect_page
968 977 page = WikiPage.find_by_wiki_id_and_title(1, 'Another_page')
969 978 assert !page.protected?
970 979 @request.session[:user_id] = 2
971 980 post :protect, :params => {:project_id => 1, :id => page.title, :protected => '1'}
972 981 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
973 982 assert page.reload.protected?
974 983 end
975 984
976 985 def test_unprotect_page
977 986 page = WikiPage.find_by_wiki_id_and_title(1, 'CookBook_documentation')
978 987 assert page.protected?
979 988 @request.session[:user_id] = 2
980 989 post :protect, :params => {:project_id => 1, :id => page.title, :protected => '0'}
981 990 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'CookBook_documentation'
982 991 assert !page.reload.protected?
983 992 end
984 993
985 994 def test_show_page_with_edit_link
986 995 @request.session[:user_id] = 2
987 996 get :show, :params => {:project_id => 1}
988 997 assert_response :success
989 998
990 999 assert_select 'a[href=?]', '/projects/1/wiki/CookBook_documentation/edit'
991 1000 end
992 1001
993 1002 def test_show_page_without_edit_link
994 1003 @request.session[:user_id] = 4
995 1004 get :show, :params => {:project_id => 1}
996 1005 assert_response :success
997 1006
998 1007 assert_select 'a[href=?]', '/projects/1/wiki/CookBook_documentation/edit', 0
999 1008 end
1000 1009
1001 1010 def test_show_pdf
1002 1011 @request.session[:user_id] = 2
1003 1012 get :show, :params => {:project_id => 1, :format => 'pdf'}
1004 1013 assert_response :success
1005 1014
1006 1015 assert_equal 'application/pdf', @response.content_type
1007 1016 assert_equal 'attachment; filename="CookBook_documentation.pdf"',
1008 1017 @response.headers['Content-Disposition']
1009 1018 end
1010 1019
1011 1020 def test_show_html
1012 1021 @request.session[:user_id] = 2
1013 1022 get :show, :params => {:project_id => 1, :format => 'html'}
1014 1023 assert_response :success
1015 1024
1016 1025 assert_equal 'text/html', @response.content_type
1017 1026 assert_equal 'attachment; filename="CookBook_documentation.html"',
1018 1027 @response.headers['Content-Disposition']
1019 1028 assert_select 'h1', :text => /CookBook documentation/
1020 1029 end
1021 1030
1022 1031 def test_show_versioned_html
1023 1032 @request.session[:user_id] = 2
1024 1033 get :show, :params => {:project_id => 1, :format => 'html', :version => 2}
1025 1034 assert_response :success
1026 1035
1027 1036 assert_equal 'text/html', @response.content_type
1028 1037 assert_equal 'attachment; filename="CookBook_documentation.html"',
1029 1038 @response.headers['Content-Disposition']
1030 1039 assert_select 'h1', :text => /CookBook documentation v2/
1031 1040 end
1032 1041
1033 1042 def test_show_txt
1034 1043 @request.session[:user_id] = 2
1035 1044 get :show, :params => {:project_id => 1, :format => 'txt'}
1036 1045 assert_response :success
1037 1046
1038 1047 assert_equal 'text/plain', @response.content_type
1039 1048 assert_equal 'attachment; filename="CookBook_documentation.txt"',
1040 1049 @response.headers['Content-Disposition']
1041 1050 assert_include 'h1. CookBook documentation', @response.body
1042 1051 end
1043 1052
1044 1053 def test_show_versioned_txt
1045 1054 @request.session[:user_id] = 2
1046 1055 get :show, :params => {:project_id => 1, :format => 'txt', :version => 2}
1047 1056 assert_response :success
1048 1057
1049 1058 assert_equal 'text/plain', @response.content_type
1050 1059 assert_equal 'attachment; filename="CookBook_documentation.txt"',
1051 1060 @response.headers['Content-Disposition']
1052 1061 assert_include 'h1. CookBook documentation v2', @response.body
1053 1062 end
1054 1063
1055 1064 def test_edit_unprotected_page
1056 1065 # Non members can edit unprotected wiki pages
1057 1066 @request.session[:user_id] = 4
1058 1067 get :edit, :params => {:project_id => 1, :id => 'Another_page'}
1059 1068 assert_response :success
1060 1069 end
1061 1070
1062 1071 def test_edit_protected_page_by_nonmember
1063 1072 # Non members cannot edit protected wiki pages
1064 1073 @request.session[:user_id] = 4
1065 1074 get :edit, :params => {:project_id => 1, :id => 'CookBook_documentation'}
1066 1075 assert_response 403
1067 1076 end
1068 1077
1069 1078 def test_edit_protected_page_by_member
1070 1079 @request.session[:user_id] = 2
1071 1080 get :edit, :params => {:project_id => 1, :id => 'CookBook_documentation'}
1072 1081 assert_response :success
1073 1082 end
1074 1083
1075 1084 def test_history_of_non_existing_page_should_return_404
1076 1085 get :history, :params => {:project_id => 1, :id => 'Unknown_page'}
1077 1086 assert_response 404
1078 1087 end
1079 1088
1080 1089 def test_add_attachment
1081 1090 @request.session[:user_id] = 2
1082 1091 assert_difference 'Attachment.count' do
1083 1092 post :add_attachment, :params => {
1084 1093 :project_id => 1,
1085 1094 :id => 'CookBook_documentation',
1086 1095 :attachments => {
1087 1096 '1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
1088 1097 }
1089 1098 }
1090 1099 end
1091 1100 attachment = Attachment.order('id DESC').first
1092 1101 assert_equal Wiki.find(1).find_page('CookBook_documentation'), attachment.container
1093 1102 end
1094 1103 end
General Comments 0
You need to be logged in to leave comments. Login now