##// END OF EJS Templates
Merged r15749 (#23700)....
Jean-Philippe Lang -
r15389:9f8053a82eba
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_filter :find_wiki, :authorize
35 35 before_filter :find_existing_or_new_page, :only => [:show, :edit, :update]
36 36 before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy, :destroy_version]
37 37 accept_api_auth :index, :show, :update, :destroy
38 38 before_filter :find_attachments, :only => [:preview]
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,1022 +1,1031
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 < ActionController::TestCase
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, :project_id => 'ecookbook'
32 32 assert_response :success
33 33 assert_template 'show'
34 34 assert_select 'h1', :text => /CookBook documentation/
35 35
36 36 # child_pages macro
37 37 assert_select 'ul.pages-hierarchy>li>a[href=?]', '/projects/ecookbook/wiki/Page_with_an_inline_image',
38 38 :text => 'Page with an inline image'
39 39 end
40 40
41 41 def test_export_link
42 42 Role.anonymous.add_permission! :export_wiki_pages
43 43 get :show, :project_id => 'ecookbook'
44 44 assert_response :success
45 45 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation.txt'
46 46 end
47 47
48 48 def test_show_page_with_name
49 49 get :show, :project_id => 1, :id => 'Another_page'
50 50 assert_response :success
51 51 assert_template 'show'
52 52 assert_select 'h1', :text => /Another page/
53 53 # Included page with an inline image
54 54 assert_select 'p', :text => /This is an inline image/
55 55 assert_select 'img[src=?][alt=?]', '/attachments/download/3/logo.gif', 'This is a logo'
56 56 end
57 57
58 58 def test_show_old_version
59 59 with_settings :default_language => 'en' do
60 60 get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '2'
61 61 end
62 62 assert_response :success
63 63 assert_template 'show'
64 64
65 65 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/1', :text => /Previous/
66 66 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2/diff', :text => /diff/
67 67 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/3', :text => /Next/
68 68 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation', :text => /Current version/
69 69 end
70 70
71 71 def test_show_old_version_with_attachments
72 72 page = WikiPage.find(4)
73 73 assert page.attachments.any?
74 74 content = page.content
75 75 content.text = "update"
76 76 content.save!
77 77
78 78 get :show, :project_id => 'ecookbook', :id => page.title, :version => '1'
79 79 assert_kind_of WikiContent::Version, assigns(:content)
80 80 assert_response :success
81 81 assert_template 'show'
82 82 end
83 83
84 84 def test_show_old_version_without_permission_should_be_denied
85 85 Role.anonymous.remove_permission! :view_wiki_edits
86 86
87 87 get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '2'
88 88 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fprojects%2Fecookbook%2Fwiki%2FCookBook_documentation%2F2'
89 89 end
90 90
91 91 def test_show_first_version
92 92 with_settings :default_language => 'en' do
93 93 get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '1'
94 94 end
95 95 assert_response :success
96 96 assert_template 'show'
97 97
98 98 assert_select 'a', :text => /Previous/, :count => 0
99 99 assert_select 'a', :text => /diff/, :count => 0
100 100 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => /Next/
101 101 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation', :text => /Current version/
102 102 end
103 103
104 104 def test_show_redirected_page
105 105 WikiRedirect.create!(:wiki_id => 1, :title => 'Old_title', :redirects_to => 'Another_page')
106 106
107 107 get :show, :project_id => 'ecookbook', :id => 'Old_title'
108 108 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
109 109 end
110 110
111 111 def test_show_with_sidebar
112 112 page = Project.find(1).wiki.pages.new(:title => 'Sidebar')
113 113 page.content = WikiContent.new(:text => 'Side bar content for test_show_with_sidebar')
114 114 page.save!
115 115
116 116 get :show, :project_id => 1, :id => 'Another_page'
117 117 assert_response :success
118 118 assert_select 'div#sidebar', :text => /Side bar content for test_show_with_sidebar/
119 119 end
120 120
121 121 def test_show_should_display_section_edit_links
122 122 @request.session[:user_id] = 2
123 123 get :show, :project_id => 1, :id => 'Page with sections'
124 124
125 125 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=1', 0
126 126 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
127 127 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=3'
128 128 end
129 129
130 130 def test_show_current_version_should_display_section_edit_links
131 131 @request.session[:user_id] = 2
132 132 get :show, :project_id => 1, :id => 'Page with sections', :version => 3
133 133
134 134 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
135 135 end
136 136
137 137 def test_show_old_version_should_not_display_section_edit_links
138 138 @request.session[:user_id] = 2
139 139 get :show, :project_id => 1, :id => 'Page with sections', :version => 2
140 140
141 141 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=2', 0
142 142 end
143 143
144 144 def test_show_unexistent_page_without_edit_right
145 145 get :show, :project_id => 1, :id => 'Unexistent page'
146 146 assert_response 404
147 147 end
148 148
149 149 def test_show_unexistent_page_with_edit_right
150 150 @request.session[:user_id] = 2
151 151 get :show, :project_id => 1, :id => 'Unexistent page'
152 152 assert_response :success
153 153 assert_template 'edit'
154 154 end
155 155
156 156 def test_show_specific_version_of_an_unexistent_page_without_edit_right
157 157 get :show, :project_id => 1, :id => 'Unexistent page', :version => 1
158 158 assert_response 404
159 159 end
160 160
161 161 def test_show_unexistent_page_with_parent_should_preselect_parent
162 162 @request.session[:user_id] = 2
163 163 get :show, :project_id => 1, :id => 'Unexistent page', :parent => 'Another_page'
164 164 assert_response :success
165 165 assert_template 'edit'
166 166 assert_select 'select[name=?] option[value="2"][selected=selected]', 'wiki_page[parent_id]'
167 167 end
168 168
169 169 def test_show_should_not_show_history_without_permission
170 170 Role.anonymous.remove_permission! :view_wiki_edits
171 171 get :show, :project_id => 1, :id => 'Page with sections', :version => 2
172 172
173 173 assert_response 302
174 174 end
175 175
176 176 def test_show_page_without_content_should_display_the_edit_form
177 177 @request.session[:user_id] = 2
178 178 WikiPage.create!(:title => 'NoContent', :wiki => Project.find(1).wiki)
179 179
180 180 get :show, :project_id => 1, :id => 'NoContent'
181 181 assert_response :success
182 182 assert_template 'edit'
183 183 assert_select 'textarea[name=?]', 'content[text]'
184 184 end
185 185
186 186 def test_get_new
187 187 @request.session[:user_id] = 2
188 188
189 189 get :new, :project_id => 'ecookbook'
190 190 assert_response :success
191 191 assert_template 'new'
192 192 end
193 193
194 194 def test_get_new_xhr
195 195 @request.session[:user_id] = 2
196 196
197 197 xhr :get, :new, :project_id => 'ecookbook'
198 198 assert_response :success
199 199 assert_template 'new'
200 200 end
201 201
202 202 def test_post_new_with_valid_title_should_redirect_to_edit
203 203 @request.session[:user_id] = 2
204 204
205 205 post :new, :project_id => 'ecookbook', :title => 'New Page'
206 206 assert_redirected_to '/projects/ecookbook/wiki/New_Page'
207 207 end
208 208
209 209 def test_post_new_xhr_with_valid_title_should_redirect_to_edit
210 210 @request.session[:user_id] = 2
211 211
212 212 xhr :post, :new, :project_id => 'ecookbook', :title => 'New Page'
213 213 assert_response :success
214 214 assert_equal 'window.location = "/projects/ecookbook/wiki/New_Page"', response.body
215 215 end
216 216
217 217 def test_post_new_with_invalid_title_should_display_errors
218 218 @request.session[:user_id] = 2
219 219
220 220 post :new, :project_id => 'ecookbook', :title => 'Another page'
221 221 assert_response :success
222 222 assert_template 'new'
223 223 assert_select_error 'Title has already been taken'
224 224 end
225 225
226 def test_post_new_with_protected_title_should_display_errors
227 Role.find(1).remove_permission!(:protect_wiki_pages)
228 @request.session[:user_id] = 2
229
230 post :new, :params => {:project_id => 'ecookbook', :title => 'Sidebar'}
231 assert_response :success
232 assert_select_error /Title/
233 end
234
226 235 def test_post_new_xhr_with_invalid_title_should_display_errors
227 236 @request.session[:user_id] = 2
228 237
229 238 xhr :post, :new, :project_id => 'ecookbook', :title => 'Another page'
230 239 assert_response :success
231 240 assert_template 'new'
232 241 assert_include 'Title has already been taken', response.body
233 242 end
234 243
235 244 def test_create_page
236 245 @request.session[:user_id] = 2
237 246 assert_difference 'WikiPage.count' do
238 247 assert_difference 'WikiContent.count' do
239 248 put :update, :project_id => 1,
240 249 :id => 'New page',
241 250 :content => {:comments => 'Created the page',
242 251 :text => "h1. New page\n\nThis is a new page",
243 252 :version => 0}
244 253 end
245 254 end
246 255 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'New_page'
247 256 page = Project.find(1).wiki.find_page('New page')
248 257 assert !page.new_record?
249 258 assert_not_nil page.content
250 259 assert_nil page.parent
251 260 assert_equal 'Created the page', page.content.comments
252 261 end
253 262
254 263 def test_create_page_with_attachments
255 264 @request.session[:user_id] = 2
256 265 assert_difference 'WikiPage.count' do
257 266 assert_difference 'Attachment.count' do
258 267 put :update, :project_id => 1,
259 268 :id => 'New page',
260 269 :content => {:comments => 'Created the page',
261 270 :text => "h1. New page\n\nThis is a new page",
262 271 :version => 0},
263 272 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
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, :project_id => 1, :id => 'New page',
275 284 :content => {:text => "h1. New page\n\nThis is a new page", :version => 0},
276 285 :wiki_page => {:parent_id => 2}
277 286 end
278 287 page = Project.find(1).wiki.find_page('New page')
279 288 assert_equal WikiPage.find(2), page.parent
280 289 end
281 290
282 291 def test_edit_page
283 292 @request.session[:user_id] = 2
284 293 get :edit, :project_id => 'ecookbook', :id => 'Another_page'
285 294
286 295 assert_response :success
287 296 assert_template 'edit'
288 297
289 298 assert_select 'textarea[name=?]', 'content[text]',
290 299 :text => WikiPage.find_by_title('Another_page').content.text
291 300 end
292 301
293 302 def test_edit_section
294 303 @request.session[:user_id] = 2
295 304 get :edit, :project_id => 'ecookbook', :id => 'Page_with_sections', :section => 2
296 305
297 306 assert_response :success
298 307 assert_template 'edit'
299 308
300 309 page = WikiPage.find_by_title('Page_with_sections')
301 310 section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
302 311
303 312 assert_select 'textarea[name=?]', 'content[text]', :text => section
304 313 assert_select 'input[name=section][type=hidden][value="2"]'
305 314 assert_select 'input[name=section_hash][type=hidden][value=?]', hash
306 315 end
307 316
308 317 def test_edit_invalid_section_should_respond_with_404
309 318 @request.session[:user_id] = 2
310 319 get :edit, :project_id => 'ecookbook', :id => 'Page_with_sections', :section => 10
311 320
312 321 assert_response 404
313 322 end
314 323
315 324 def test_update_page
316 325 @request.session[:user_id] = 2
317 326 assert_no_difference 'WikiPage.count' do
318 327 assert_no_difference 'WikiContent.count' do
319 328 assert_difference 'WikiContent::Version.count' do
320 329 put :update, :project_id => 1,
321 330 :id => 'Another_page',
322 331 :content => {
323 332 :comments => "my comments",
324 333 :text => "edited",
325 334 :version => 1
326 335 }
327 336 end
328 337 end
329 338 end
330 339 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
331 340
332 341 page = Wiki.find(1).pages.find_by_title('Another_page')
333 342 assert_equal "edited", page.content.text
334 343 assert_equal 2, page.content.version
335 344 assert_equal "my comments", page.content.comments
336 345 end
337 346
338 347 def test_update_page_with_parent
339 348 @request.session[:user_id] = 2
340 349 assert_no_difference 'WikiPage.count' do
341 350 assert_no_difference 'WikiContent.count' do
342 351 assert_difference 'WikiContent::Version.count' do
343 352 put :update, :project_id => 1,
344 353 :id => 'Another_page',
345 354 :content => {
346 355 :comments => "my comments",
347 356 :text => "edited",
348 357 :version => 1
349 358 },
350 359 :wiki_page => {:parent_id => '1'}
351 360 end
352 361 end
353 362 end
354 363 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
355 364
356 365 page = Wiki.find(1).pages.find_by_title('Another_page')
357 366 assert_equal "edited", page.content.text
358 367 assert_equal 2, page.content.version
359 368 assert_equal "my comments", page.content.comments
360 369 assert_equal WikiPage.find(1), page.parent
361 370 end
362 371
363 372 def test_update_page_with_failure
364 373 @request.session[:user_id] = 2
365 374 assert_no_difference 'WikiPage.count' do
366 375 assert_no_difference 'WikiContent.count' do
367 376 assert_no_difference 'WikiContent::Version.count' do
368 377 put :update, :project_id => 1,
369 378 :id => 'Another_page',
370 379 :content => {
371 380 :comments => 'a' * 1300, # failure here, comment is too long
372 381 :text => 'edited'
373 382 },
374 383 :wiki_page => {
375 384 :parent_id => ""
376 385 }
377 386 end
378 387 end
379 388 end
380 389 assert_response :success
381 390 assert_template 'edit'
382 391
383 392 assert_select_error /Comment is too long/
384 393 assert_select 'textarea#content_text', :text => "edited"
385 394 assert_select 'input#content_version[value="1"]'
386 395 end
387 396
388 397 def test_update_page_with_parent_change_only_should_not_create_content_version
389 398 @request.session[:user_id] = 2
390 399 assert_no_difference 'WikiPage.count' do
391 400 assert_no_difference 'WikiContent.count' do
392 401 assert_no_difference 'WikiContent::Version.count' do
393 402 put :update, :project_id => 1,
394 403 :id => 'Another_page',
395 404 :content => {
396 405 :comments => '',
397 406 :text => Wiki.find(1).find_page('Another_page').content.text,
398 407 :version => 1
399 408 },
400 409 :wiki_page => {:parent_id => '1'}
401 410 end
402 411 end
403 412 end
404 413 page = Wiki.find(1).pages.find_by_title('Another_page')
405 414 assert_equal 1, page.content.version
406 415 assert_equal WikiPage.find(1), page.parent
407 416 end
408 417
409 418 def test_update_page_with_attachments_only_should_not_create_content_version
410 419 @request.session[:user_id] = 2
411 420 assert_no_difference 'WikiPage.count' do
412 421 assert_no_difference 'WikiContent.count' do
413 422 assert_no_difference 'WikiContent::Version.count' do
414 423 assert_difference 'Attachment.count' do
415 424 put :update, :project_id => 1,
416 425 :id => 'Another_page',
417 426 :content => {
418 427 :comments => '',
419 428 :text => Wiki.find(1).find_page('Another_page').content.text,
420 429 :version => 1
421 430 },
422 431 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
423 432 end
424 433 end
425 434 end
426 435 end
427 436 page = Wiki.find(1).pages.find_by_title('Another_page')
428 437 assert_equal 1, page.content.version
429 438 end
430 439
431 440 def test_update_stale_page_should_not_raise_an_error
432 441 @request.session[:user_id] = 2
433 442 c = Wiki.find(1).find_page('Another_page').content
434 443 c.text = 'Previous text'
435 444 c.save!
436 445 assert_equal 2, c.version
437 446
438 447 assert_no_difference 'WikiPage.count' do
439 448 assert_no_difference 'WikiContent.count' do
440 449 assert_no_difference 'WikiContent::Version.count' do
441 450 put :update, :project_id => 1,
442 451 :id => 'Another_page',
443 452 :content => {
444 453 :comments => 'My comments',
445 454 :text => 'Text should not be lost',
446 455 :version => 1
447 456 }
448 457 end
449 458 end
450 459 end
451 460 assert_response :success
452 461 assert_template 'edit'
453 462 assert_select 'div.error', :text => /Data has been updated by another user/
454 463 assert_select 'textarea[name=?]', 'content[text]', :text => /Text should not be lost/
455 464 assert_select 'input[name=?][value=?]', 'content[comments]', 'My comments'
456 465
457 466 c.reload
458 467 assert_equal 'Previous text', c.text
459 468 assert_equal 2, c.version
460 469 end
461 470
462 471 def test_update_page_without_content_should_create_content
463 472 @request.session[:user_id] = 2
464 473 page = WikiPage.create!(:title => 'NoContent', :wiki => Project.find(1).wiki)
465 474
466 475 assert_no_difference 'WikiPage.count' do
467 476 assert_difference 'WikiContent.count' do
468 477 put :update, :project_id => 1, :id => 'NoContent', :content => {:text => 'Some content'}
469 478 assert_response 302
470 479 end
471 480 end
472 481 assert_equal 'Some content', page.reload.content.text
473 482 end
474 483
475 484 def test_update_section
476 485 @request.session[:user_id] = 2
477 486 page = WikiPage.find_by_title('Page_with_sections')
478 487 section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
479 488 text = page.content.text
480 489
481 490 assert_no_difference 'WikiPage.count' do
482 491 assert_no_difference 'WikiContent.count' do
483 492 assert_difference 'WikiContent::Version.count' do
484 493 put :update, :project_id => 1, :id => 'Page_with_sections',
485 494 :content => {
486 495 :text => "New section content",
487 496 :version => 3
488 497 },
489 498 :section => 2,
490 499 :section_hash => hash
491 500 end
492 501 end
493 502 end
494 503 assert_redirected_to '/projects/ecookbook/wiki/Page_with_sections#section-2'
495 504 assert_equal Redmine::WikiFormatting::Textile::Formatter.new(text).update_section(2, "New section content"), page.reload.content.text
496 505 end
497 506
498 507 def test_update_section_should_allow_stale_page_update
499 508 @request.session[:user_id] = 2
500 509 page = WikiPage.find_by_title('Page_with_sections')
501 510 section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
502 511 text = page.content.text
503 512
504 513 assert_no_difference 'WikiPage.count' do
505 514 assert_no_difference 'WikiContent.count' do
506 515 assert_difference 'WikiContent::Version.count' do
507 516 put :update, :project_id => 1, :id => 'Page_with_sections',
508 517 :content => {
509 518 :text => "New section content",
510 519 :version => 2 # Current version is 3
511 520 },
512 521 :section => 2,
513 522 :section_hash => hash
514 523 end
515 524 end
516 525 end
517 526 assert_redirected_to '/projects/ecookbook/wiki/Page_with_sections#section-2'
518 527 page.reload
519 528 assert_equal Redmine::WikiFormatting::Textile::Formatter.new(text).update_section(2, "New section content"), page.content.text
520 529 assert_equal 4, page.content.version
521 530 end
522 531
523 532 def test_update_section_should_not_allow_stale_section_update
524 533 @request.session[:user_id] = 2
525 534
526 535 assert_no_difference 'WikiPage.count' do
527 536 assert_no_difference 'WikiContent.count' do
528 537 assert_no_difference 'WikiContent::Version.count' do
529 538 put :update, :project_id => 1, :id => 'Page_with_sections',
530 539 :content => {
531 540 :comments => 'My comments',
532 541 :text => "Text should not be lost",
533 542 :version => 3
534 543 },
535 544 :section => 2,
536 545 :section_hash => Digest::MD5.hexdigest("wrong hash")
537 546 end
538 547 end
539 548 end
540 549 assert_response :success
541 550 assert_template 'edit'
542 551 assert_select 'div.error', :text => /Data has been updated by another user/
543 552 assert_select 'textarea[name=?]', 'content[text]', :text => /Text should not be lost/
544 553 assert_select 'input[name=?][value=?]', 'content[comments]', 'My comments'
545 554 end
546 555
547 556 def test_preview
548 557 @request.session[:user_id] = 2
549 558 xhr :post, :preview, :project_id => 1, :id => 'CookBook_documentation',
550 559 :content => { :comments => '',
551 560 :text => 'this is a *previewed text*',
552 561 :version => 3 }
553 562 assert_response :success
554 563 assert_template 'common/_preview'
555 564 assert_select 'strong', :text => /previewed text/
556 565 end
557 566
558 567 def test_preview_new_page
559 568 @request.session[:user_id] = 2
560 569 xhr :post, :preview, :project_id => 1, :id => 'New page',
561 570 :content => { :text => 'h1. New page',
562 571 :comments => '',
563 572 :version => 0 }
564 573 assert_response :success
565 574 assert_template 'common/_preview'
566 575 assert_select 'h1', :text => /New page/
567 576 end
568 577
569 578 def test_history
570 579 @request.session[:user_id] = 2
571 580 get :history, :project_id => 'ecookbook', :id => 'CookBook_documentation'
572 581 assert_response :success
573 582 assert_template 'history'
574 583 assert_not_nil assigns(:versions)
575 584 assert_equal 3, assigns(:versions).size
576 585
577 586 assert_select "input[type=submit][name=commit]"
578 587 assert_select 'td' do
579 588 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => '2'
580 589 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2/annotate', :text => 'Annotate'
581 590 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => 'Delete'
582 591 end
583 592 end
584 593
585 594 def test_history_with_one_version
586 595 @request.session[:user_id] = 2
587 596 get :history, :project_id => 'ecookbook', :id => 'Another_page'
588 597 assert_response :success
589 598 assert_template 'history'
590 599 assert_not_nil assigns(:versions)
591 600 assert_equal 1, assigns(:versions).size
592 601 assert_select "input[type=submit][name=commit]", false
593 602 assert_select 'td' do
594 603 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1', :text => '1'
595 604 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1/annotate', :text => 'Annotate'
596 605 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1', :text => 'Delete', :count => 0
597 606 end
598 607 end
599 608
600 609 def test_diff
601 610 content = WikiPage.find(1).content
602 611 assert_difference 'WikiContent::Version.count', 2 do
603 612 content.text = "Line removed\nThis is a sample text for testing diffs"
604 613 content.save!
605 614 content.text = "This is a sample text for testing diffs\nLine added"
606 615 content.save!
607 616 end
608 617
609 618 get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => content.version, :version_from => (content.version - 1)
610 619 assert_response :success
611 620 assert_template 'diff'
612 621 assert_select 'span.diff_out', :text => 'Line removed'
613 622 assert_select 'span.diff_in', :text => 'Line added'
614 623 end
615 624
616 625 def test_diff_with_invalid_version_should_respond_with_404
617 626 get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => '99'
618 627 assert_response 404
619 628 end
620 629
621 630 def test_diff_with_invalid_version_from_should_respond_with_404
622 631 get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => '99', :version_from => '98'
623 632 assert_response 404
624 633 end
625 634
626 635 def test_annotate
627 636 get :annotate, :project_id => 1, :id => 'CookBook_documentation', :version => 2
628 637 assert_response :success
629 638 assert_template 'annotate'
630 639
631 640 # Line 1
632 641 assert_select 'table.annotate tr:nth-child(1)' do
633 642 assert_select 'th.line-num', :text => '1'
634 643 assert_select 'td.author', :text => /John Smith/
635 644 assert_select 'td', :text => /h1\. CookBook documentation/
636 645 end
637 646
638 647 # Line 5
639 648 assert_select 'table.annotate tr:nth-child(5)' do
640 649 assert_select 'th.line-num', :text => '5'
641 650 assert_select 'td.author', :text => /Redmine Admin/
642 651 assert_select 'td', :text => /Some updated \[\[documentation\]\] here/
643 652 end
644 653 end
645 654
646 655 def test_annotate_with_invalid_version_should_respond_with_404
647 656 get :annotate, :project_id => 1, :id => 'CookBook_documentation', :version => '99'
648 657 assert_response 404
649 658 end
650 659
651 660 def test_get_rename
652 661 @request.session[:user_id] = 2
653 662 get :rename, :project_id => 1, :id => 'Another_page'
654 663 assert_response :success
655 664 assert_template 'rename'
656 665
657 666 assert_select 'select[name=?]', 'wiki_page[parent_id]' do
658 667 assert_select 'option[value=""]', :text => ''
659 668 assert_select 'option[selected=selected]', 0
660 669 end
661 670 end
662 671
663 672 def test_get_rename_child_page
664 673 @request.session[:user_id] = 2
665 674 get :rename, :project_id => 1, :id => 'Child_1'
666 675 assert_response :success
667 676 assert_template 'rename'
668 677
669 678 assert_select 'select[name=?]', 'wiki_page[parent_id]' do
670 679 assert_select 'option[value=""]', :text => ''
671 680 assert_select 'option[value="2"][selected=selected]', :text => /Another page/
672 681 end
673 682 end
674 683
675 684 def test_rename_with_redirect
676 685 @request.session[:user_id] = 2
677 686 post :rename, :project_id => 1, :id => 'Another_page',
678 687 :wiki_page => { :title => 'Another renamed page',
679 688 :redirect_existing_links => 1 }
680 689 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
681 690 wiki = Project.find(1).wiki
682 691 # Check redirects
683 692 assert_not_nil wiki.find_page('Another page')
684 693 assert_nil wiki.find_page('Another page', :with_redirect => false)
685 694 end
686 695
687 696 def test_rename_without_redirect
688 697 @request.session[:user_id] = 2
689 698 post :rename, :project_id => 1, :id => 'Another_page',
690 699 :wiki_page => { :title => 'Another renamed page',
691 700 :redirect_existing_links => "0" }
692 701 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
693 702 wiki = Project.find(1).wiki
694 703 # Check that there's no redirects
695 704 assert_nil wiki.find_page('Another page')
696 705 end
697 706
698 707 def test_rename_with_parent_assignment
699 708 @request.session[:user_id] = 2
700 709 post :rename, :project_id => 1, :id => 'Another_page',
701 710 :wiki_page => { :title => 'Another page', :redirect_existing_links => "0", :parent_id => '4' }
702 711 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
703 712 assert_equal WikiPage.find(4), WikiPage.find_by_title('Another_page').parent
704 713 end
705 714
706 715 def test_rename_with_parent_unassignment
707 716 @request.session[:user_id] = 2
708 717 post :rename, :project_id => 1, :id => 'Child_1',
709 718 :wiki_page => { :title => 'Child 1', :redirect_existing_links => "0", :parent_id => '' }
710 719 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Child_1'
711 720 assert_nil WikiPage.find_by_title('Child_1').parent
712 721 end
713 722
714 723 def test_get_rename_should_show_target_projects_list
715 724 @request.session[:user_id] = 2
716 725 project = Project.find(5)
717 726 project.enable_module! :wiki
718 727
719 728 get :rename, :project_id => 1, :id => 'Another_page'
720 729 assert_response :success
721 730 assert_template 'rename'
722 731
723 732 assert_select 'select[name=?]', 'wiki_page[wiki_id]' do
724 733 assert_select 'option', 2
725 734 assert_select 'option[value=?][selected=selected]', '1', :text => /eCookbook/
726 735 assert_select 'option[value=?]', project.wiki.id.to_s, :text => /#{project.name}/
727 736 end
728 737 end
729 738
730 739 def test_rename_with_move
731 740 @request.session[:user_id] = 2
732 741 project = Project.find(5)
733 742 project.enable_module! :wiki
734 743
735 744 post :rename, :project_id => 1, :id => 'Another_page',
736 745 :wiki_page => {
737 746 :wiki_id => project.wiki.id.to_s,
738 747 :title => 'Another renamed page',
739 748 :redirect_existing_links => 1
740 749 }
741 750 assert_redirected_to '/projects/private-child/wiki/Another_renamed_page'
742 751
743 752 page = WikiPage.find(2)
744 753 assert_equal project.wiki.id, page.wiki_id
745 754 end
746 755
747 756 def test_destroy_a_page_without_children_should_not_ask_confirmation
748 757 @request.session[:user_id] = 2
749 758 delete :destroy, :project_id => 1, :id => 'Child_2'
750 759 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
751 760 end
752 761
753 762 def test_destroy_parent_should_ask_confirmation
754 763 @request.session[:user_id] = 2
755 764 assert_no_difference('WikiPage.count') do
756 765 delete :destroy, :project_id => 1, :id => 'Another_page'
757 766 end
758 767 assert_response :success
759 768 assert_template 'destroy'
760 769 assert_select 'form' do
761 770 assert_select 'input[name=todo][value=nullify]'
762 771 assert_select 'input[name=todo][value=destroy]'
763 772 assert_select 'input[name=todo][value=reassign]'
764 773 end
765 774 end
766 775
767 776 def test_destroy_parent_with_nullify_should_delete_parent_only
768 777 @request.session[:user_id] = 2
769 778 assert_difference('WikiPage.count', -1) do
770 779 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'nullify'
771 780 end
772 781 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
773 782 assert_nil WikiPage.find_by_id(2)
774 783 end
775 784
776 785 def test_destroy_parent_with_cascade_should_delete_descendants
777 786 @request.session[:user_id] = 2
778 787 assert_difference('WikiPage.count', -4) do
779 788 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'destroy'
780 789 end
781 790 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
782 791 assert_nil WikiPage.find_by_id(2)
783 792 assert_nil WikiPage.find_by_id(5)
784 793 end
785 794
786 795 def test_destroy_parent_with_reassign
787 796 @request.session[:user_id] = 2
788 797 assert_difference('WikiPage.count', -1) do
789 798 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'reassign', :reassign_to_id => 1
790 799 end
791 800 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
792 801 assert_nil WikiPage.find_by_id(2)
793 802 assert_equal WikiPage.find(1), WikiPage.find_by_id(5).parent
794 803 end
795 804
796 805 def test_destroy_version
797 806 @request.session[:user_id] = 2
798 807 assert_difference 'WikiContent::Version.count', -1 do
799 808 assert_no_difference 'WikiContent.count' do
800 809 assert_no_difference 'WikiPage.count' do
801 810 delete :destroy_version, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => 2
802 811 assert_redirected_to '/projects/ecookbook/wiki/CookBook_documentation/history'
803 812 end
804 813 end
805 814 end
806 815 end
807 816
808 817 def test_destroy_invalid_version_should_respond_with_404
809 818 @request.session[:user_id] = 2
810 819 assert_no_difference 'WikiContent::Version.count' do
811 820 assert_no_difference 'WikiContent.count' do
812 821 assert_no_difference 'WikiPage.count' do
813 822 delete :destroy_version, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => 99
814 823 end
815 824 end
816 825 end
817 826 assert_response 404
818 827 end
819 828
820 829 def test_index
821 830 get :index, :project_id => 'ecookbook'
822 831 assert_response :success
823 832 assert_template 'index'
824 833 pages = assigns(:pages)
825 834 assert_not_nil pages
826 835 assert_equal Project.find(1).wiki.pages.size, pages.size
827 836 assert_equal pages.first.content.updated_on, pages.first.updated_on
828 837
829 838 assert_select 'ul.pages-hierarchy' do
830 839 assert_select 'li' do
831 840 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation', :text => 'CookBook documentation'
832 841 assert_select 'ul li a[href=?]', '/projects/ecookbook/wiki/Page_with_an_inline_image', :text => 'Page with an inline image'
833 842 end
834 843 assert_select 'li a[href=?]', '/projects/ecookbook/wiki/Another_page', :text => 'Another page'
835 844 end
836 845 end
837 846
838 847 def test_index_should_include_atom_link
839 848 get :index, :project_id => 'ecookbook'
840 849 assert_select 'a[href=?]', '/projects/ecookbook/activity.atom?show_wiki_edits=1'
841 850 end
842 851
843 852 def test_export_to_html
844 853 @request.session[:user_id] = 2
845 854 get :export, :project_id => 'ecookbook'
846 855
847 856 assert_response :success
848 857 assert_not_nil assigns(:pages)
849 858 assert assigns(:pages).any?
850 859 assert_equal "text/html", @response.content_type
851 860
852 861 assert_select "a[name=?]", "CookBook_documentation"
853 862 assert_select "a[name=?]", "Another_page"
854 863 assert_select "a[name=?]", "Page_with_an_inline_image"
855 864 end
856 865
857 866 def test_export_to_pdf
858 867 @request.session[:user_id] = 2
859 868 get :export, :project_id => 'ecookbook', :format => 'pdf'
860 869
861 870 assert_response :success
862 871 assert_not_nil assigns(:pages)
863 872 assert assigns(:pages).any?
864 873 assert_equal 'application/pdf', @response.content_type
865 874 assert_equal 'attachment; filename="ecookbook.pdf"', @response.headers['Content-Disposition']
866 875 assert @response.body.starts_with?('%PDF')
867 876 end
868 877
869 878 def test_export_without_permission_should_be_denied
870 879 @request.session[:user_id] = 2
871 880 Role.find_by_name('Manager').remove_permission! :export_wiki_pages
872 881 get :export, :project_id => 'ecookbook'
873 882
874 883 assert_response 403
875 884 end
876 885
877 886 def test_date_index
878 887 get :date_index, :project_id => 'ecookbook'
879 888
880 889 assert_response :success
881 890 assert_template 'date_index'
882 891 assert_not_nil assigns(:pages)
883 892 assert_not_nil assigns(:pages_by_date)
884 893
885 894 assert_select 'a[href=?]', '/projects/ecookbook/activity.atom?show_wiki_edits=1'
886 895 end
887 896
888 897 def test_not_found
889 898 get :show, :project_id => 999
890 899 assert_response 404
891 900 end
892 901
893 902 def test_protect_page
894 903 page = WikiPage.find_by_wiki_id_and_title(1, 'Another_page')
895 904 assert !page.protected?
896 905 @request.session[:user_id] = 2
897 906 post :protect, :project_id => 1, :id => page.title, :protected => '1'
898 907 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
899 908 assert page.reload.protected?
900 909 end
901 910
902 911 def test_unprotect_page
903 912 page = WikiPage.find_by_wiki_id_and_title(1, 'CookBook_documentation')
904 913 assert page.protected?
905 914 @request.session[:user_id] = 2
906 915 post :protect, :project_id => 1, :id => page.title, :protected => '0'
907 916 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'CookBook_documentation'
908 917 assert !page.reload.protected?
909 918 end
910 919
911 920 def test_show_page_with_edit_link
912 921 @request.session[:user_id] = 2
913 922 get :show, :project_id => 1
914 923 assert_response :success
915 924 assert_template 'show'
916 925 assert_select 'a[href=?]', '/projects/1/wiki/CookBook_documentation/edit'
917 926 end
918 927
919 928 def test_show_page_without_edit_link
920 929 @request.session[:user_id] = 4
921 930 get :show, :project_id => 1
922 931 assert_response :success
923 932 assert_template 'show'
924 933 assert_select 'a[href=?]', '/projects/1/wiki/CookBook_documentation/edit', 0
925 934 end
926 935
927 936 def test_show_pdf
928 937 @request.session[:user_id] = 2
929 938 get :show, :project_id => 1, :format => 'pdf'
930 939 assert_response :success
931 940 assert_not_nil assigns(:page)
932 941 assert_equal 'application/pdf', @response.content_type
933 942 assert_equal 'attachment; filename="CookBook_documentation.pdf"',
934 943 @response.headers['Content-Disposition']
935 944 end
936 945
937 946 def test_show_html
938 947 @request.session[:user_id] = 2
939 948 get :show, :project_id => 1, :format => 'html'
940 949 assert_response :success
941 950 assert_not_nil assigns(:page)
942 951 assert_equal 'text/html', @response.content_type
943 952 assert_equal 'attachment; filename="CookBook_documentation.html"',
944 953 @response.headers['Content-Disposition']
945 954 assert_select 'h1', :text => /CookBook documentation/
946 955 end
947 956
948 957 def test_show_versioned_html
949 958 @request.session[:user_id] = 2
950 959 get :show, :project_id => 1, :format => 'html', :version => 2
951 960 assert_response :success
952 961 assert_not_nil assigns(:content)
953 962 assert_equal 2, assigns(:content).version
954 963 assert_equal 'text/html', @response.content_type
955 964 assert_equal 'attachment; filename="CookBook_documentation.html"',
956 965 @response.headers['Content-Disposition']
957 966 assert_select 'h1', :text => /CookBook documentation/
958 967 end
959 968
960 969 def test_show_txt
961 970 @request.session[:user_id] = 2
962 971 get :show, :project_id => 1, :format => 'txt'
963 972 assert_response :success
964 973 assert_not_nil assigns(:page)
965 974 assert_equal 'text/plain', @response.content_type
966 975 assert_equal 'attachment; filename="CookBook_documentation.txt"',
967 976 @response.headers['Content-Disposition']
968 977 assert_include 'h1. CookBook documentation', @response.body
969 978 end
970 979
971 980 def test_show_versioned_txt
972 981 @request.session[:user_id] = 2
973 982 get :show, :project_id => 1, :format => 'txt', :version => 2
974 983 assert_response :success
975 984 assert_not_nil assigns(:content)
976 985 assert_equal 2, assigns(:content).version
977 986 assert_equal 'text/plain', @response.content_type
978 987 assert_equal 'attachment; filename="CookBook_documentation.txt"',
979 988 @response.headers['Content-Disposition']
980 989 assert_include 'h1. CookBook documentation', @response.body
981 990 end
982 991
983 992 def test_edit_unprotected_page
984 993 # Non members can edit unprotected wiki pages
985 994 @request.session[:user_id] = 4
986 995 get :edit, :project_id => 1, :id => 'Another_page'
987 996 assert_response :success
988 997 assert_template 'edit'
989 998 end
990 999
991 1000 def test_edit_protected_page_by_nonmember
992 1001 # Non members cannot edit protected wiki pages
993 1002 @request.session[:user_id] = 4
994 1003 get :edit, :project_id => 1, :id => 'CookBook_documentation'
995 1004 assert_response 403
996 1005 end
997 1006
998 1007 def test_edit_protected_page_by_member
999 1008 @request.session[:user_id] = 2
1000 1009 get :edit, :project_id => 1, :id => 'CookBook_documentation'
1001 1010 assert_response :success
1002 1011 assert_template 'edit'
1003 1012 end
1004 1013
1005 1014 def test_history_of_non_existing_page_should_return_404
1006 1015 get :history, :project_id => 1, :id => 'Unknown_page'
1007 1016 assert_response 404
1008 1017 end
1009 1018
1010 1019 def test_add_attachment
1011 1020 @request.session[:user_id] = 2
1012 1021 assert_difference 'Attachment.count' do
1013 1022 post :add_attachment, :project_id => 1, :id => 'CookBook_documentation',
1014 1023 :attachments => {
1015 1024 '1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'),
1016 1025 'description' => 'test file'}
1017 1026 }
1018 1027 end
1019 1028 attachment = Attachment.order('id DESC').first
1020 1029 assert_equal Wiki.find(1).find_page('CookBook_documentation'), attachment.container
1021 1030 end
1022 1031 end
General Comments 0
You need to be logged in to leave comments. Login now